move Optional
out of spirv_backend and into coremem_types
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::geom::Index;
|
||||
use coremem_types::compound::Optional;
|
||||
use coremem_types::vec::{Vec3, Vec3u};
|
||||
|
||||
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
|
||||
mod ffi {
|
||||
pub use spirv_backend::{entry_points, SerializedSimMeta};
|
||||
pub use spirv_backend::support::Optional;
|
||||
}
|
||||
|
||||
// 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>
|
||||
where L::Ffi: Default
|
||||
{
|
||||
type Ffi = ffi::Optional<L::Ffi>;
|
||||
type Ffi = Optional<L::Ffi>;
|
||||
fn into_ffi(self) -> Self::Ffi {
|
||||
match self {
|
||||
Some(s) => ffi::Optional::some(s.into_ffi()),
|
||||
None => ffi::Optional::none(),
|
||||
Some(s) => Optional::some(s.into_ffi()),
|
||||
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>;
|
||||
fn into_lib(self) -> Self::Lib {
|
||||
if self.is_some() {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
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::real::Real;
|
||||
use coremem_types::vec::{Vec3, Vec3u};
|
||||
|
@@ -17,8 +17,9 @@ pub mod sim;
|
||||
pub mod support;
|
||||
|
||||
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::vec::{Vec3, Vec3u};
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// use spirv_std::RuntimeArray;
|
||||
use crate::support::Optional;
|
||||
use coremem_types::compound::Optional;
|
||||
use coremem_types::mat::Material;
|
||||
use coremem_types::real::Real;
|
||||
use coremem_types::vec::Vec3;
|
||||
|
@@ -1,86 +1,6 @@
|
||||
use coremem_types::compound::Optional;
|
||||
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.
|
||||
/// Such code wouldn't ordinarily compile with the spirv target because of
|
||||
/// unsupported pointer math. RuntimeArray exists to overcome this, however
|
||||
|
@@ -1,3 +1,6 @@
|
||||
pub mod enumerated;
|
||||
pub mod list;
|
||||
mod optional;
|
||||
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]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
mod compound;
|
||||
pub mod compound;
|
||||
pub mod mat;
|
||||
pub mod real;
|
||||
pub mod vec;
|
||||
// private because `vec` re-exports to important vecu constructs
|
||||
mod vecu;
|
||||
|
Reference in New Issue
Block a user