HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_PackedArrayOfArrays.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: UT_PackedArrayOfArrays.h (UT Library, C++)
7  *
8  * COMMENTS: An array of arrays that is more efficiently
9  * laid out than the UT_Array<UT_Array<T> >
10  * Only allows appending, however.
11  */
12 
13 #pragma once
14 
15 #ifndef __UT_PACKED_ARRAY_OF_ARRAYS_H__
16 #define __UT_PACKED_ARRAY_OF_ARRAYS_H__
17 
18 #include "UT_API.h"
19 
20 #include "UT_Array.h"
21 #include "UT_Span.h"
22 #include "UT_IteratorRange.h"
23 
24 template <typename T>
26 {
27 public:
29 
31  {
32  }
33 
34  void clear()
35  { myOffsets.clear(); myData.clear(); }
36  bool isEmpty() const
37  { return size() == 0; }
38 
39  /// Returns the number of arrays in this structure.
40  exint size() const { return SYSmax(myOffsets.size() - 1, 0); }
41  exint entries() const { return size(); }
42 
43  int64 getMemoryUsage(bool inclusive = false) const
44  {
45  return (inclusive ? sizeof(*this) : 0) +
46  myOffsets.getMemoryUsage(false) +
47  myData.getMemoryUsage(false);
48  }
49 
50  /// Adds a new array to the end of our list of arrays.
51  void append(const UT_Array<T> &arr)
52  { append(arr.array(), arr.entries()); }
53  void append(const T *data, exint len)
54  {
55  if (myOffsets.isEmpty())
56  myOffsets.append(0);
57  for (exint i = 0; i < len; i++)
58  myData.append(data[i]);
59  myOffsets.append(myData.entries());
60  }
61  void append(const UT_PackedArrayOfArrays<T> &arr, exint idx)
62  { append(arr.arrayData(idx), arr.arrayLen(idx)); }
63 
64  /// Appends an array of arrays to our list.
66  {
67  for (exint i = 0; i < arr.entries(); i++)
68  append(arr, i);
69  }
70 
71  /// Moves an array of arrays to our list.
73  {
74  // If the array is empty just steal the other array.
75  if (isEmpty())
76  {
77  *this = std::move(arr);
78  return;
79  }
80 
81  // Otherwise we can do a move concat for the data, but the
82  // offsets need to be shifted.
83  myData.concat(std::move(arr.myData));
84 
85  myOffsets.bumpCapacity(myOffsets.size() + arr.size());
86  for (exint i = 0, n = arr.size(); i < n; ++i)
87  myOffsets.append(myOffsets.last() + arr.arrayLen(i));
88 
89  arr.myOffsets.clear();
90  }
91 
92  /// Appends a new array and returns a pointer to the resulting
93  /// data so it can be filled in.
95  {
96  if (myOffsets.isEmpty())
97  myOffsets.append(0);
98  exint base = myOffsets.last();
99  myOffsets.append(base+len);
100  myData.bumpSize(base+len);
101  return myData.array() + base;
102  }
103 
104  /// From the given idxth array, return the idx_in_array element
105  const T &operator()(exint idx, exint idx_in_array) const
106  {
107  UT_ASSERT_P(idx >= 0 && idx < size());
108  exint base = myOffsets(idx);
109  UT_ASSERT_P(base+idx_in_array < myOffsets(idx+1));
110  return myData(base+idx_in_array);
111  }
112 
113  /// Extracts an array into a UT_Array.
114  void extract(UT_Array<T> &result, exint idx) const
115  {
116  UT_ASSERT_P(idx >= 0 && idx < size());
117  exint base = myOffsets(idx);
118  exint len = myOffsets(idx+1)-base;
119  result.entries(len);
120  for (exint i = 0; i < len; i++)
121  result(i) = myData(base+i);
122  }
123 
125  {
126  // This is less than equal to as it is valid to
127  // point to the final element if the corresponding
128  // array is empty!
129  UT_ASSERT_P(myOffsets(idx) <= myData.size());
130  return myData.array() + myOffsets(idx);
131  }
132  const T *arrayData(exint idx) const
133  {
134  UT_ASSERT_P(myOffsets(idx) <= myData.size());
135  return myData.array() + myOffsets(idx);
136  }
137  exint arrayLen(exint idx) const
138  {
139  return myOffsets(idx+1)-myOffsets(idx);
140  }
142  {
143  return UT_Span<const T>(arrayData(idx), arrayLen(idx));
144  }
145 
146  /// @{
147  /// Returns an iterator range for the specified array.
149  { return UTmakeRange(arrayData(idx), arrayData(idx + 1)); }
151  { return UTmakeRange(arrayData(idx), arrayData(idx + 1)); }
152  /// @}
153 
154  /// Decreases, but never expands, to the given maxsize.
155  void truncate(exint maxsize)
156  {
157  if (maxsize >= 0 && size() > maxsize)
158  {
159  if (maxsize == 0)
160  clear();
161  else
162  {
163  myOffsets.setSize(maxsize+1);
164  myData.setSize(myOffsets(maxsize));
165  }
166  }
167  }
168 
169  /// These adjust the capacity without adjusting the entries
170  /// and are useful for pre-allocing the amount when known
171  /// in advance.
172  void setDataCapacity(exint capacity)
173  { myData.setCapacity(capacity); }
175  { myData.setCapacityIfNeeded(capacity); }
176  void setArrayCapacity(exint capacity)
177  { myOffsets.setCapacity(capacity); }
179  { myOffsets.setCapacityIfNeeded(capacity); }
180 
181  /// The raw offset table stores the end of each array
182  /// in the data array.
183  /// Each array has [rawOffsets(idx) ... rawOffsets(idx+1))
184  UT_Array<exint> &rawOffsets() { return myOffsets; }
185  const UT_Array<exint> &rawOffsets() const { return myOffsets; }
186 
187  /// All of the array data is in one contiguous block.
188  UT_Array<T> &rawData() { return myData; }
189  const UT_Array<T> &rawData() const { return myData; }
190 
191 private:
192  UT_Array<exint> myOffsets;
193  UT_Array<T> myData;
194 };
195 
196 #endif
197 
#define SYSmax(a, b)
Definition: SYS_Math.h:1570
void setDataCapacity(exint capacity)
const T & operator()(exint idx, exint idx_in_array) const
From the given idxth array, return the idx_in_array element.
void truncate(exint maxsize)
Decreases, but never expands, to the given maxsize.
UT_Array< exint > & rawOffsets()
UT_IteratorRange< IterT > UTmakeRange(IterT &&b, IterT &&e)
int64 exint
Definition: SYS_Types.h:125
const UT_Array< T > & rawData() const
T * array()
Definition: UT_Array.h:839
**But if you need a result
Definition: thread.h:613
UT_IteratorRange< const T * > arrayRange(exint idx) const
void append(const UT_PackedArrayOfArrays< T > &arr, exint idx)
void append(const T *data, exint len)
void setArrayCapacity(exint capacity)
const UT_Array< exint > & rawOffsets() const
GLdouble n
Definition: glcorearb.h:2008
const T * arrayData(exint idx) const
void concat(const UT_PackedArrayOfArrays< T > &arr)
Appends an array of arrays to our list.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
UT_Array< T > & rawData()
All of the array data is in one contiguous block.
void setArrayCapacityIfNeeded(exint capacity)
long long int64
Definition: SYS_Types.h:116
UT_Span< const T > span(exint idx) const
void concat(UT_PackedArrayOfArrays< T > &&arr)
Moves an array of arrays to our list.
void extract(UT_Array< T > &result, exint idx) const
Extracts an array into a UT_Array.
exint size() const
Returns the number of arrays in this structure.
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:648
GLsizeiptr size
Definition: glcorearb.h:664
void setDataCapacityIfNeeded(exint capacity)
int64 getMemoryUsage(bool inclusive=false) const
#define UT_API_TMPL
Definition: UT_API.h:15
void append(const UT_Array< T > &arr)
Adds a new array to the end of our list of arrays.
exint arrayLen(exint idx) const
Definition: format.h:895
UT_IteratorRange< T * > arrayRange(exint idx)