#pragma once #include <type_traits> namespace Script { // Deferred-type is used to indicate types identified dynamically struct DeferredType {}; // Supported script input types (scalars, 3-vectors, 5-D images) template <typename T> struct Scalar {}; template <typename T> struct Vector {}; template <typename T> struct Image {}; template <typename T> struct ImageRef {}; template <typename T> struct StructTrait {}; // IO Traits (Parameter type, output, input, optional input) template <typename T> struct OutParam {}; template <typename T> struct InParam {}; template <typename T> struct OptParam { // TODO: Static assert on invalid- io type combinations (e.g. default values can't be type-deferred) }; // NOTE: These are general predicates for interrogating nested types ///////////////////////// // has_underlying_type - // Predicate: true if underlying type is U (e.g. OutParam<ImageRef<V>>) ///////////////////////// template <typename T, typename U> struct has_underlying_type { static constexpr bool value = std::is_same<T,U>::value; }; template <template<typename> class T, typename V, typename U> struct has_underlying_type<T<V>, U> { static constexpr bool value = has_underlying_type<V,U>::value; }; ///////////////////////// // has_trait - // Predicate: true if contains a type-trait (Trait) in nested type set (e.g. A<Trait<B<...>>>) ///////////////////////// template <typename T, template<typename> class Trait> struct has_trait : std::false_type {}; template <template<typename> class T, typename V, template<typename> class Trait> struct has_trait<T<V>, Trait> { static constexpr bool value = (std::is_same<T<V>,Trait<V>>::value || has_trait<V,Trait>::value); }; ///////////////////////// // is_deferred - // Predicate: true if underlying type is deferred (e.g. OutParam<ImageRef<DeferredType>>) ///////////////////////// template <typename T> struct is_deferred { static constexpr bool value = has_underlying_type<T, DeferredType>::value; }; ///////////////////////// // is_image - // Predicate: true if contains an image/imageref (e.g. InParam<ImageRef<DeferredType>>) ///////////////////////// template <typename T> struct is_image { static constexpr bool value = (has_trait<T, ImageRef>::value || has_trait<T, Image>::value); }; ///////////////////////// // is_outparam - // Predicate: true if is output parameter (e.g. OutParam<...>) ///////////////////////// template <typename T> struct is_outparam { static constexpr bool value = has_trait<T, OutParam>::value; }; ///////////////////////// // is_inparam - // Predicate: true if is input parameter (e.g. InParam<...>) ///////////////////////// template <typename T> struct is_inparam { static constexpr bool value = has_trait<T, InParam>::value; }; ///////////////////////// // is_optparam - // Predicate: true if is optional input parameter (e.g. OptParam<...>) ///////////////////////// template <typename T> struct is_optparam { static constexpr bool value = has_trait<T, OptParam>::value; }; ///////////////////////// // not_deferred - // Predicate: true if underlying type is NOT deferred (e.g. OutParam<ImageRef<float>>) ///////////////////////// template <typename T> struct not_deferred { static constexpr bool value = !is_deferred<T>::value; }; ///////////////////////// // true_pred - // Predicate: always true ///////////////////////// template <typename T> struct true_pred : std::true_type {}; ///////////////////////// // false_pred - // Predicate: always false ///////////////////////// template <typename T> struct false_pred: std::false_type {}; };