HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UN_Include.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_Include.h ( UN Library, C++)
7  *
8  * COMMENTS: Common C++ types used in the UN library.
9  *
10  */
11 
12 #ifndef __UN_Include_h__
13 #define __UN_Include_h__
14 
15 #include "UN_API.h"
16 #include <UT/UT_Array.h>
17 #include <UT/UT_ArrayMap.h>
18 #include <UT/UT_Options.h>
19 #include <UT/UT_StringHolder.h>
20 #include <UT/UT_UniquePtr.h> // IWYU pragma: export
21 #include <SYS/SYS_Types.h>
22 #include <SYS/SYS_Hash.h> // For SYShash() use in hash_value().
23 
24 // TODO: FIXME: Can the data numbers be `int` instead of `int64`?
25 // Will they be different for indexing and for identification?
27 {
28 public:
29  /// A numerical value for indexing into data containers and for
30  /// unique IDs to validate of data objects.
31  ///
32  /// An enum class `ValueType` and `UN_DataNumber` should be interchangeable.
33  /// UN_DataNumber really just provides methods to operate on it and
34  /// the ability to "derive" from it.
35  /// In particular, it should be possible to implicitly cast `ValueType`
36  /// to UN_DataNumber class type.
37  /// It should be possible to implicitly cast this UN_DataNumber class type
38  /// to ValueType since it is an enum class, and therefore
39  /// not implicitly castable to other types such as `exint` or `int`
40  /// (and therefore deemed "safe" without the risk of data narrowing).
42  enum class ValueType : ValueIntType {};
43 
44  /// A numerical value for an invalid data object number.
45  /// It is used in initialization to denote a non-existent, invalid,
46  /// or an unknown data object.
47  /// The value of -1 is consistent in its use as an index into data arrays.
48  static constexpr ValueType INVALID_NUMBER = ValueType(-1);
49 
50  /// A constructor for the data number.
51  /// Note, this is not an explicit constructor to allow asting from
52  /// ValueType to UN_DataNumber. See comment for `ValueType` definition.
54  : myValue( value ) {}
55 
56  /// @{ Returns true if this data number is valid; false otherwise.
57  constexpr bool isValid() const
58  { return myValue != INVALID_NUMBER; }
59  constexpr explicit operator bool() const
60  { return isValid(); }
61  /// @}
62 
63  /// Sets the numerical value of this number.
65  { myValue = value; }
66 
67  /// Returns the numerical value of this number.
68  constexpr ValueType value() const
69  { return myValue; }
70 
71  /// Implicit cast to `ValueType` since it is an enum class.
72  /// See the comment for `ValueType` definition.
73  operator ValueType() const
74  { return value(); }
75 
76  /// Returns an exint value of this number.
77  constexpr exint exintValue() const
78  {
80  sizeof(ValueType) == sizeof(exint) );
81  return static_cast<exint>( value() );
82  }
83 
84 
85  /// @{ Comparison operators.
86  constexpr bool operator==( const UN_DataNumber &other ) const
87  { return myValue == other.myValue; }
88  constexpr bool operator!=( const UN_DataNumber &other ) const
89  { return myValue != other.myValue; }
90  constexpr bool operator<( const UN_DataNumber &other ) const
91  { return myValue < other.myValue; }
92  constexpr bool operator<=( const UN_DataNumber &other ) const
93  { return myValue <= other.myValue; }
94  constexpr bool operator>( const UN_DataNumber &other ) const
95  { return myValue > other.myValue; }
96  constexpr bool operator>=( const UN_DataNumber &other ) const
97  { return myValue >= other.myValue; }
98  /// @}
99 
100  /// @{ Basic arithmetic operators.
102  {
103  myValue = ValueType( ValueIntType(myValue) + 1);
104  return *this;
105  }
107  {
108  UN_DataNumber tmp( *this );
109  myValue = ValueType( ValueIntType(myValue) + 1);
110  return tmp;
111  }
112  /// @}
113 
114  /// Hash function for use of UN_DataNumber as a key in the UT_Map class.
115  friend size_t hash_value( const UN_DataNumber &data_number )
116  { return SYShash( data_number.value() ); }
117 
118 private:
119  /// The value of the data number.
120  ValueType myValue;
121 };
122 
123 
124 /// A type denoting the size of data arrays indexed with UN_DataIndex.
125 /// It can also be used as the size of the interval between indices,
126 /// eg, to offset an index by a delta.
128 {
129 public:
130  /// Constructs the size object given the numerical value.
132  : UN_DataNumber( value ) {}
133 
134  /// An exint is used for UT_Array sizes, and UN_DataSize represents
135  /// such size, so these types should be interchangeable.
136  /// Thus providing a constructor from exint.
137  explicit UN_DataSize( exint value )
138  : UN_DataNumber( static_cast<ValueType>( value ))
139  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
140 
141  /// Implicit cast to `exint` for sizing arrays (eg, UT_Array).
142  operator exint() const
143  { return exintValue(); }
144 };
145 
146 
147 /// An index into a data container, referring to a particular data object.
148 /// Indices may be reused for new data objects, if old objects were deleted.
150 {
151 public:
152  /// Constructs the index object given the numerical value.
154  : UN_DataNumber( value ) {}
155 
156  /// For past-end array index.
158  : UN_DataNumber( size ) {}
159 
160  /// An exint is used for indexing into UT_Array, and UN_DataIndex represents
161  /// such index, so these types should be interchangeable.
162  /// Thus providing a constructor from exint.
164  : UN_DataNumber( static_cast<ValueType>( value ))
165  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
166 
167  /// Resets the index to an invalid value.
168  void clear()
169  { setValue( INVALID_NUMBER ); }
170 
171  /// Implicit cast to `exint` for indexing into arrays (eg, UT_Array).
172  operator exint() const
173  { return exintValue(); }
174 
175  /// @{ Some arithmetic operators that make sense on indices.
177  {
178  return UN_DataIndex( ValueType(
179  exintValue() + offset.exintValue() ));
180  }
181 
183  {
184  return UN_DataIndex( ValueType(
185  exintValue() - offset.exintValue() ));
186  }
187 
189  {
190  *this = *this + offset;
191  return *this;
192  }
193 
195  {
196  *this = *this - offset;
197  return *this;
198  }
199  /// @}
200 
201 };
202 
203 
204 /// A range of contiguous data indices.
205 /// Commonly used for copying blocks of data in the buffers.
207 {
208 public:
209  /// Construct the data index span range object given.
211  : myStart(start), mySize(size)
212  {}
213 
214  /// Returns the first index in the range.
216  { return myStart; }
217 
218  /// Returns the number of indices in the range.
219  UN_DataSize size() const
220  { return mySize; }
221 
222 private:
223  UN_DataIndex myStart;
224  UN_DataSize mySize;
225 };
226 
227 /// An index into a data container, referring to a data object.
228 /// Indices may be reused for new data objects, if old ones were deleted.
229 #define UN_DATA_INDEX(Class) \
230 class Class : public UN_DataIndex \
231 { \
232 public: \
233  explicit Class( UN_DataIndex data_index = UN_DataIndex() ) \
234  : UN_DataIndex( data_index ) {} \
235 }; \
236  \
237 using Class##List = UT_Array< Class >; \
238 
239 UN_DATA_INDEX( UN_NodeIndex )
240 UN_DATA_INDEX( UN_ParmIndex )
241 UN_DATA_INDEX( UN_PortIndex )
242 UN_DATA_INDEX( UN_WireIndex )
243 UN_DATA_INDEX( UN_MetaDataIndex )
244 UN_DATA_INDEX( UN_SubnetIndex )
245 
246 
247 /// A unique identifier of a particular data object.
248 /// Data objects of the same type (eg, nodes or ports) are assigned a unique ID
249 /// in a given graph, and no two data objects of that type share same ID,
250 /// withing the lifespan of the given graph.
251 /// Ie, unlike indices, the IDs are not reused for new data objects,
252 /// even if some old objects were deleted.
254 {
255 public:
256  /// Constructs the ID object given the numerical value.
257  constexpr explicit UN_DataID( ValueType value = INVALID_NUMBER )
258  : UN_DataNumber( value ) {}
259 
260  // Convenience constructor to create an ID from an exint value.
261  constexpr explicit UN_DataID( exint value )
262  : UN_DataNumber( static_cast<ValueType>( value ))
263  { SYS_STATIC_ASSERT( sizeof(value) == sizeof(ValueType) ); }
264 
265  /// Cast to `exint` for use in template functions that cast templated types,
266  /// but for now make it explicit, to discourage the numerical aspect of IDs.
267  explicit operator exint() const
268  { return exintValue(); }
269 
270  /// Resets the ID to an invalid value.
271  void clear()
272  { setValue( INVALID_NUMBER ); }
273 };
274 
275 /// A list of data IDs.
277 
278 // Forward declare the templated remap, to use in the macro below.
279 template <typename ID> class UN_DataIDRemapT;
280 
281 /// Data ID is unique throughout the lifespan of a graph, but only for
282 /// within the same data class (eg, nodes). Ie, a node may have same data id
283 /// as a wire. So it's a good idea to keep these type spaces separate.
284 /// Defines types for various data ID numbers.
285 
286 #define UN_DATA_ID( Class ) \
287 class Class : public UN_DataID \
288 { \
289 public: \
290  constexpr explicit Class( UN_DataID data_id = UN_DataID() ) \
291  : UN_DataID( data_id ) {} \
292 }; \
293  \
294 using Class##List = UT_Array< Class >; \
295 using Class##Remap = UN_DataIDRemapT< Class >; \
296 
297 UN_DATA_ID( UN_NodeID )
298 UN_DATA_ID( UN_ParmID )
299 UN_DATA_ID( UN_PortID )
300 UN_DATA_ID( UN_WireID )
301 UN_DATA_ID( UN_MetaDataID )
302 UN_DATA_ID( UN_SubnetID )
303 
304 /// Index and ID of the graph's root node.
305 /// We often treat the root node in a special way,
306 /// eg, skip it when iterating actual graph nodes, skip it in merging graphs.
307 /// We can make that code simpler and faster if we can assume that
308 /// the root ID and INDEX is 0.
309 static constexpr UN_DataID UN_ID_ZERO( UN_DataID(0) );
310 static constexpr UN_NodeID UN_ROOT_NODE_ID( UN_ID_ZERO );
311 static constexpr UN_SubnetID UN_ROOT_SUBNET_ID( UN_ID_ZERO );
312 
313 /// Returns true if the given node ID corresponds to the graph root node.
314 static inline bool UNisRoot( UN_NodeID node_id )
315  { return node_id == UN_ROOT_NODE_ID; }
316 static inline bool UNisRoot( UN_SubnetID subnet_id )
317  { return subnet_id == UN_ROOT_SUBNET_ID; }
318 
319 
320 /// Class that remaps data IDs.
321 /// Eg, between merged data conainers, like UN_NodeData.
322 /// It's a lightweight object representing a mapping of old IDs to new ones.
323 /// NOTE: Assumes the underlying mapping is representable as a constant shift.
324 /// However it has a few range checks for consistency.
326 {
327 public:
328  /// Default constructor
329  UN_DataIDRemap() = default;
330 
331  /// Convenience constructor.
332  /// @p old_id_end - the limit on the original IDs in the source.
333  /// Used for rudimentary range checks.
334  /// @p new_id_start - the base destination ID at which the entries
335  /// copied from the source begin their new IDs in the destination.
336  /// If @p combine_id_zero is true, the data for the ID zero is not mapped
337  /// to a brand new data slot, but is remapped to an existing ID of zero.
338  /// Some data containers use ID of zero for a special entry
339  /// that is treated differently than the other ones. Notably,
340  /// the node data container uses ID of zero for the root node, and
341  /// the root node from the src should not become a regular node in dest.
342  /// Instead, src root ID maps to dst root ID and their data is combined.
343  UN_DataIDRemap( UN_DataID old_id_end,
344  UN_DataID new_id_start,
345  bool combine_id_zero = false )
346  : myNewStartID( new_id_start.exintValue() )
347  , myShouldCombineIDZero( combine_id_zero )
348  , myOldEndID( old_id_end.exintValue() )
349  {}
350 
351  /// Returns the start offset for the destination ID range.
352  /// I.e. the ID which source ID zero would be mapped to.
353  /// Can be used with @ref remapIdFromOffsets to map between ID sets
354  /// with identical structure.
356  { return myNewStartID; }
357 
358  /// Returns the limit for the old IDs source range.
360  { return myOldEndID; }
361 
362  /// Returns the number of IDs reserved by this merge map.
363  UN_DataSize size() const
364  { return UN_DataSize( myOldEndID.exintValue() ); }
365 
366  /// Return @c true if the mergemap was constructed with a valid
367  /// @c newStartOffset().
368  /// Default-constructed instances will return @c false.
369  explicit operator bool() const
370  { return myNewStartID.isValid(); }
371 
372  /// Returns the new ID corresponding to the @p old ID,
373  /// if the @p old ID is an ID contained within the source ID range;
374  /// otherwise, returns an invalid ID.
376  {
377  if( !old_id )
378  return UN_DataID(); // invalid ID
379  else if( old_id >= myOldEndID )
380  return UN_DataID(); // invalid old range
381  else if( myShouldCombineIDZero && old_id == UN_ID_ZERO )
382  return UN_ID_ZERO;
383  else
384  return UN_DataID( myNewStartID.exintValue() + old_id.exintValue()
385  - (myShouldCombineIDZero ? 1 : 0) );
386  }
387 
388  /// Returns the data ID that should be used for the data created next time.
390  {
391  return UN_DataID( myNewStartID.exintValue() + myOldEndID.exintValue()
392  - (myShouldCombineIDZero ? 1 : 0) );
393  }
394 
395 
396  /// Let O be some object in an ID set S.
397  /// If S is remapped multiple times at offsets A and B,
398  /// with I being its ID within A, then @c{remapIdFromOffsets(I, A, B)} will
399  /// return the ID of O within the remapping starting at B.
400  /// If these conditions are not met, an undefined ID is returned.
402  UN_DataID old_offset, UN_DataID new_offset )
403  {
404  return UN_DataID( old_id.exintValue() - old_offset.exintValue()
405  + new_offset.exintValue() );
406  }
407 
408 private:
409  /// The base destination ID that shifts the old IDs to the new IDs.
410  UN_DataID myNewStartID;
411 
412  /// The flag to indicate whether the data for the ID zero is mapped
413  /// to a brand new data slot or is mapped to an existing ID of zero.
414  /// Some data containers use ID of zero for a special entry
415  /// that is treated differently than the other ones. Notably,
416  /// the node data container uses ID of zero for the root node, and
417  /// the root node from the src should not become a regular node in dest.
418  /// Instead, src root ID maps to dst root ID and their data is combined.
419  bool myShouldCombineIDZero = false;
420 
421  /// The range limit of the original IDs (for basic consistency checks).
422  UN_DataID myOldEndID;
423 };
424 
425 
426 /// Adaptor of the UN_DataIDRemap to specific data types.
427 template <typename ID>
428 class UN_DataIDRemapT : public UN_DataIDRemap
429 {
430 public:
431  /// Default constructor
432  UN_DataIDRemapT() = default;
433 
434  /// Convenience constructor that takes an instance of the base class.
435  UN_DataIDRemapT( const UN_DataIDRemap &remap_base )
436  : UN_DataIDRemap( remap_base )
437  {}
438 
439  /// Convenience constructor. See UN_DataIDRemap.
440  UN_DataIDRemapT( ID old_id_end, ID new_id_start,
441  bool combine_id_zero = false )
442  : UN_DataIDRemap( old_id_end, new_id_start, combine_id_zero )
443  {}
444 
445  /// Returns the new ID corresponding to the @p old ID,
446  /// if the @p old ID is an ID contained within the source ID range;
447  /// otherwise, returns an invalid ID.
448  ID operator[]( ID old_id ) const
449  { return ID(UN_DataIDRemap::operator[]( old_id )); }
450 
451  /// @see operator[]
452  ID at( ID old_id ) const
453  { return operator[]( old_id ); }
454 };
455 
456 
457 /// Information about data entries merged from another map.
458 /// Data buffers use this info to actually copy over the corresponding data.
460 {
461 public:
462  /// Constructor.
463  UN_DataMergeInfo( UN_DataIDRemap &&data_id_remap,
464  UT_Array<UN_DataIndexSpan> &&data_idx_spans )
465  : myDataIDRemap( std::move( data_id_remap ))
466  , myDataIndexSpans( std::move( data_idx_spans ))
467  {}
468 
469  /// Returns the continous index ranges that can be block-copied.
471  { return myDataIndexSpans; }
472 
473  /// Returns the data IDs remapping that occured during a merge.
474  /// Maps the old ID from the merge source to the new ID in destination.
475  const UN_DataIDRemap & dataIDRemap() const
476  { return myDataIDRemap; }
477 
478 
479 private:
480  /// A map between merged data's old IDs in the source
481  /// and the new IDs in the destination.
482  UN_DataIDRemap myDataIDRemap;
483 
484  /// Data buffers often use contiguous arrays. To optimize copying
485  /// data during a merge, they can use this info to bulk-copy entries.
486  UT_Array< UN_DataIndexSpan > myDataIndexSpans;
487 };
488 
489 
490 /// Package of remappings for various data ID types (nodes, ports, subnets).
492 {
493 public:
494  /// Constructors
495  UN_IDRemapInfo() = default;
497  UN_NodeID root_destination_node,
498  UN_NodeIDRemap &&node_id_remap,
499  UN_SubnetIDRemap &&subnet_id_remap,
500  UN_PortIDRemap &&port_id_remap,
501  UN_PortIDRemap &&wire_id_remap )
502  : myRootDstNode( root_destination_node )
503  , myNodeIDRemap( std::move(node_id_remap) )
504  , mySubnetIDRemap( std::move(subnet_id_remap) )
505  , myPortIDRemap( std::move(port_id_remap) )
506  , myWireIDRemap( std::move(wire_id_remap) )
507  {}
508 
509  // An existing node in the destination graph to which the source root
510  // should map to. Ie, into which node to merge the other graph.
511  UN_NodeID rootDstNode() const { return myRootDstNode; }
512 
513  /// @{ Returns the object the remaps the various data IDs
514  /// from the src to dst after the graph merge.
515  const UN_NodeIDRemap & nodeIDRemap() const { return myNodeIDRemap; }
516  const UN_SubnetIDRemap& subnetIDRemap() const { return mySubnetIDRemap; }
517  const UN_PortIDRemap & portIDRemap() const { return myPortIDRemap; }
518  const UN_WireIDRemap & wireIDRemap() const { return myWireIDRemap; }
519  /// @}
520 
521 private:
522  // TODO: FIXME: should the root be moved to UN_GraphMergeInfo?
523  // An existing node in the destination graph to which the source root
524  // should map to. Ie, into which node to merge the other graph.
525  UN_NodeID myRootDstNode;
526 
527  // Objects that remap data IDs from the src to the dst after the merge.
528  UN_NodeIDRemap myNodeIDRemap;
529  UN_SubnetIDRemap mySubnetIDRemap;
530  UN_PortIDRemap myPortIDRemap;
531  UN_WireIDRemap myWireIDRemap;
532 };
533 
534 /// Information about the result of a merge from another graph.
536 {
537 public:
538  /// Constructors
539  UN_GraphMergeInfo() = default;
541  : myIDRemapInfo( std::move( id_remap_info ))
542  {}
543 
544  /// Returns the object that contains mapping between data IDs after merge.
546  { return myIDRemapInfo; }
547 
548 private:
549  /// Contains mapping of IDs from source graph to IDs in destination graph.
550  UN_IDRemapInfo myIDRemapInfo;
551 };
552 
553 /// For debug printouts, etc:
554 #define UN_NUMBER_FORMATTER(IdOrIndexType) \
555 inline size_t format(char *buffer, size_t buffer_size, const IdOrIndexType &v) \
556 { \
557  UT::Format::Writer w(buffer, buffer_size); \
558  UT::Format::Formatter f; \
559  return f.format(w, #IdOrIndexType "({})", {v.exintValue()}); \
560 } \
561 inline size_t format(char *buffer, size_t buffer_size, \
562  const UT_Array<IdOrIndexType> &v) \
563 { \
564  UT::Format::Writer w(buffer, buffer_size); \
565  UT::Format::Formatter f; \
566  size_t bytesWritten = w("UT_Array<" #IdOrIndexType ">([", \
567  sizeof("UT_Array<" #IdOrIndexType ">([")-1); \
568  bool first = true; \
569  for (auto &&item : v) \
570  { \
571  bytesWritten += f.format(w, first ? "{}" : ", {}", \
572  {item.exintValue()}); \
573  first = false; \
574  } \
575  bytesWritten += w("])", 2); \
576  return bytesWritten; \
577 }
578 
579 
583 
584 UN_NUMBER_FORMATTER( UN_NodeID )
585 UN_NUMBER_FORMATTER( UN_ParmID )
586 UN_NUMBER_FORMATTER( UN_PortID )
587 UN_NUMBER_FORMATTER( UN_WireID )
588 UN_NUMBER_FORMATTER( UN_MetaDataID )
589 UN_NUMBER_FORMATTER( UN_SubnetID )
590 
591 UN_NUMBER_FORMATTER( UN_NodeIndex )
592 UN_NUMBER_FORMATTER( UN_ParmIndex )
593 UN_NUMBER_FORMATTER( UN_PortIndex )
594 UN_NUMBER_FORMATTER( UN_WireIndex )
595 UN_NUMBER_FORMATTER( UN_MetaDataIndex )
596 UN_NUMBER_FORMATTER( UN_SubnetIndex )
597 
598 
599 // Needed for data IDs and indices in UT_ArrayMap and UT_ArraySet classes.
600 namespace UT
601 {
602  template <typename T> struct DefaultClearer;
603 
604 
605  template <>
607  {
608  static void clear( UN_DataID &v ) { v = UN_DataID(); }
609  static bool isClear( const UN_DataID &v ) { return !v.isValid(); }
610  static void clearConstruct( UN_DataID *p ) { clear(*p); }
611  static const bool clearNeedsDestruction = false;
612  };
613 
614 #define UN_ID_CLEARER(ID) \
615  template <> struct DefaultClearer<ID> : public DefaultClearer<UN_DataID> {};
616 
617  UN_ID_CLEARER( UN_NodeID )
618  UN_ID_CLEARER( UN_ParmID )
619  UN_ID_CLEARER( UN_PortID )
620  UN_ID_CLEARER( UN_WireID )
621  UN_ID_CLEARER( UN_SubnetID )
622 
623 
624  template <>
626  {
627  static void clear( UN_DataIndex &v ) { v.clear(); }
628  static bool isClear( const UN_DataIndex &v ) { return !v.isValid(); }
629  static void clearConstruct( UN_DataIndex *p ) { clear(*p); }
630  static const bool clearNeedsDestruction = false;
631  };
632 
633 #define UN_INDEX_CLEARER(ID) \
634  template<> struct DefaultClearer<ID>: public DefaultClearer<UN_DataIndex>{};
635 
636  UN_INDEX_CLEARER( UN_NodeIndex )
637  UN_INDEX_CLEARER( UN_ParmIndex )
638  UN_INDEX_CLEARER( UN_PortIndex )
639  UN_INDEX_CLEARER( UN_WireIndex )
640  UN_INDEX_CLEARER( UN_SubnetIndex )
641 
642 } // end: namespace UT
643 
644 
645 /// Differentiates between input and output ports.
647 {
648  Invalid, // Unknown port kind; used for uninitialized state or errors.
649  Input, // Represents an input port.
650  Output // Represents an output port.
651 };
652 
653 
654 /// Unknown or undefined port type name: an empty string.
655 static constexpr UT_StringLit UN_UNDEFINED_PORT_TYPE_NAME;
656 
657 
658 /// Unknown or undefined parameter type name: an empty string.
659 static constexpr UT_StringLit UN_UNDEFINED_PARM_TYPE_NAME;
660 
661 
662 /// Returns true if the given type name is invalid; false otherwise;
663 static inline bool UNisValid( const UT_StringRef &type_name )
664  { return type_name.isstring(); }
665 
666 /// Graph serialization to UT_Options.
667 /// Using UT_UniquePtr<UT_Options> to return values, to indicate the ownership.
668 /// Using UT_UniquePtr<UT_OPtions> rather than UT_OptionsHolder because
669 /// it is more flexible: it's easier to further edit options (editing
670 /// UT_OptionsHolder is cumbersome), and it's easy to create UT_OptionsHolder
671 /// from the UT_UniquePtr, if need be.
674 
675 /// Returns a non-null pointer to the UN_Options.
676 static inline UN_OptionsPtr
677 UNmakeOptions()
678 {
679  return UN_OptionsPtr(new UT_Options());
680 }
681 
682 
683 #endif
684 
constexpr exint exintValue() const
Returns an exint value of this number.
Definition: UN_Include.h:77
constexpr UN_DataID(exint value)
Definition: UN_Include.h:261
UN_DataIndex operator+(UN_DataSize offset)
Some arithmetic operators that make sense on indices.
Definition: UN_Include.h:176
const UN_IDRemapInfo & idRemapInfo()
Returns the object that contains mapping between data IDs after merge.
Definition: UN_Include.h:545
#define SYS_STATIC_ASSERT(expr)
static bool isClear(const UN_DataIndex &v)
Definition: UN_Include.h:628
void clear()
Resets the index to an invalid value.
Definition: UN_Include.h:168
UN_DataIndexSpan(UN_DataIndex start, UN_DataSize size)
Construct the data index span range object given.
Definition: UN_Include.h:210
UN_DataIDRemap(UN_DataID old_id_end, UN_DataID new_id_start, bool combine_id_zero=false)
Definition: UN_Include.h:343
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
constexpr size_t SYShash(const SYS_Flicks f)
Definition: SYS_Flicks.h:46
UN_DataIndex operator-(UN_DataSize offset)
Some arithmetic operators that make sense on indices.
Definition: UN_Include.h:182
UN_GraphMergeInfo()=default
Constructors.
UN_DataNumber & operator++()
Basic arithmetic operators.
Definition: UN_Include.h:101
UN_DataIndex(ValueType value=INVALID_NUMBER)
Constructs the index object given the numerical value.
Definition: UN_Include.h:153
const GLdouble * v
Definition: glcorearb.h:837
GLuint start
Definition: glcorearb.h:475
GLsizei const GLfloat * value
Definition: glcorearb.h:824
const UN_SubnetIDRemap & subnetIDRemap() const
Definition: UN_Include.h:516
UN_DataIndex operator-=(UN_DataSize offset)
Some arithmetic operators that make sense on indices.
Definition: UN_Include.h:194
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_Include.h:115
int64 exint
Definition: SYS_Types.h:125
static void clearConstruct(UN_DataIndex *p)
Definition: UN_Include.h:629
UN_NodeID rootDstNode() const
Definition: UN_Include.h:511
UN_DataIndex operator+=(UN_DataSize offset)
Some arithmetic operators that make sense on indices.
Definition: UN_Include.h:188
UN_DataIndex start() const
Returns the first index in the range.
Definition: UN_Include.h:215
#define UN_NUMBER_FORMATTER(IdOrIndexType)
For debug printouts, etc:
Definition: UN_Include.h:554
constexpr bool operator!=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:88
constexpr bool operator>=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:96
UN_DataIDRemapT(ID old_id_end, ID new_id_start, bool combine_id_zero=false)
Convenience constructor. See UN_DataIDRemap.
Definition: UN_Include.h:440
Adaptor of the UN_DataIDRemap to specific data types.
Definition: UN_Include.h:279
__hostdev__ void setValue(uint32_t offset, bool v)
Definition: NanoVDB.h:5750
#define UN_INDEX_CLEARER(ID)
Definition: UN_Include.h:633
UN_DataID nextDataID() const
Returns the data ID that should be used for the data created next time.
Definition: UN_Include.h:389
constexpr UN_DataID(ValueType value=INVALID_NUMBER)
Constructs the ID object given the numerical value.
Definition: UN_Include.h:257
static UN_DataID remapIDFromOffsets(UN_DataID old_id, UN_DataID old_offset, UN_DataID new_offset)
Definition: UN_Include.h:401
const UN_DataIDRemap & dataIDRemap() const
Definition: UN_Include.h:475
UN_IDRemapInfo()=default
Constructors.
exint ValueIntType
Definition: UN_Include.h:41
OutGridT const XformOp bool bool
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
static void clearConstruct(UN_DataID *p)
Definition: UN_Include.h:610
#define UN_DATA_INDEX(Class)
Definition: UN_Include.h:229
UN_PortKind
Differentiates between input and output ports.
Definition: UN_Include.h:646
static bool isClear(const UN_DataID &v)
Definition: UN_Include.h:609
ID at(ID old_id) const
Definition: UN_Include.h:452
Package of remappings for various data ID types (nodes, ports, subnets).
Definition: UN_Include.h:491
GLintptr offset
Definition: glcorearb.h:665
ID operator[](ID old_id) const
Definition: UN_Include.h:448
UN_DataIDRemap()=default
Default constructor.
UN_DataNumber operator++(int)
Basic arithmetic operators.
Definition: UN_Include.h:106
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
const UT_Array< UN_DataIndexSpan > & dataIndexSpans() const
Returns the continous index ranges that can be block-copied.
Definition: UN_Include.h:470
const UN_WireIDRemap & wireIDRemap() const
Definition: UN_Include.h:518
UN_DataIDRemapT()=default
Default constructor.
constexpr bool isValid() const
Returns true if this data number is valid; false otherwise.
Definition: UN_Include.h:57
UN_DataMergeInfo(UN_DataIDRemap &&data_id_remap, UT_Array< UN_DataIndexSpan > &&data_idx_spans)
Constructor.
Definition: UN_Include.h:463
constexpr UN_DataNumber(ValueType value=INVALID_NUMBER)
Definition: UN_Include.h:53
#define UN_ID_CLEARER(ID)
Definition: UN_Include.h:614
static void clear(UN_DataIndex &v)
Definition: UN_Include.h:627
static void clear(UN_DataID &v)
Definition: UN_Include.h:608
constexpr bool operator==(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:86
UN_DataID newStartOffset() const
Definition: UN_Include.h:355
UN_DataID oldEndOffset() const
Returns the limit for the old IDs source range.
Definition: UN_Include.h:359
UN_GraphMergeInfo(UN_IDRemapInfo &&id_remap_info)
Definition: UN_Include.h:540
constexpr bool operator<(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:90
GLsizeiptr size
Definition: glcorearb.h:664
A map of string to various well defined value types.
Definition: UT_Options.h:84
const UN_NodeIDRemap & nodeIDRemap() const
Definition: UN_Include.h:515
const UN_PortIDRemap & portIDRemap() const
Definition: UN_Include.h:517
Information about the result of a merge from another graph.
Definition: UN_Include.h:535
static constexpr ValueType INVALID_NUMBER
Definition: UN_Include.h:48
UN_DataIndex(UN_DataSize size)
For past-end array index.
Definition: UN_Include.h:157
constexpr bool operator<=(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:92
UN_DataIndex(exint value)
Definition: UN_Include.h:163
constexpr bool operator>(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:94
UN_DataSize size() const
Returns the number of IDs reserved by this merge map.
Definition: UN_Include.h:363
void setValue(ValueType value)
Sets the numerical value of this number.
Definition: UN_Include.h:64
#define UN_DATA_ID(Class)
Definition: UN_Include.h:286
constexpr ValueType value() const
Returns the numerical value of this number.
Definition: UN_Include.h:68
UN_DataID operator[](UN_DataID old_id) const
Definition: UN_Include.h:375
UN_DataIDRemapT(const UN_DataIDRemap &remap_base)
Convenience constructor that takes an instance of the base class.
Definition: UN_Include.h:435
UN_IDRemapInfo(UN_NodeID root_destination_node, UN_NodeIDRemap &&node_id_remap, UN_SubnetIDRemap &&subnet_id_remap, UN_PortIDRemap &&port_id_remap, UN_PortIDRemap &&wire_id_remap)
Definition: UN_Include.h:496
UN_DataSize(exint value)
Definition: UN_Include.h:137
void clear()
Resets the ID to an invalid value.
Definition: UN_Include.h:271
SYS_FORCE_INLINE bool isstring() const
UN_DataSize(ValueType value=ValueType(0))
Constructs the size object given the numerical value.
Definition: UN_Include.h:131
UT_UniquePtr< UN_Options > UN_OptionsPtr
Definition: UN_Include.h:673
UN_DataSize size() const
Returns the number of indices in the range.
Definition: UN_Include.h:219