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 <UNI/UNI_Include.h>
17 #include <UT/UT_Array.h>
18 #include <UT/UT_ArrayMap.h>
19 #include <UT/UT_Options.h>
20 #include <UT/UT_StringHolder.h>
21 #include <UT/UT_UniquePtr.h> // IWYU pragma: export
22 #include <SYS/SYS_Types.h>
23 #include <SYS/SYS_Hash.h> // For SYShash() use in hash_value().
24 
25 
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 UN_DATA_INDEX( UN_StickyNoteIndex )
246 
247 
248 /// A unique identifier of a particular data object.
249 /// Data objects of the same type (eg, nodes or ports) are assigned a unique ID
250 /// in a given graph, and no two data objects of that type share same ID,
251 /// withing the lifespan of the given graph.
252 /// Ie, unlike indices, the IDs are not reused for new data objects,
253 /// even if some old objects were deleted.
256 
257 // Forward declare the templated remap, to use in the macro below.
258 template <typename ID> class UN_DataIDRemapT;
259 
260 /// Data ID is unique throughout the lifespan of a graph, but only for
261 /// within the same data class (eg, nodes). Ie, a node may have same data id
262 /// as a wire. So it's a good idea to keep these type spaces separate.
263 /// Defines types for various data ID numbers.
264 /// Note, since UN is an implementation of the UNI interface, it reuses
265 /// (aliases) the UNI IDs to avoid frequent type casts.
266 /// However, it is possible to decouple them if really needed in the future.
267 #define UN_DATA_ID( SubClass, BaseClass ) \
268 using SubClass = BaseClass; \
269 using SubClass##List = BaseClass##List; \
270 using SubClass##Remap = UN_DataIDRemapT< SubClass >; \
271 
272 UN_DATA_ID( UN_NodeID, UNI_NodeID )
273 UN_DATA_ID( UN_ParmID, UNI_ParmID )
274 UN_DATA_ID( UN_PortID, UNI_PortID )
275 UN_DATA_ID( UN_WireID, UNI_WireID )
276 UN_DATA_ID( UN_SubnetID, UNI_SubnetID )
277 UN_DATA_ID( UN_MetaDataID, UNI_MetaDataID )
278 UN_DATA_ID( UN_StickyNoteID,UNI_StickyNoteID )
279 
280 
281 /// Template function to return an array of data handles constructed
282 /// from an range of data IDs (eg, an array, a span, or a pair of iterators).
283 template <typename HANDLE, typename GRAPH_DATA, typename ID_RANGE>
284 static inline UT_Array< HANDLE >
285 UNhandleArray( GRAPH_DATA *graph_data, const ID_RANGE &data_ids )
286 {
287  UT_Array<HANDLE> result( data_ids.size() );
288 
289  for( auto &&data_id : data_ids )
290  result.append( HANDLE( graph_data, data_id ));
291 
292  return result;
293 }
294 
295 
296 /// Index and ID of the graph's root node.
297 /// We often treat the root node in a special way,
298 /// eg, skip it when iterating actual graph nodes, skip it in merging graphs.
299 /// We can make that code simpler and faster if we can assume that
300 /// the root ID and INDEX is 0.
301 static constexpr UN_DataID UN_ID_ZERO( UN_DataID(0) );
302 static constexpr UN_NodeID UN_ROOT_NODE_ID( UN_ID_ZERO );
303 static constexpr UN_SubnetID UN_ROOT_SUBNET_ID( UN_ID_ZERO );
304 
305 /// Returns true if the given node ID corresponds to the graph root node.
306 static inline bool UNisRoot( UN_NodeID node_id )
307  { return node_id == UN_ROOT_NODE_ID; }
308 static inline bool UNisRoot( UN_SubnetID subnet_id )
309  { return subnet_id == UN_ROOT_SUBNET_ID; }
310 
311 
312 /// Class that remaps data IDs.
313 /// Eg, between merged data conainers, like UN_NodeData.
314 /// It's a lightweight object representing a mapping of old IDs to new ones.
315 /// NOTE: Assumes the underlying mapping is representable as a constant shift.
316 /// However it has a few range checks for consistency.
318 {
319 public:
320  /// Default constructor
321  UN_DataIDRemap() = default;
322 
323  /// Convenience constructor.
324  /// @p old_id_end - the limit on the original IDs in the source.
325  /// Used for rudimentary range checks.
326  /// @p new_id_start - the base destination ID at which the entries
327  /// copied from the source begin their new IDs in the destination.
328  /// If @p combine_id_zero is true, the data for the ID zero is not mapped
329  /// to a brand new data slot, but is remapped to an existing ID of zero.
330  /// Some data containers use ID of zero for a special entry
331  /// that is treated differently than the other ones. Notably,
332  /// the node data container uses ID of zero for the root node, and
333  /// the root node from the src should not become a regular node in dest.
334  /// Instead, src root ID maps to dst root ID and their data is combined.
335  UN_DataIDRemap( UN_DataID old_id_end,
336  UN_DataID new_id_start,
337  bool combine_id_zero = false )
338  : myNewStartID( new_id_start.exintValue() )
339  , myShouldCombineIDZero( combine_id_zero )
340  , myOldEndID( old_id_end.exintValue() )
341  {}
342 
343  /// Returns the start offset for the destination ID range.
344  /// I.e. the ID which source ID zero would be mapped to.
345  /// Can be used with @ref remapIdFromOffsets to map between ID sets
346  /// with identical structure.
347  UN_DataID newStartOffset() const
348  { return myNewStartID; }
349 
350  /// Returns the limit for the old IDs source range.
351  UN_DataID oldEndOffset() const
352  { return myOldEndID; }
353 
354  /// Returns the number of IDs reserved by this merge map.
355  UN_DataSize size() const
356  { return UN_DataSize( myOldEndID.exintValue() ); }
357 
358  /// Return @c true if the mergemap was constructed with a valid
359  /// @c newStartOffset().
360  /// Default-constructed instances will return @c false.
361  explicit operator bool() const
362  { return myNewStartID.isValid(); }
363 
364  /// Returns the new ID corresponding to the @p old ID,
365  /// if the @p old ID is an ID contained within the source ID range;
366  /// otherwise, returns an invalid ID.
367  UN_DataID operator[]( UN_DataID old_id ) const
368  {
369  if( !old_id )
370  return UN_DataID(); // invalid ID
371  else if( old_id.exintValue() >= myOldEndID.exintValue() )
372  return UN_DataID(); // invalid old range
373  else if( myShouldCombineIDZero && old_id == UN_ID_ZERO )
374  return UN_ID_ZERO;
375  else
376  return UN_DataID( myNewStartID.exintValue() + old_id.exintValue()
377  - (myShouldCombineIDZero ? 1 : 0) );
378  }
379 
380  /// Returns the data ID that should be used for the data created next time.
381  UN_DataID nextDataID() const
382  {
383  return UN_DataID( myNewStartID.exintValue() + myOldEndID.exintValue()
384  - (myShouldCombineIDZero ? 1 : 0) );
385  }
386 
387 
388  /// Let O be some object in an ID set S.
389  /// If S is remapped multiple times at offsets A and B,
390  /// with I being its ID within A, then @c{remapIdFromOffsets(I, A, B)} will
391  /// return the ID of O within the remapping starting at B.
392  /// If these conditions are not met, an undefined ID is returned.
393  static UN_DataID remapIDFromOffsets( UN_DataID old_id,
394  UN_DataID old_offset, UN_DataID new_offset )
395  {
396  return UN_DataID( old_id.exintValue() - old_offset.exintValue()
397  + new_offset.exintValue() );
398  }
399 
400 private:
401  /// The base destination ID that shifts the old IDs to the new IDs.
402  UN_DataID myNewStartID;
403 
404  /// The flag to indicate whether the data for the ID zero is mapped
405  /// to a brand new data slot or is mapped to an existing ID of zero.
406  /// Some data containers use ID of zero for a special entry
407  /// that is treated differently than the other ones. Notably,
408  /// the node data container uses ID of zero for the root node, and
409  /// the root node from the src should not become a regular node in dest.
410  /// Instead, src root ID maps to dst root ID and their data is combined.
411  bool myShouldCombineIDZero = false;
412 
413  /// The range limit of the original IDs (for basic consistency checks).
414  UN_DataID myOldEndID;
415 };
416 
417 
418 /// Adaptor of the UN_DataIDRemap to specific data types.
419 template <typename ID>
420 class UN_DataIDRemapT : public UN_DataIDRemap
421 {
422 public:
423  /// Default constructor
424  UN_DataIDRemapT() = default;
425 
426  /// Convenience constructor that takes an instance of the base class.
427  UN_DataIDRemapT( const UN_DataIDRemap &remap_base )
428  : UN_DataIDRemap( remap_base )
429  {}
430 
431  /// Convenience constructor. See UN_DataIDRemap.
432  UN_DataIDRemapT( ID old_id_end, ID new_id_start,
433  bool combine_id_zero = false )
434  : UN_DataIDRemap( old_id_end, new_id_start, combine_id_zero )
435  {}
436 
437  /// Returns the new ID corresponding to the @p old ID,
438  /// if the @p old ID is an ID contained within the source ID range;
439  /// otherwise, returns an invalid ID.
440  ID operator[]( ID old_id ) const
441  { return ID(UN_DataIDRemap::operator[]( old_id )); }
442 
443  /// @see operator[]
444  ID at( ID old_id ) const
445  { return operator[]( old_id ); }
446 };
447 
448 
449 /// Information about data entries merged from another map.
450 /// Data buffers use this info to actually copy over the corresponding data.
452 {
453 public:
454  /// Constructor.
455  UN_DataMergeInfo( UN_DataIDRemap &&data_id_remap,
456  UT_Array<UN_DataIndexSpan> &&data_idx_spans )
457  : myDataIDRemap( std::move( data_id_remap ))
458  , myDataIndexSpans( std::move( data_idx_spans ))
459  {}
460 
461  /// Returns the continous index ranges that can be block-copied.
463  { return myDataIndexSpans; }
464 
465  /// Returns the data IDs remapping that occured during a merge.
466  /// Maps the old ID from the merge source to the new ID in destination.
467  const UN_DataIDRemap & dataIDRemap() const
468  { return myDataIDRemap; }
469 
470 
471 private:
472  /// A map between merged data's old IDs in the source
473  /// and the new IDs in the destination.
474  UN_DataIDRemap myDataIDRemap;
475 
476  /// Data buffers often use contiguous arrays. To optimize copying
477  /// data during a merge, they can use this info to bulk-copy entries.
478  UT_Array< UN_DataIndexSpan > myDataIndexSpans;
479 };
480 
481 
482 /// Package of remappings for various data ID types (nodes, ports, subnets).
484 {
485 public:
486  /// Constructors
487  UN_IDRemapInfo() = default;
489  UN_NodeID root_destination_node,
490  UN_NodeIDRemap &&node_id_remap,
491  UN_SubnetIDRemap &&subnet_id_remap,
492  UN_PortIDRemap &&port_id_remap,
493  UN_WireIDRemap &&wire_id_remap,
494  UN_StickyNoteIDRemap &&sticky_note_id_remap )
495  : myRootDstNode( root_destination_node )
496  , myNodeIDRemap( std::move(node_id_remap) )
497  , mySubnetIDRemap( std::move(subnet_id_remap) )
498  , myPortIDRemap( std::move(port_id_remap) )
499  , myWireIDRemap( std::move(wire_id_remap) )
500  , myStickyNoteIDRemap( std::move(sticky_note_id_remap) )
501  {}
502 
503  // An existing node in the destination graph to which the source root
504  // should map to. Ie, into which node to merge the other graph.
505  UN_NodeID rootDstNode() const { return myRootDstNode; }
506 
507  /// @{ Returns the object the remaps the various data IDs
508  /// from the src to dst after the graph merge.
509  const UN_NodeIDRemap & nodeIDRemap() const { return myNodeIDRemap; }
510  const UN_SubnetIDRemap& subnetIDRemap() const { return mySubnetIDRemap; }
511  const UN_PortIDRemap & portIDRemap() const { return myPortIDRemap; }
512  const UN_WireIDRemap & wireIDRemap() const { return myWireIDRemap; }
513  const UN_StickyNoteIDRemap &stickyNoteIDRemap() const
514  { return myStickyNoteIDRemap; }
515  /// @}
516 
517 private:
518  // TODO: FIXME: should the root be moved to UN_GraphMergeInfo?
519  // An existing node in the destination graph to which the source root
520  // should map to. Ie, into which node to merge the other graph.
521  UN_NodeID myRootDstNode;
522 
523  // Objects that remap data IDs from the src to the dst after the merge.
524  UN_NodeIDRemap myNodeIDRemap;
525  UN_SubnetIDRemap mySubnetIDRemap;
526  UN_PortIDRemap myPortIDRemap;
527  UN_WireIDRemap myWireIDRemap;
528  UN_StickyNoteIDRemap myStickyNoteIDRemap;
529 };
530 
531 /// Information about the result of a merge from another graph.
533 {
534 public:
535  /// Constructors
536  UN_GraphMergeInfo() = default;
538  : myIDRemapInfo( std::move( id_remap_info ))
539  {}
540 
541  /// Returns the object that contains mapping between data IDs after merge.
543  { return myIDRemapInfo; }
544 
545 private:
546  /// Contains mapping of IDs from source graph to IDs in destination graph.
547  UN_IDRemapInfo myIDRemapInfo;
548 };
549 
550 /// For debug printouts, etc:
551 #define UN_NUMBER_FORMATTER(IdOrIndexType) \
552 inline size_t \
553 UTformatBuffer(char *buffer, size_t buffer_size, const IdOrIndexType &v) \
554 { \
555  UT::Format::Writer w(buffer, buffer_size); \
556  UT::Format::Formatter f; \
557  return f.format(w, #IdOrIndexType "({})", {v.exintValue()}); \
558 } \
559 inline size_t \
560 UTformatBuffer(char *buffer, size_t buffer_size, \
561  const UT_Array<IdOrIndexType> &v) \
562 { \
563  UT::Format::Writer w(buffer, buffer_size); \
564  UT::Format::Formatter f; \
565  size_t bytesWritten = w("UT_Array<" #IdOrIndexType ">([", \
566  sizeof("UT_Array<" #IdOrIndexType ">([")-1); \
567  bool first = true; \
568  for (auto &&item : v) \
569  { \
570  bytesWritten += f.format(w, first ? "{}" : ", {}", \
571  {item.exintValue()}); \
572  first = false; \
573  } \
574  bytesWritten += w("])", 2); \
575  return bytesWritten; \
576 }
577 
578 
581 
582 UN_NUMBER_FORMATTER( UN_NodeIndex )
583 UN_NUMBER_FORMATTER( UN_ParmIndex )
584 UN_NUMBER_FORMATTER( UN_PortIndex )
585 UN_NUMBER_FORMATTER( UN_WireIndex )
586 UN_NUMBER_FORMATTER( UN_MetaDataIndex )
587 UN_NUMBER_FORMATTER( UN_SubnetIndex )
588 UN_NUMBER_FORMATTER( UN_StickyNoteIndex )
589 
590 
591 // Needed for data IDs and indices in UT_ArrayMap and UT_ArraySet classes.
592 namespace UT
593 {
594  template <typename T> struct DefaultClearer;
595 
596  template <>
598  {
599  static void clear( UN_DataIndex &v ) { v.clear(); }
600  static bool isClear( const UN_DataIndex &v ) { return !v.isValid(); }
601  static void clearConstruct( UN_DataIndex *p ) { clear(*p); }
602  static const bool clearNeedsDestruction = false;
603  };
604 
605 #define UN_INDEX_CLEARER(ID) \
606  template<> struct DefaultClearer<ID>: public DefaultClearer<UN_DataIndex>{};
607 
608  UN_INDEX_CLEARER( UN_NodeIndex )
609  UN_INDEX_CLEARER( UN_ParmIndex )
610  UN_INDEX_CLEARER( UN_PortIndex )
611  UN_INDEX_CLEARER( UN_WireIndex )
612  UN_INDEX_CLEARER( UN_SubnetIndex )
613  UN_INDEX_CLEARER( UN_StickyNoteIndex )
614 
615 } // end: namespace UT
616 
617 
618 /// Differentiates between input and output ports.
620 
621 /// Unknown or undefined port type name: an empty string.
622 static constexpr UT_StringLit UN_UNDEFINED_PORT_TYPE_NAME;
623 
624 
625 /// Unknown or undefined parameter type name: an empty string.
626 static constexpr UT_StringLit UN_UNDEFINED_PARM_TYPE_NAME;
627 
628 
629 /// Returns true if the given type name is invalid; false otherwise;
630 static inline bool UNisValid( const UT_StringRef &type_name )
631  { return type_name.isstring(); }
632 
633 /// Graph serialization to UT_Options.
634 /// Using UT_UniquePtr<UT_Options> to return values, to indicate the ownership.
635 /// Using UT_UniquePtr<UT_OPtions> rather than UT_OptionsHolder because
636 /// it is more flexible: it's easier to further edit options (editing
637 /// UT_OptionsHolder is cumbersome), and it's easy to create UT_OptionsHolder
638 /// from the UT_UniquePtr, if need be.
641 
642 /// Returns a non-null pointer to the UN_Options.
643 static inline UN_OptionsPtr
644 UNmakeOptions()
645 {
646  return UN_OptionsPtr(new UT_Options());
647 }
648 
649 
650 #endif
651 
constexpr exint exintValue() const
Returns an exint value of this number.
Definition: UN_Include.h:77
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:542
#define SYS_STATIC_ASSERT(expr)
UN_IDRemapInfo(UN_NodeID root_destination_node, UN_NodeIDRemap &&node_id_remap, UN_SubnetIDRemap &&subnet_id_remap, UN_PortIDRemap &&port_id_remap, UN_WireIDRemap &&wire_id_remap, UN_StickyNoteIDRemap &&sticky_note_id_remap)
Definition: UN_Include.h:488
static bool isClear(const UN_DataIndex &v)
Definition: UN_Include.h:600
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:335
*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:510
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:601
UN_NodeID rootDstNode() const
Definition: UN_Include.h:505
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:551
UNI_ID UN_DataID
Definition: UN_Include.h:254
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:432
Adaptor of the UN_DataIDRemap to specific data types.
Definition: UN_Include.h:258
**But if you need a result
Definition: thread.h:622
#define UN_INDEX_CLEARER(ID)
Definition: UN_Include.h:605
UN_DataID nextDataID() const
Returns the data ID that should be used for the data created next time.
Definition: UN_Include.h:381
static UN_DataID remapIDFromOffsets(UN_DataID old_id, UN_DataID old_offset, UN_DataID new_offset)
Definition: UN_Include.h:393
const UN_DataIDRemap & dataIDRemap() const
Definition: UN_Include.h:467
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
#define UN_DATA_INDEX(Class)
Definition: UN_Include.h:229
ID at(ID old_id) const
Definition: UN_Include.h:444
Package of remappings for various data ID types (nodes, ports, subnets).
Definition: UN_Include.h:483
GLintptr offset
Definition: glcorearb.h:665
ID operator[](ID old_id) const
Definition: UN_Include.h:440
#define UN_DATA_ID(SubClass, BaseClass)
Definition: UN_Include.h:267
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:462
const UN_WireIDRemap & wireIDRemap() const
Definition: UN_Include.h:512
UNI_PortKind
Specifies the port kind, ie, wheter it is an input or an output port.
Definition: UNI_Include.h:21
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:455
constexpr UN_DataNumber(ValueType value=INVALID_NUMBER)
Definition: UN_Include.h:53
static void clear(UN_DataIndex &v)
Definition: UN_Include.h:599
constexpr bool operator==(const UN_DataNumber &other) const
Comparison operators.
Definition: UN_Include.h:86
UN_DataID newStartOffset() const
Definition: UN_Include.h:347
UN_DataID oldEndOffset() const
Returns the limit for the old IDs source range.
Definition: UN_Include.h:351
UN_GraphMergeInfo(UN_IDRemapInfo &&id_remap_info)
Definition: UN_Include.h:537
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:87
const UN_NodeIDRemap & nodeIDRemap() const
Definition: UN_Include.h:509
const UN_PortIDRemap & portIDRemap() const
Definition: UN_Include.h:511
const UN_StickyNoteIDRemap & stickyNoteIDRemap() const
Definition: UN_Include.h:513
Information about the result of a merge from another graph.
Definition: UN_Include.h:532
static constexpr ValueType INVALID_NUMBER
Definition: UN_Include.h:48
constexpr bool isValid() const
Returns true if this ID is valid; false otherwise.
Definition: UNI_ID.h:41
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
constexpr exint exintValue() const
Returns an exint value of this ID.
Definition: UNI_ID.h:74
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:355
void setValue(ValueType value)
Sets the numerical value of this number.
Definition: UN_Include.h:64
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:367
UN_DataIDRemapT(const UN_DataIDRemap &remap_base)
Convenience constructor that takes an instance of the base class.
Definition: UN_Include.h:427
Definition: UNI_ID.h:25
UN_DataSize(exint value)
Definition: UN_Include.h:137
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:640
UN_DataSize size() const
Returns the number of indices in the range.
Definition: UN_Include.h:219