move Optional
out of spirv_backend and into coremem_types
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::geom::Index;
|
use crate::geom::Index;
|
||||||
|
use coremem_types::compound::Optional;
|
||||||
use coremem_types::vec::{Vec3, Vec3u};
|
use coremem_types::vec::{Vec3, Vec3u};
|
||||||
|
|
||||||
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
|
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
|
||||||
mod ffi {
|
mod ffi {
|
||||||
pub use spirv_backend::{entry_points, SerializedSimMeta};
|
pub use spirv_backend::{entry_points, SerializedSimMeta};
|
||||||
pub use spirv_backend::support::Optional;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// conversion traits for types defined cross-lib
|
// conversion traits for types defined cross-lib
|
||||||
@@ -43,16 +43,16 @@ impl<T: Identity> Identity for Vec3<T> {}
|
|||||||
impl<L: IntoFfi> IntoFfi for Option<L>
|
impl<L: IntoFfi> IntoFfi for Option<L>
|
||||||
where L::Ffi: Default
|
where L::Ffi: Default
|
||||||
{
|
{
|
||||||
type Ffi = ffi::Optional<L::Ffi>;
|
type Ffi = Optional<L::Ffi>;
|
||||||
fn into_ffi(self) -> Self::Ffi {
|
fn into_ffi(self) -> Self::Ffi {
|
||||||
match self {
|
match self {
|
||||||
Some(s) => ffi::Optional::some(s.into_ffi()),
|
Some(s) => Optional::some(s.into_ffi()),
|
||||||
None => ffi::Optional::none(),
|
None => Optional::none(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Copy + IntoLib> IntoLib for ffi::Optional<F> {
|
impl<F: Copy + IntoLib> IntoLib for Optional<F> {
|
||||||
type Lib = Option<F::Lib>;
|
type Lib = Option<F::Lib>;
|
||||||
fn into_lib(self) -> Self::Lib {
|
fn into_lib(self) -> Self::Lib {
|
||||||
if self.is_some() {
|
if self.is_some() {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
use crate::sim::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
|
use crate::sim::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
|
||||||
use crate::support::{Array3, Array3Mut, Optional, UnsizedArray};
|
use crate::support::{Array3, Array3Mut, UnsizedArray};
|
||||||
|
use coremem_types::compound::Optional;
|
||||||
use coremem_types::mat::Material;
|
use coremem_types::mat::Material;
|
||||||
use coremem_types::real::Real;
|
use coremem_types::real::Real;
|
||||||
use coremem_types::vec::{Vec3, Vec3u};
|
use coremem_types::vec::{Vec3, Vec3u};
|
||||||
|
@@ -17,8 +17,9 @@ pub mod sim;
|
|||||||
pub mod support;
|
pub mod support;
|
||||||
|
|
||||||
pub use adapt::SerializedSimMeta;
|
pub use adapt::SerializedSimMeta;
|
||||||
pub use support::{Optional, UnsizedArray};
|
pub use support::UnsizedArray;
|
||||||
|
|
||||||
|
use coremem_types::compound::Optional;
|
||||||
use coremem_types::mat::{Ferroxcube3R1MH, FullyGenericMaterial, IsoConductorOr};
|
use coremem_types::mat::{Ferroxcube3R1MH, FullyGenericMaterial, IsoConductorOr};
|
||||||
use coremem_types::vec::{Vec3, Vec3u};
|
use coremem_types::vec::{Vec3, Vec3u};
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// use spirv_std::RuntimeArray;
|
// use spirv_std::RuntimeArray;
|
||||||
use crate::support::Optional;
|
use coremem_types::compound::Optional;
|
||||||
use coremem_types::mat::Material;
|
use coremem_types::mat::Material;
|
||||||
use coremem_types::real::Real;
|
use coremem_types::real::Real;
|
||||||
use coremem_types::vec::Vec3;
|
use coremem_types::vec::Vec3;
|
||||||
|
@@ -1,86 +1,6 @@
|
|||||||
|
use coremem_types::compound::Optional;
|
||||||
use coremem_types::vec::Vec3u;
|
use coremem_types::vec::Vec3u;
|
||||||
|
|
||||||
/// This is a spirv-compatible option type.
|
|
||||||
/// The native rust Option type produces invalid spirv due to its enum nature; this custom option
|
|
||||||
/// type creates code which will actually compile.
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub struct Optional<T> {
|
|
||||||
// XXX: not a bool, because: "entrypoint parameter cannot contain a boolean"
|
|
||||||
present: u8,
|
|
||||||
data: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Optional<T> {
|
|
||||||
pub fn some(data: T) -> Self {
|
|
||||||
Self {
|
|
||||||
present: 1,
|
|
||||||
data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn explicit_none(data: T) -> Self {
|
|
||||||
Self {
|
|
||||||
present: 0,
|
|
||||||
data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_some(self) -> bool {
|
|
||||||
self.present != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap(self) -> T {
|
|
||||||
assert!(self.present != 0);
|
|
||||||
self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map<U: Default, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
|
|
||||||
self.and_then(|inner| Optional::some(f(inner)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn and_then<U: Default, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
|
|
||||||
if self.present != 0 {
|
|
||||||
f(self.unwrap())
|
|
||||||
} else {
|
|
||||||
Optional::none()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap_or(self, default: T) -> T {
|
|
||||||
if self.present != 0 {
|
|
||||||
self.unwrap()
|
|
||||||
} else {
|
|
||||||
default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Default> Optional<T> {
|
|
||||||
pub fn none() -> Self {
|
|
||||||
Self::explicit_none(Default::default())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap_or_default(self) -> T {
|
|
||||||
self.unwrap_or(Default::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Default> Default for Optional<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::none()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T0: Default, T1: Default> Optional<(T0, T1)> {
|
|
||||||
pub fn flatten((f0, f1): (Optional<T0>, Optional<T1>)) -> Self {
|
|
||||||
if f0.present != 0 && f1.present != 0 {
|
|
||||||
Optional::some((f0.unwrap(), f1.unwrap()))
|
|
||||||
} else {
|
|
||||||
Optional::none()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This struct allows doing things like *(ptr + offset) = value.
|
/// This struct allows doing things like *(ptr + offset) = value.
|
||||||
/// Such code wouldn't ordinarily compile with the spirv target because of
|
/// Such code wouldn't ordinarily compile with the spirv target because of
|
||||||
/// unsupported pointer math. RuntimeArray exists to overcome this, however
|
/// unsupported pointer math. RuntimeArray exists to overcome this, however
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
pub mod enumerated;
|
pub mod enumerated;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
mod optional;
|
||||||
pub mod peano;
|
pub mod peano;
|
||||||
|
|
||||||
|
pub use optional::Optional;
|
||||||
|
82
crates/types/src/compound/optional.rs
Normal file
82
crates/types/src/compound/optional.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/// This is a spirv-compatible option type.
|
||||||
|
/// The native rust Option type produces invalid spirv due to its enum nature; this custom option
|
||||||
|
/// type creates code which will actually compile.
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub struct Optional<T> {
|
||||||
|
// XXX: not a bool, because: "entrypoint parameter cannot contain a boolean"
|
||||||
|
present: u8,
|
||||||
|
data: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Optional<T> {
|
||||||
|
pub fn some(data: T) -> Self {
|
||||||
|
Self {
|
||||||
|
present: 1,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn explicit_none(data: T) -> Self {
|
||||||
|
Self {
|
||||||
|
present: 0,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_some(self) -> bool {
|
||||||
|
self.present != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap(self) -> T {
|
||||||
|
assert!(self.present != 0);
|
||||||
|
self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map<U: Default, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
|
||||||
|
self.and_then(|inner| Optional::some(f(inner)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn and_then<U: Default, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
|
||||||
|
if self.present != 0 {
|
||||||
|
f(self.unwrap())
|
||||||
|
} else {
|
||||||
|
Optional::none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_or(self, default: T) -> T {
|
||||||
|
if self.present != 0 {
|
||||||
|
self.unwrap()
|
||||||
|
} else {
|
||||||
|
default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Optional<T> {
|
||||||
|
pub fn none() -> Self {
|
||||||
|
Self::explicit_none(Default::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_or_default(self) -> T {
|
||||||
|
self.unwrap_or(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Default for Optional<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T0: Default, T1: Default> Optional<(T0, T1)> {
|
||||||
|
pub fn flatten((f0, f1): (Optional<T0>, Optional<T1>)) -> Self {
|
||||||
|
if f0.present != 0 && f1.present != 0 {
|
||||||
|
Optional::some((f0.unwrap(), f1.unwrap()))
|
||||||
|
} else {
|
||||||
|
Optional::none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@@ -1,8 +1,9 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
mod compound;
|
pub mod compound;
|
||||||
pub mod mat;
|
pub mod mat;
|
||||||
pub mod real;
|
pub mod real;
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
|
// private because `vec` re-exports to important vecu constructs
|
||||||
mod vecu;
|
mod vecu;
|
||||||
|
Reference in New Issue
Block a user