HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
APEX_Types.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: APEX_Types.h (APEX Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __APEX_TYPES_H__
12 #define __APEX_TYPES_H__
13 
14 #include "APEX_API.h"
15 #include "APEX_Include.h"
16 
17 #include <UT/UT_Array.h>
18 #include <UT/UT_ArrayMap.h>
19 #include <UT/UT_ArrayStringMap.h>
20 #include <UT/UT_Assert.h>
21 #include <UT/UT_Debug.h>
22 #include <UT/UT_StringHolder.h>
23 #include <SYS/SYS_StaticAssert.h>
24 #include <SYS/SYS_Compiler.h>
25 #include <SYS/SYS_Types.h>
26 #include <SYS/SYS_TypeTraits.h>
27 
28 #include <new>
29 #include <typeindex>
30 #include <typeinfo>
31 #include <utility>
32 
33 #include <stddef.h>
34 
35 namespace apex
36 {
37 
38 class APEX_Buffer;
39 class APEX_Graph;
40 class APEX_TypeDefinitionBase;
41 
43 
44 static constexpr UT_StringLit theUndefTypeName = "undefined";
45 static constexpr UT_StringLit theVariadicPrefix = "VariadicArg<";
46 static constexpr UT_StringLit theVariadicFormat = "VariadicArg<{}>";
47 static constexpr char theInplacePortPrefix[] = "*";
48 static constexpr char theSparePortPrefix[] = "+";
49 static constexpr char theConditionalInplacePortPrefix[] = "-";
50 static constexpr UT_StringLit theSparePortName = "__spare__";
51 static constexpr UT_StringLit theRunDataPortName = "rundata";
52 
54 {
55 public:
57 
58  /// Return the size of a single instance of the type, or 0 if the type is not well-defined (i.e. a void).
59  virtual size_t sizeT() const = 0;
60 
61  /// Return a human-readable string representing the type.
62  virtual const UT_StringRef &repr() const = 0;
63  /// Allocate a resizable array of the type. The current implementation uses a UT_Array behind-the-scenes, however
64  /// the implementation is type-erased to allow flexibility.
65  virtual void *allocate(exint size) const = 0;
66  /// Append a default-constructed instance to the array previously allocated by @ref allocate. If no allocation could be performed,
67  /// return -1.
68  virtual exint append(void *mem) const = 0;
69  /// Reset the instance of this type (member of buffer created in @ref allocate) to a default value if possible.
70  virtual void clear(void *mem) const = 0;
71  /// Free a resizable array created by @ref allocate.
72  virtual void deallocate(void *mem) const = 0;
73  /// Get a pointer to the @p{index}-th value in the resizable array created by @ref allocate stored at @p mem.
74  virtual void *getPtrAtIndex(void *mem, exint index) const = 0;
75 
76  virtual bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const = 0;
77  /// Copy the value at @p val to @p mem.
78  virtual void setData(void *mem, const void *val) const = 0;
79  /// If this is a compound type (such as variadics), return the type definition for the contained type.
80  virtual const APEX_TypeDefinitionBase *subTypeDef() const = 0;
81  /// Return the RTTI information for the contained type.
82  virtual std::type_index typeIndex() const = 0;
83  /// Return whether the type is copy-assignable (i.e. can @ref setData function).
84  virtual bool isCopyable() const = 0;
85  /// Return whether the type is an array
86  virtual bool isArray() const { return false; }
87  /// Return whether the type is a variadic arg
88  virtual bool isVariadic() const { return false; }
89  /// Return whether the type is a handle to some shared data (i.e. geometry)
90  virtual bool isHandle() const { return false; }
91 };
92 
93 /// Compile-time information about the default initialization to use for a type visible to the APEX type system.
94 template <typename T>
96 {
97  /// Return a default value for the type.
98  static T value() { return T(); }
99 
100  /// If this member is missing or false in a specialization, the default value is assumed to be
101  /// something other than T(), and any code that implicitly relies on that being the case will
102  /// static assert.
103  static constexpr bool isDefaultConstructing = true;
104 };
105 
106 template <>
108 {
109  static Vector2 value() { return Vector2(0.0, 0.0); }
110 };
111 
112 template <>
114 {
115  static Vector3 value() { return Vector3(0.0, 0.0, 0.0); }
116 };
117 
118 template <>
120 {
121  static Vector4 value() { return Vector4(0.0, 0.0, 0.0, 0.0); }
122 };
123 
124 template <>
126 {
127  static Matrix3 value() { return Matrix3(1.0); }
128 };
129 
130 template <>
132 {
133  static Matrix4 value() { return Matrix4(1.0); }
134 };
135 
136 namespace detail
137 {
138 
139 template <typename T, typename = void>
141 {
142 };
143 
144 template <typename T>
146  T,
147  SYS_Void_t<decltype(APEX_TypeDefault<T>::isDefaultConstructing)>>
148  : SYS_BoolConstant<APEX_TypeDefault<T>::isDefaultConstructing == false>
149 {
150 };
151 
152 template <typename T>
154 
155 }
156 
157 template <typename T>
158 static inline void *
159 allocateT(exint size)
160 {
161  auto *arr = new UT_Array<T>(size);
162  if constexpr (SYS_IsPod_v<T>)
163  {
164  arr->setSizeNoInit(size);
165  arr->constant(APEX_TypeDefault<T>::value());
166  }
167  else if constexpr (std::is_move_constructible_v<T>)
168  {
169  arr->setCapacity(size);
170  for (exint i = 0; i < size; ++i)
171  arr->emplace_back(APEX_TypeDefault<T>::value());
172  }
173  else
174  {
176  !detail::APEX_TypeDefaultIsSpecialized_v<T>, "A move constructor must be declared on a "
177  "type with an explicit APEX default value.");
178  arr->setSize(size);
179  }
180  return arr;
181 }
182 
183 template <typename T>
185 {
186 public:
187  /// Called to allocate a @c UT_Array<T> of length @p size.
188  static void *allocate(exint size) { return allocateT<T>(size); }
189  /// Called for each non-subport usage of a type with the buffer, graph and allocated port.
190  ///
191  /// Returns whether or not compilation was successful -- if it returns false, then compilation
192  /// is aborted. Error messages can be added into the passed graph with addError. For types which
193  /// handle their own subports (like VariadicArgs), validity of those subports must be checked
194  /// here; callbacks can do the same thing (usually with __spare__ ports) in their compile
195  /// callback.
196  static bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) { return true; }
197  /// Given an initialized instance of `T`, reset it to the default state.
198  static void clear(T *mem)
199  {
200  // If we can assign the type to its default, use that. Despite the name of the type trait,
201  // this also catches copy assign operators (it's defined as whether assigning from an rvalue
202  // compiles, which is precisely what the guarded statement does -- there is no need to allow
203  // adding extra types to the condition as anything not std::is_move_assignable_v will not
204  // compile)
205  if constexpr (std::is_move_assignable_v<T>)
206  {
208  }
209  // If the type is not assignable, then destroy the old object and construct a new one in its
210  // place. If the destructor is trivial or the type was marked POD with SYS_DECLARE_IS_POD
211  // then the destructor call is skipped. Note that the apparent use of a move constructor
212  // here is not what it seems: due to the new rvalue semantics in C++17 (aka "guaranteed copy
213  // elision") the call to value() directly initializes the data in `mem` (almost as if it
214  // took a hidden destination pointer) so no temporary is ever made. This trick is not
215  // possible in the various UT_Array-dependent parts of the APEX type system, as they do not
216  // expose any API to manually call the constructors for new elements.
217  else
218  {
219  if constexpr (!std::is_trivially_destructible_v<T> && !SYS_IsPod_v<T>)
220  mem->~T();
221  new (static_cast<void *>(mem)) T(APEX_TypeDefault<T>::value());
222  }
223  }
224  static bool isHandle() { return false; }
225 };
226 
227 template <typename T, typename = void>
229 {
230 };
231 
232 /// Check if an APEX type wraps another type (for example, @ref VariadicArg)
233 template <typename T>
235 {
236 };
237 
238 // The idea behind this overload is to support callbacks that perform
239 // 'graph-compile-time' type resolution, resolving the underlying types
240 // connected data. This class enables higher level tooling to treat
241 // these callbacks and their signatures in the same way as well-defined
242 // types whilst also being able to detect whether special allocation or
243 // compilation steps are necessary.
244 // For an example see the APEX_CopyArg callback in APEX_Callback.h
246 {
247 public:
249  : myTypeName("void")
250  , mySubTypeDef(nullptr)
251  , myTypeIndex(std::type_index(typeid(void)))
252  {
253  auto key = typeid(void).name();
255  ? APEXtypeDefinitions()[key]->repr() == myTypeName
256  : true);
257  APEXtypeDefinitions()[key] = this;
258  }
259 
261 
262  size_t sizeT() const override { return 0; }
263  const UT_StringRef &repr() const override { return myTypeName.asRef(); }
264  void *allocate(exint size) const override { return nullptr; }
265  void clear(void *mem) const override {}
266  exint append(void *mem) const override { return -1; }
267  void deallocate(void *mem) const override {}
268  void *getPtrAtIndex(void *mem, exint index) const override { return nullptr; }
269  void setData(void *mem, const void *val) const override {}
270  bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override { return true; }
271  const APEX_TypeDefinitionBase *subTypeDef() const override { return mySubTypeDef; }
272  std::type_index typeIndex() const override { return myTypeIndex; }
273  bool isCopyable() const override { return false; };
274 
275 private:
276  const UT_StringLit myTypeName;
277  const APEX_TypeDefinitionBase *mySubTypeDef;
278  std::type_index myTypeIndex;
279 };
280 
281 template <typename>
283 {
284 };
285 
286 template <typename T> class ApexArray;
287 
288 template <typename T>
290 {
291 };
292 
293 template <typename>
295 {
296 };
297 
298 
299 template <typename T>
301 {
302 };
303 
304 template <typename T>
306 {
307 public:
309  : myTypeName(type_name)
310  , mySubTypeDef(nullptr)
311  , myTypeIndex(std::type_index(typeid(T)))
312  {
313  // UTdebugPrint(type_name, std::is_copy_assignable_v<T>, std::is_copy_constructible_v<T>);
314  auto key = typeid(T).name();
316  ? APEXtypeDefinitions()[key]->repr() == myTypeName
317  : true);
318  if (!APEXtypeDefinitions().contains(key))
319  APEXtypeDefinitions()[key] = this;
320  if constexpr (APEX_IsCompoundType<T>::value)
321  {
322  auto sub_key = typeid(typename T::value_type).name();
323  if (APEXtypeDefinitions().contains(sub_key))
324  {
325  mySubTypeDef = APEXtypeDefinitions()[sub_key];
326  }
327  }
328  }
329 
330  ~APEX_TypeDefinition() override {}
331 
332  typedef T value_type;
333 
334  const UT_StringRef &repr() const override { return myTypeName.asRef(); }
335 
336  size_t sizeT() const override { return sizeof(T); }
337 
338  /// Return number of definitions present in the provided memory
339  /// block.
340  exint entries(void *mem) const
341  {
342  UT_Array<T> *buffer_arr = reinterpret_cast<UT_Array<T> *>(mem);
343  if (buffer_arr) return buffer_arr->entries();
344  return 0;
345  }
346 
347  void *allocate(exint size) const override
348  {
349  return APEX_TypeTraits<T>::allocate(size);
350  }
351 
352  void clear(void *mem) const override
353  {
354  APEX_TypeTraits<T>::clear(reinterpret_cast<T *>(mem));
355  }
356 
357  exint append(void *mem) const override
358  {
359  UT_Array<T> *buffer_arr = reinterpret_cast<UT_Array<T> *>(mem);
360  exint index = -1;
361  if constexpr (std::is_move_assignable_v<T>)
362  index = buffer_arr->emplace_back(APEX_TypeDefault<T>::value());
363  else
364  {
366  !detail::APEX_TypeDefaultIsSpecialized_v<T>,
367  "A move constructor must be declared on a type with an explicit APEX default "
368  "value.");
369  index = buffer_arr->emplace_back();
370  }
371  return index;
372  }
373 
374  void deallocate(void *mem) const override
375  {
376  UT_Array<T> *buffer_arr = reinterpret_cast<UT_Array<T> *>(mem);
377  delete buffer_arr;
378  }
379 
380  void *getPtrAtIndex(void *mem, exint index) const override
381  {
382  UT_Array<T> &buffer_arr = *reinterpret_cast<UT_Array<T> *>(mem);
383  return &buffer_arr[index];
384  }
385 
386  void setData(SYS_MAYBE_UNUSED void *mem, SYS_MAYBE_UNUSED const void *val) const override
387  {
388  if constexpr (std::is_copy_assignable_v<T>)
389  {
390  const T *typed_val = reinterpret_cast<const T *>(val);
391  T *buffer_value = reinterpret_cast<T *>(mem);
392  *buffer_value = *typed_val;
393  }
394  else
395  UTdebugPrint("cannot copy assign", myTypeName);
396  }
397 
398  bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override
399  {
400  return APEX_TypeTraits<T>::compile(buffer, graph, port);
401  }
402 
403  std::type_index typeIndex() const override { return myTypeIndex; }
404  bool isCopyable() const override { return std::is_copy_assignable_v<T>; }
405 
406  bool isArray() const override { return APEX_IsArrayType<T>::value; }
407  bool isVariadic() const override { return APEX_IsVariadicType<T>::value; }
408  bool isHandle() const override { return APEX_TypeTraits<T>::isHandle(); }
409 
410  const APEX_TypeDefinitionBase *subTypeDef() const override { return mySubTypeDef; }
411 
412 private:
413  const UT_StringLit myTypeName;
414  const APEX_TypeDefinitionBase *mySubTypeDef;
415  std::type_index myTypeIndex;
416 };
417 
418 template <>
420 {
421 };
422 
423 /// Return the type definition for a compile-time known type. APEX equivalent of @c typeid().
424 template <typename T>
425 static const APEX_TypeDefinitionBase *
426 findTypeDef()
427 {
428  auto key = typeid(T).name();
429  auto it = APEXtypeDefinitions().find(key);
430  if (!it.atEnd())
431  return it->second;
432  // UTdebugPrint("findTypeDef could not find:", key);
433  return nullptr;
434 }
435 
436 /// Lookup a type definition by its @c repr().
437 static const APEX_TypeDefinitionBase *
438 findTypeDef(const UT_StringRef &type_name)
439 {
440  for (auto it = APEXtypeDefinitions().begin(); !it.atEnd(); ++it)
441  {
442  if (it->second->repr() == type_name)
443  return it->second;
444  }
445  return nullptr;
446 }
447 
448 /// Return the @c repr() name for a compile-time known type.
449 template <typename T>
450 static const UT_StringRef &
451 findTypeName()
452 {
453  auto key = typeid(T).name();
454  auto it = APEXtypeDefinitions().find(key);
455  if (!it.atEnd())
456  return it->second->repr();
457  return theUndefTypeName.asRef();
458 }
459 
460 static bool
461 isVariadicType(const APEX_TypeDefinitionBase *type)
462 {
463  return type && type->isVariadic();
464 }
465 
466 // Check if copyArgData will attempt to perform a copy, or whether it will fail
467 // due to type issues.
468 static bool
469 canCopyArgData(
470  const APEX_TypeDefinitionBase *dst,
471  const APEX_TypeDefinitionBase *src,
472  bool allow_implicit_conversion = false)
473 {
474  if (dst != src)
475  {
476  if (!allow_implicit_conversion)
477  return false;
478  if (dst == findTypeDef<Bool>() && src == findTypeDef<Int>())
479  return true;
480  if (src == findTypeDef<Bool>() && dst == findTypeDef<Int>())
481  return true;
482  return false;
483  }
484  return dst->isCopyable();
485 }
486 
487 #define APEX_DEF_TYPE_NAME(t) static APEX_TypeDefinition<t> t_dfn_##t{ #t };
488 #define APEX_DEF_TYPE_NAME_N(t, n) static APEX_TypeDefinition<t> t_dfn_##n{ #t };
489 #define APEX_DEF_TYPE_RUNDATA(c) \
490  inline static APEX_TypeDefinition<RunData> t_dfn_##c{ #c"::RunData" };
491 
492 /// Defines the type, its array, and variadic arg variants at the same time
493 #define APEX_DEF_TYPE_NAME_BASIC(type) \
494  APEX_DEF_TYPE_NAME(type) \
495  APEX_DEF_TYPE_NAME_N(VariadicArg<type>, VariadicArg_##type) \
496  /**/
497 #define APEX_DEF_TYPE_NAME_FULL(type) \
498  APEX_DEF_TYPE_NAME_BASIC(type) \
499  APEX_DEF_TYPE_NAME(type##Array) \
500  APEX_DEF_TYPE_NAME_N(VariadicArg<type##Array>, VariadicArg_##type##Array) \
501  /**/
502 
503 APEX_API extern APEX_VoidTypeDefinition void_type_defn;
504 
505 } // namespace apex
506 
507 #endif // end header guard
~APEX_TypeDefinition() override
Definition: APEX_Types.h:330
std::type_index typeIndex() const override
Return the RTTI information for the contained type.
Definition: APEX_Types.h:403
bool isCopyable() const override
Return whether the type is copy-assignable (i.e. can setData function).
Definition: APEX_Types.h:404
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...
Definition: APEX_Types.h:268
virtual std::type_index typeIndex() const =0
Return the RTTI information for the contained type.
virtual void * allocate(exint size) const =0
#define UTdebugPrint(...)
Definition: UT_Debug.h:146
APEX_API UT_ArrayStringMap< const APEX_TypeDefinitionBase * > & APEXtypeDefinitions()
virtual bool isArray() const
Return whether the type is an array.
Definition: APEX_Types.h:86
UT_Vector4T< Float > Vector4
Definition: APEX_Include.h:66
void
Definition: png.h:1083
#define SYS_STATIC_ASSERT_MSG(expr, msg)
Compile-time information about the default initialization to use for a type visible to the APEX type ...
Definition: APEX_Types.h:95
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void SYS_Void_t
Alternative for C++17's std::void that can be used in C++14:
void setSizeNoInit(exint newsize)
Definition: UT_Array.h:719
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...
Definition: APEX_Types.h:380
#define SYS_MAYBE_UNUSED
Definition: SYS_Compiler.h:64
#define APEX_API
Definition: APEX_API.h:21
void clear(void *mem) const override
Reset the instance of this type (member of buffer created in allocate) to a default value if possible...
Definition: APEX_Types.h:265
const UT_StringRef & repr() const override
Return a human-readable string representing the type.
Definition: APEX_Types.h:334
int64 exint
Definition: SYS_Types.h:125
bool isVariadic() const override
Return whether the type is a variadic arg.
Definition: APEX_Types.h:407
APEX_API APEX_VoidTypeDefinition void_type_defn
void * allocate(exint size) const override
Definition: APEX_Types.h:347
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...
3D Vector class.
2D Vector class.
Definition: UT_Vector2.h:162
GLuint buffer
Definition: glcorearb.h:660
uint64 value_type
Definition: GA_PrimCompat.h:29
Holds all of the memory for execution state of a compiled APEX graph.
Definition: APEX_Buffer.h:97
constexpr auto APEX_TypeDefaultIsSpecialized_v
Definition: APEX_Types.h:153
void * allocate(exint size) const override
Definition: APEX_Types.h:264
virtual exint append(void *mem) const =0
void deallocate(void *mem) const override
Free a resizable array created by allocate.
Definition: APEX_Types.h:374
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
exint emplace_back(S &&...s)
Definition: UT_ArrayImpl.h:781
virtual void deallocate(void *mem) const =0
Free a resizable array created by allocate.
static constexpr bool isDefaultConstructing
Definition: APEX_Types.h:103
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...
Definition: APEX_Types.h:410
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.
Definition: CLI11.h:1729
UT_Matrix3T< Float > Matrix3
Definition: APEX_Include.h:67
exint append(void *mem) const override
Definition: APEX_Types.h:357
UN_PortID APEX_PortID
Definition: APEX_Include.h:236
bool isHandle() const override
Return whether the type is a handle to some shared data (i.e. geometry)
Definition: APEX_Types.h:408
UT_Matrix4T< Float > Matrix4
Definition: APEX_Include.h:68
exint append(void *mem) const override
Definition: APEX_Types.h:266
virtual void setData(void *mem, const void *val) const =0
Copy the value at val to mem.
GLuint const GLchar * name
Definition: glcorearb.h:786
static void * allocate(exint size)
Called to allocate a UT_Array<T> of length size.
Definition: APEX_Types.h:188
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...
Definition: APEX_Types.h:271
exint entries(void *mem) const
Definition: APEX_Types.h:340
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...
Definition: APEX_Types.h:262
void clear(void *mem) const override
Reset the instance of this type (member of buffer created in allocate) to a default value if possible...
Definition: APEX_Types.h:352
static T value()
Return a default value for the type.
Definition: APEX_Types.h:98
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:669
void deallocate(void *mem) const override
Free a resizable array created by allocate.
Definition: APEX_Types.h:267
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
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
const UT_StringRef & repr() const override
Return a human-readable string representing the type.
Definition: APEX_Types.h:263
UT_Vector2T< Float > Vector2
Definition: APEX_Include.h:64
static bool isHandle()
Definition: APEX_Types.h:224
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
bool isCopyable() const override
Return whether the type is copy-assignable (i.e. can setData function).
Definition: APEX_Types.h:273
GLuint index
Definition: glcorearb.h:786
GLuint GLfloat * val
Definition: glcorearb.h:1608
void setData(SYS_MAYBE_UNUSED void *mem, SYS_MAYBE_UNUSED const void *val) const override
Definition: APEX_Types.h:386
virtual bool isVariadic() const
Return whether the type is a variadic arg.
Definition: APEX_Types.h:88
static void clear(T *mem)
Given an initialized instance of T, reset it to the default state.
Definition: APEX_Types.h:198
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override
Definition: APEX_Types.h:398
UT_Vector3T< Float > Vector3
Definition: APEX_Include.h:65
bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port) const override
Definition: APEX_Types.h:270
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.
Definition: APEX_Types.h:272
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.
Definition: APEX_Types.h:269
static bool compile(APEX_Buffer *buffer, APEX_Graph *graph, APEX_PortID port)
Definition: APEX_Types.h:196
bool isArray() const override
Return whether the type is an array.
Definition: APEX_Types.h:406
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...
Definition: APEX_Types.h:336
virtual bool isHandle() const
Return whether the type is a handle to some shared data (i.e. geometry)
Definition: APEX_Types.h:90
APEX_TypeDefinition(const UT_StringLit &&type_name)
Definition: APEX_Types.h:308
GLenum src
Definition: glcorearb.h:1793
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...