HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UN_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: UN_Types.h ( UN Library, C++)
7  *
8  * COMMENTS: Common C++ types used in the UN library.
9  *
10  */
11 
12 #ifndef __UN_Types_h__
13 #define __UN_Types_h__
14 
15 #include "UN_API.h"
16 #include <SYS/SYS_Types.h>
17 #include <SYS/SYS_Hash.h> // For SYShash() use in hash_value().
18 #include <UT/UT_StringHolder.h>
19 
20 template <typename> class UT_Array;
21 
22 
23 // TODO: FIXME: Can the data numbers be `int` instead of `int64`?
24 // Will they be different for indexing and for identification?
26 {
27 public:
28  /// A numerical value for indexing into data containers and for
29  /// unique IDs to validate of data objects.
30  ///
31  /// An enum class `ValueType` and `UN_DataNumber` should be interchangeable.
32  /// UN_DataNumber really just provides methods to operate on it and
33  /// the ability to "derive" from it.
34  /// In particular, it should be possible to implicitly cast `ValueType`
35  /// to UN_DataNumber class type.
36  /// It should be possible to implicitly cast this UN_DataNumber class type
37  /// to ValueType since it is an enum class, and therefore
38  /// not implicitly castable to other types such as `exint` or `int`
39  /// (and therefore deemed "safe" without the risk of data narrowing).
41  enum class ValueType : ValueIntType {};
42 
43  /// A numerical value for an invalid data object number.
44  /// It is used in initialization to denote a non-existent, invalid,
45  /// or an unknown data object.
46  /// The value of -1 is consistent in its use as an index into data arrays.
47  static constexpr ValueType INVALID_NUMBER = ValueType(-1);
48 
49  /// A constructor for the data number.
50  /// Note, this is not an explicit constructor to allow asting from
51  /// ValueType to UN_DataNumber. See comment for `ValueType` definition.
53  : myValue( value ) {}
54 
55  /// @{ Returns true if this data number is valid; false otherwise.
56  bool isValid() const
57  { return myValue != INVALID_NUMBER; }
58  explicit operator bool() const
59  { return isValid(); }
60  /// @}
61 
62  /// Sets the numerical value of this number.
64  { myValue = value; }
65 
66  /// Returns the numerical value of this number.
67  ValueType value() const
68  { return myValue; }
69 
70  /// Implicit cast to `ValueType` since it is an enum class.
71  /// See the comment for `ValueType` definition.
72  operator ValueType() const
73  { return value(); }
74 
75  /// @{ Comparison operators.
76  bool operator==( const UN_DataNumber &other ) const
77  { return myValue == other.myValue; }
78  bool operator!=( const UN_DataNumber &other ) const
79  { return myValue != other.myValue; }
80  bool operator<( const UN_DataNumber &other ) const
81  { return myValue < other.myValue; }
82  bool operator<=( const UN_DataNumber &other ) const
83  { return myValue <= other.myValue; }
84  bool operator>( const UN_DataNumber &other ) const
85  { return myValue > other.myValue; }
86  bool operator>=( const UN_DataNumber &other ) const
87  { return myValue >= other.myValue; }
88  /// @}
89 
90  /// @{ Basic arithmetic operators.
92  {
93  myValue = ValueType( ValueIntType(myValue) + 1);
94  return *this;
95  }
97  {
98  UN_DataNumber tmp( *this );
99  myValue = ValueType( ValueIntType(myValue) + 1);
100  return tmp;
101  }
102  /// @}
103 
104  /// Hash function for use of UN_DataNumber as a key in the UT_Map class.
105  friend size_t hash_value( const UN_DataNumber &data_number )
106  { return SYShash( data_number.value() ); }
107 
108 private:
109  /// The value of the data number.
110  ValueType myValue;
111 };
112 
113 
114 /// A type denoting the size of data arrays indexed with UN_DataIndex.
116 {
117 public:
119  : UN_DataNumber( value ) {}
120 
121  /// An exint is used for UT_Array sizes, and UN_DataSize represents
122  /// such size, so these types should be interchangeable.
123  /// Thus providing a constructor from exint.
124  explicit UN_DataSize( exint value )
125  : UN_DataNumber( static_cast<ValueType>( value ))
126  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
127 
128  /// Returns an exint value of this data index.
130  {
131  SYS_STATIC_ASSERT( sizeof(ValueType) == sizeof(exint) );
132  return static_cast<exint>( value() );
133  }
134 
135  /// Implicit cast to `exint` for sizing arrays (eg, UT_Array).
136  operator exint() const
137  { return exintValue(); }
138 };
139 
140 
141 /// An index into a data container, referring to a particular data object.
142 /// Indices may be reused for new data objects, if old objects were deleted.
144 {
145 public:
147  : UN_DataNumber( value ) {}
148 
149  /// For past-end array index.
151  : UN_DataNumber( size ) {}
152 
153  /// An exint is used for indexing into UT_Array, and UN_DataIndex represents
154  /// such index, so these types should be interchangeable.
155  /// Thus providing a constructor from exint.
157  : UN_DataNumber( static_cast<ValueType>( value ))
158  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
159 
160  /// Resets the index to an invalid value.
161  void clear()
162  { setValue( INVALID_NUMBER ); }
163 
164  /// Returns an exint value of this data index.
166  {
167  SYS_STATIC_ASSERT( sizeof(ValueType) == sizeof(exint) );
168  return static_cast<exint>( value() );
169  }
170 
171  /// Implicit cast to `exint` for indexing into arrays (eg, UT_Array).
172  operator exint() const
173  { return exintValue(); }
174 };
175 
176 
177 /// An index into a node data container, referring to a node data object.
178 /// Indices may be reused for new node data objects, if old ones were deleted.
180 {
181 public:
182  /// An index of the graph's root node.
183  /// Note, the graph root node's index value of 0 is asserted as an
184  /// invariant in UN_GraphData constructor.
185  static constexpr ValueType ROOT_NODE_INDEX = ValueType(0);
186 
187  /// A constructor for the node data index.
188  explicit UN_NodeIndex( UN_DataIndex data_index = UN_DataIndex() )
189  : UN_DataIndex( data_index ) {}
190 
191  /// Returns true if this index refers to the root node.
192  bool isRootNode() const
193  { return value() == ROOT_NODE_INDEX; }
194 };
195 
196 
197 /// An index of the graph's root node.
198 static const UN_NodeIndex UN_ROOT_NODE_INDEX = UN_NodeIndex( UN_DataIndex(
200 
201 /// An array of node indices.
203 
204 
205 
206 /// An index into a wire data container, referring to a wire data object.
207 /// Indices may be reused for new wire data objects, if old ones were deleted.
209 {
210 public:
211  explicit UN_WireIndex( UN_DataIndex data_index = UN_DataIndex() )
212  : UN_DataIndex( data_index ) {}
213 };
214 
215 /// An array of wire IDs
217 
218 
219 /// An index into a parameter data container, referring to a parm data object.
220 /// Indices may be reused for new data objects, if old ones were deleted.
222 {
223 public:
224  explicit UN_ParmIndex( UN_DataIndex data_index = UN_DataIndex() )
225  : UN_DataIndex( data_index ) {}
226 };
227 
228 /// An array of parameter indices.
230 
231 
232 /// An index into a port data container, referring to a port data object.
233 /// Indices may be reused for new data objects, if old ones were deleted.
235 {
236 public:
237  explicit UN_PortIndex( UN_DataIndex data_index = UN_DataIndex() )
238  : UN_DataIndex( data_index ) {}
239 };
240 
241 /// An array of port indices.
243 
244 
245 /// A unique identifier of a particular data object.
246 /// Data objects of the same type (eg, nodes or ports) are assigned a unique ID
247 /// in a given graph, and no two data objects of that type share same ID,
248 /// withing the lifespan of the given graph.
249 /// Ie, unlike indices, the IDs are not reused for new data objects,
250 /// even if some old objects were deleted.
251 class UN_DataID : public UN_DataNumber
252 {
253 public:
255  : UN_DataNumber( value ) {}
256 
257  // Convenience constructor to create an ID from an exint value.
258  explicit UN_DataID( exint value )
259  : UN_DataNumber( static_cast<ValueType>( value ))
260  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
261 };
262 
263 /// An array of data IDs.
265 
266 
267 /// Data ID is unique throughout the lifespan of a graph, but only for
268 /// within the same data (eg, nodes). Ie, a node may have same data id
269 /// as a wire. So it's a good idea to keep these type spaces separate.
270 /// Defines types for various data ID numbers.
271 
272 /// An node ID.
273 class UN_NodeID : public UN_DataID
274 {
275 public:
276  explicit UN_NodeID( UN_DataID data_id = UN_DataID() )
277  : UN_DataID( data_id ) {}
278 };
279 
280 /// An array of node IDs.
282 
283 
284 /// A wire ID.
285 class UN_WireID : public UN_DataID
286 {
287 public:
288  explicit UN_WireID( UN_DataID data_id = UN_DataID() )
289  : UN_DataID( data_id ) {}
290 };
291 
292 /// An array of node IDs.
294 
295 
296 /// A port ID.
297 class UN_PortID : public UN_DataID
298 {
299 public:
300  explicit UN_PortID( UN_DataID data_id = UN_DataID() )
301  : UN_DataID( data_id ) {}
302 };
303 
304 /// An array of port IDs.
306 
307 
308 /// A parameter ID.
309 class UN_ParmID : public UN_DataID
310 {
311 public:
312  explicit UN_ParmID( UN_DataID data_id = UN_DataID() )
313  : UN_DataID( data_id ) {}
314 };
315 
316 /// An array of parameter IDs.
318 
319 
320 
321 /// Differentiates input node ports from output node ports.
322 enum class UN_PortKind
323 {
324  INVALID, // Unknown port kind; used for uninitialized state or errors.
325  INPUT, // Indicates an input port.
326  OUTPUT // Indicates an output port.
327 };
328 
329 
330 /// Unknown or undefined port type name: an empty string.
331 static constexpr UT_StringLit UN_UNDEFINED_PORT_TYPE_NAME;
332 
333 
334 /// Unknown or undefined parameter type name: an empty string.
335 static constexpr UT_StringLit UN_UNDEFINED_PARM_TYPE_NAME;
336 
337 
338 /// Returns true if the given type name is invalid; false otherwise;
339 static inline bool UNisValid( const UT_StringRef &type_name )
340  { return type_name.isstring(); }
341 
342 #endif
343 
#define SYS_STATIC_ASSERT(expr)
void clear()
Resets the index to an invalid value.
Definition: UN_Types.h:161
ValueType value() const
Returns the numerical value of this number.
Definition: UN_Types.h:67
UN_DataNumber & operator++()
Basic arithmetic operators.
Definition: UN_Types.h:91
UN_DataIndex(ValueType value=INVALID_NUMBER)
Definition: UN_Types.h:146
UN_PortKind
Differentiates input node ports from output node ports.
Definition: UN_Types.h:322
bool isRootNode() const
Returns true if this index refers to the root node.
Definition: UN_Types.h:192
exint exintValue() const
Returns an exint value of this data index.
Definition: UN_Types.h:129
friend size_t hash_value(const UN_DataNumber &data_number)
Hash function for use of UN_DataNumber as a key in the UT_Map class.
Definition: UN_Types.h:105
int64 exint
Definition: SYS_Types.h:125
UN_PortID(UN_DataID data_id=UN_DataID())
Definition: UN_Types.h:300
A wire ID.
Definition: UN_Types.h:285
bool operator>=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:86
UN_ParmID(UN_DataID data_id=UN_DataID())
Definition: UN_Types.h:312
exint ValueIntType
Definition: UN_Types.h:40
bool isValid() const
Returns true if this data number is valid; false otherwise.
Definition: UN_Types.h:56
A parameter ID.
Definition: UN_Types.h:309
UN_DataNumber operator++(int)
Basic arithmetic operators.
Definition: UN_Types.h:96
bool operator>(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:84
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
A type denoting the size of data arrays indexed with UN_DataIndex.
Definition: UN_Types.h:115
exint exintValue() const
Returns an exint value of this data index.
Definition: UN_Types.h:165
UN_NodeID(UN_DataID data_id=UN_DataID())
Definition: UN_Types.h:276
bool operator<(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:80
UN_NodeIndex(UN_DataIndex data_index=UN_DataIndex())
A constructor for the node data index.
Definition: UN_Types.h:188
GLsizeiptr size
Definition: glcorearb.h:664
bool operator<=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:82
UN_DataNumber(ValueType value=INVALID_NUMBER)
Definition: UN_Types.h:52
static constexpr ValueType INVALID_NUMBER
Definition: UN_Types.h:47
UN_DataID(exint value)
Definition: UN_Types.h:258
A port ID.
Definition: UN_Types.h:297
bool operator==(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:76
static constexpr ValueType ROOT_NODE_INDEX
Definition: UN_Types.h:185
UN_DataIndex(UN_DataSize size)
For past-end array index.
Definition: UN_Types.h:150
bool operator!=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Types.h:78
UN_DataIndex(exint value)
Definition: UN_Types.h:156
Definition: core.h:1131
UN_WireIndex(UN_DataIndex data_index=UN_DataIndex())
Definition: UN_Types.h:211
void setValue(ValueType value)
Sets the numerical value of this number.
Definition: UN_Types.h:63
UN_PortIndex(UN_DataIndex data_index=UN_DataIndex())
Definition: UN_Types.h:237
UN_DataSize(exint value)
Definition: UN_Types.h:124
SYS_FORCE_INLINE bool isstring() const
UN_DataSize(ValueType value=ValueType(0))
Definition: UN_Types.h:118
An node ID.
Definition: UN_Types.h:273
UN_DataID(ValueType value=INVALID_NUMBER)
Definition: UN_Types.h:254
UN_WireID(UN_DataID data_id=UN_DataID())
Definition: UN_Types.h:288
UN_ParmIndex(UN_DataIndex data_index=UN_DataIndex())
Definition: UN_Types.h:224