11 #ifndef __APEX_TYPES_H__
12 #define __APEX_TYPES_H__
40 class APEX_TypeDefinitionBase;
44 static constexpr
UT_StringLit theUndefTypeName =
"undefined";
45 static constexpr
UT_StringLit theAnonTypeName =
"anonymous";
46 static constexpr
UT_StringLit theVariadicPrefix =
"VariadicArg<";
47 static constexpr
UT_StringLit theVariadicFormat =
"VariadicArg<{}>";
48 static constexpr
char theInplacePortPrefix[] =
"*";
49 static constexpr
char theSparePortPrefix[] =
"+";
50 static constexpr
char theConditionalInplacePortPrefix[] =
"-";
51 static constexpr
UT_StringLit theSparePortName =
"__spare__";
52 static constexpr
UT_StringLit theRunDataPortName =
"rundata";
60 virtual size_t sizeT()
const = 0;
71 virtual void clear(
void *mem)
const = 0;
79 virtual void setData(
void *mem,
const void *
val)
const = 0;
83 virtual std::type_index
typeIndex()
const = 0;
87 virtual bool isArray()
const {
return false; }
91 virtual bool isHandle()
const {
return false; }
140 template <
typename T,
typename =
void>
145 template <
typename T>
153 template <
typename T>
158 template <
typename T>
163 if constexpr (SYS_IsPod_v<T>)
168 else if constexpr (std::is_move_constructible_v<T>)
170 arr->setCapacity(size);
177 !detail::APEX_TypeDefaultIsSpecialized_v<T>,
"A move constructor must be declared on a "
178 "type with an explicit APEX default value.");
184 template <
typename T>
206 if constexpr (std::is_move_assignable_v<T>)
220 if constexpr (!std::is_trivially_destructible_v<T> && !SYS_IsPod_v<T>)
228 template <
typename T,
typename =
void>
234 template <
typename T>
251 , mySubTypeDef(nullptr)
252 , myTypeIndex(std::type_index(typeid(
void)))
263 size_t sizeT()
const override {
return 0; }
266 void clear(
void *mem)
const override {}
273 std::type_index
typeIndex()
const override {
return myTypeIndex; }
279 std::type_index myTypeIndex;
289 template <
typename T>
300 template <
typename T>
305 template <
typename T>
311 , mySubTypeDef(nullptr)
312 , myTypeIndex(std::type_index(typeid(
T)))
315 auto key =
typeid(
T).
name();
337 size_t sizeT()
const override {
return sizeof(
T); }
344 void clear(
void *mem)
const override
353 if constexpr (std::is_move_assignable_v<T>)
358 !detail::APEX_TypeDefaultIsSpecialized_v<T>,
359 "A move constructor must be declared on a type with an explicit APEX default "
375 return &buffer_arr[index];
380 if constexpr (std::is_copy_assignable_v<T>)
382 const T *typed_val =
reinterpret_cast<const T *
>(
val);
383 T *buffer_value =
reinterpret_cast<T *
>(mem);
384 *buffer_value = *typed_val;
395 std::type_index
typeIndex()
const override {
return myTypeIndex; }
396 bool isCopyable()
const override {
return std::is_copy_assignable_v<T>; }
407 std::type_index myTypeIndex;
416 template <
typename T>
420 auto key =
typeid(
T).
name();
429 static const APEX_TypeDefinitionBase *
433 if (type_name == theAnonTypeName)
444 template <
typename T>
448 auto key =
typeid(
T).
name();
451 return it->second->repr();
452 return theUndefTypeName.
asRef();
456 isVariadicType(
const APEX_TypeDefinitionBase *
type)
458 return type && type->isVariadic();
465 const APEX_TypeDefinitionBase *
dst,
466 const APEX_TypeDefinitionBase *
src,
467 bool allow_implicit_conversion =
false)
471 if (!allow_implicit_conversion)
473 if (dst == findTypeDef<Bool>() && src == findTypeDef<Int>())
475 if (src == findTypeDef<Bool>() && dst == findTypeDef<Int>())
479 return dst->isCopyable();
482 #define APEX_DEF_TYPE_NAME(t) static APEX_TypeDefinition<t> t_dfn_##t{ #t };
483 #define APEX_DEF_TYPE_NAME_N(t, n) static APEX_TypeDefinition<t> t_dfn_##n{ #t };
484 #define APEX_DEF_TYPE_RUNDATA(c) \
485 inline static APEX_TypeDefinition<RunData> t_dfn_##c{ #c"::RunData" };
488 #define APEX_DEF_TYPE_NAME_BASIC(type) \
489 APEX_DEF_TYPE_NAME(type) \
490 APEX_DEF_TYPE_NAME_N(VariadicArg<type>, VariadicArg_##type) \
492 #define APEX_DEF_TYPE_NAME_FULL(type) \
493 APEX_DEF_TYPE_NAME_BASIC(type) \
494 APEX_DEF_TYPE_NAME(type##Array) \
495 APEX_DEF_TYPE_NAME_N(VariadicArg<type##Array>, VariadicArg_##type##Array) \
502 #endif // end header guard
~APEX_TypeDefinition() override
std::type_index typeIndex() const override
Return the RTTI information for the contained type.
bool isCopyable() const override
Return whether the type is copy-assignable (i.e. can setData function).
virtual bool isCopyable() const =0
Return whether the type is copy-assignable (i.e. can setData function).
void * getPtrAtIndex(void *mem, exint index) const override
Get a pointer to the {index}-th value in the resizable array created by allocate stored at mem...
virtual std::type_index typeIndex() const =0
Return the RTTI information for the contained type.
virtual void * allocate(exint size) const =0
#define UTdebugPrint(...)
APEX_API UT_ArrayStringMap< const APEX_TypeDefinitionBase * > & APEXtypeDefinitions()
virtual bool isArray() const
Return whether the type is an array.
UT_Vector4T< Float > Vector4
#define SYS_STATIC_ASSERT_MSG(expr, msg)
Compile-time information about the default initialization to use for a type visible to the APEX type ...
GLsizei const GLfloat * value
void SYS_Void_t
Alternative for C++17's std::void that can be used in C++14:
void setSizeNoInit(exint newsize)
void * getPtrAtIndex(void *mem, exint index) const override
Get a pointer to the {index}-th value in the resizable array created by allocate stored at mem...
void clear(void *mem) const override
Reset the instance of this type (member of buffer created in allocate) to a default value if possible...
const UT_StringRef & repr() const override
Return a human-readable string representing the type.
bool isVariadic() const override
Return whether the type is a variadic arg.
APEX_API APEX_VoidTypeDefinition void_type_defn
void * allocate(exint size) const override
virtual void clear(void *mem) const =0
Reset the instance of this type (member of buffer created in allocate) to a default value if possible...
Holds all of the memory for execution state of a compiled APEX graph.
constexpr auto APEX_TypeDefaultIsSpecialized_v
void * allocate(exint size) const override
virtual exint append(void *mem) const =0
void deallocate(void *mem) const override
Free a resizable array created by allocate.
~APEX_VoidTypeDefinition() override
GLint GLint GLsizei GLint GLenum GLenum type
exint emplace_back(S &&...s)
virtual void deallocate(void *mem) const =0
Free a resizable array created by allocate.
static constexpr bool isDefaultConstructing
virtual const UT_StringRef & repr() const =0
Return a human-readable string representing the type.
const APEX_TypeDefinitionBase * subTypeDef() const override
If this is a compound type (such as variadics), return the type definition for the contained type...
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
UT_Matrix3T< Float > Matrix3
exint append(void *mem) const override
bool isHandle() const override
Return whether the type is a handle to some shared data (i.e. geometry)
UT_Matrix4T< Float > Matrix4
exint append(void *mem) const override
virtual void setData(void *mem, const void *val) const =0
Copy the value at val to mem.
APEX_VoidTypeDefinition()
GLuint const GLchar * name
static void * allocate(exint size)
Called to allocate a UT_Array<T> of length size.
virtual bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const =0
const APEX_TypeDefinitionBase * subTypeDef() const override
If this is a compound type (such as variadics), return the type definition for the contained type...
size_t sizeT() const override
Return the size of a single instance of the type, or 0 if the type is not well-defined (i...
void clear(void *mem) const override
Reset the instance of this type (member of buffer created in allocate) to a default value if possible...
static T value()
Return a default value for the type.
void deallocate(void *mem) const override
Free a resizable array created by allocate.
virtual const APEX_TypeDefinitionBase * subTypeDef() const =0
If this is a compound type (such as variadics), return the type definition for the contained type...
SYS_FORCE_INLINE const UT_StringRef & asRef() const
const UT_StringRef & repr() const override
Return a human-readable string representing the type.
UT_Vector2T< Float > Vector2
bool isCopyable() const override
Return whether the type is copy-assignable (i.e. can setData function).
void setData(SYS_MAYBE_UNUSED void *mem, SYS_MAYBE_UNUSED const void *val) const override
virtual bool isVariadic() const
Return whether the type is a variadic arg.
static void clear(T *mem)
Given an initialized instance of T, reset it to the default state.
virtual ~APEX_TypeDefinitionBase()
bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override
UT_Vector3T< Float > Vector3
bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override
virtual void * getPtrAtIndex(void *mem, exint index) const =0
Get a pointer to the {index}-th value in the resizable array created by allocate stored at mem...
std::type_index typeIndex() const override
Return the RTTI information for the contained type.
bool OIIO_UTIL_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
void setData(void *mem, const void *val) const override
Copy the value at val to mem.
static bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port)
bool isArray() const override
Return whether the type is an array.
size_t sizeT() const override
Return the size of a single instance of the type, or 0 if the type is not well-defined (i...
virtual bool isHandle() const
Return whether the type is a handle to some shared data (i.e. geometry)
APEX_TypeDefinition(const UT_StringLit &&type_name)
virtual size_t sizeT() const =0
Return the size of a single instance of the type, or 0 if the type is not well-defined (i...
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.