HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_SmallArray.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_SmallArray.h (UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #pragma once
12 
13 #ifndef __UT_SMALLARRAY_H_INCLUDED__
14 #define __UT_SMALLARRAY_H_INCLUDED__
15 
16 #include "UT_API.h"
17 #include "UT_Array.h"
18 #include "UT_Assert.h"
19 #include <SYS/SYS_Compiler.h>
20 #include <SYS/SYS_StaticAssert.h>
21 #include <utility>
22 #include <stddef.h>
23 
24 /// An array class with the small buffer optimization, making it ideal for
25 /// cases when you know it will only contain a few elements at the expense of
26 /// increasing the object size by MAX_BYTES (subject to alignment).
27 template <typename T, size_t MAX_BYTES = 64>
29 {
30  // As many elements that fit into MAX_BYTES with 1 item minimum
31  enum { MAX_ELEMS = MAX_BYTES/sizeof(T) < 1 ? 1 : MAX_BYTES/sizeof(T) };
32 
33 public:
34 
35 // gcc falsely warns about our use of offsetof() on non-POD types. We can't
36 // easily suppress this because it has to be done in the caller at
37 // instantiation time. Instead, punt to a runtime check instead.
38 #if defined(__clang__)
39  #define UT_SMALL_ARRAY_SIZE_ASSERT() \
40  using ThisT = UT_SmallArray<T,MAX_BYTES>; \
41  SYS_STATIC_ASSERT( \
42  __builtin_offsetof(ThisT, myBuffer) == sizeof(UT_Array<T>))
43 #elif !SYS_IS_GCC_GE(4, 8) || defined(_MSC_VER)
44  #define UT_SMALL_ARRAY_SIZE_ASSERT() \
45  using ThisT = UT_SmallArray<T,MAX_BYTES>; \
46  SYS_STATIC_ASSERT(offsetof(ThisT, myBuffer) == sizeof(UT_Array<T>))
47 #else
48  #define UT_SMALL_ARRAY_SIZE_ASSERT() \
49  UT_ASSERT_P(!UT_Array<T>::isHeapBuffer());
50 #endif
51 
52  /// Default construction
54  : UT_Array<T>(/*capacity*/0)
55  {
56  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
58  }
59 
60  /// Copy constructor
61  /// @{
62  explicit UT_SmallArray(const UT_Array<T> &copy)
63  : UT_Array<T>(/*capacity*/0)
64  {
65  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
68  }
70  : UT_Array<T>(/*capacity*/0)
71  {
72  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
75  }
76  /// @}
77 
78  /// Move constructor
79  /// @{
81  {
82  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
84  UT_Array<T>::operator=(std::move(movable));
85  }
87  {
88  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
90  UT_Array<T>::operator=(std::move(movable));
91  }
92  /// @}
93 
94  /// Initializer list constructor
95  explicit UT_SmallArray(std::initializer_list<T> init)
96  {
97  UT_Array<T>::unsafeShareData((T*)myBuffer, 0, MAX_ELEMS);
100  }
101 
102 #undef UT_SMALL_ARRAY_SIZE_ASSERT
103 
104  /// Assignment operator
105  /// @{
108  {
110  return *this;
111  }
113  operator=(const UT_Array<T> &copy)
114  {
116  return *this;
117  }
118  /// @}
119 
120  /// Move operator
121  /// @{
124  {
125  UT_Array<T>::operator=(std::move(movable));
126  return *this;
127  }
130  {
131  UT_Array<T>::operator=(std::move(movable));
132  return *this;
133  }
134  /// @}
135 
137  operator=(std::initializer_list<T> src)
138  {
140  return *this;
141  }
142 private:
143  alignas(T) char myBuffer[MAX_ELEMS*sizeof(T)];
144 };
145 
146 // For UT::ArraySet.
147 namespace UT
148 {
149 template <typename T>
150 struct DefaultClearer;
151 
152 template <typename T, size_t BYTES>
154 {
156  {
157  // Just in case, destruct and reconstruct,
158  // instead of using setCapacity(0).
160  p->~UT_SmallArray<T, BYTES>();
161  new ((void *)p) UT_SmallArray<T, BYTES>();
162  }
163  static bool isClear(const UT_SmallArray<T, BYTES> &v)
164  {
165  return v.isEmpty();
166  }
168  {
169  new ((void *)p) UT_SmallArray<T, BYTES>();
170  }
171  static const bool clearNeedsDestruction = false;
172 };
173 } // namespace UT
174 
175 #endif // __UT_SMALLARRAY_H_INCLUDED__
UT_SmallArray< T, MAX_BYTES > & operator=(UT_Array< T > &&movable)
UT_SmallArray< T, MAX_BYTES > & operator=(const UT_Array< T > &copy)
#define UT_SMALL_ARRAY_SIZE_ASSERT()
Definition: UT_SmallArray.h:44
const GLdouble * v
Definition: glcorearb.h:836
UT_Array< T > & operator=(const UT_Array< T > &a)
Definition: UT_ArrayImpl.h:824
UT_SmallArray< T, MAX_BYTES > & operator=(UT_SmallArray< T, MAX_BYTES > &&movable)
UT_SmallArray(UT_Array< T > &&movable) SYS_NOEXCEPT
Definition: UT_SmallArray.h:80
UT_SmallArray(const UT_Array< T > &copy)
Definition: UT_SmallArray.h:62
static void clearConstruct(UT_SmallArray< T, BYTES > *p)
static void clear(UT_SmallArray< T, BYTES > &v)
void unsafeShareData(UT_Array< T > &src)
Definition: UT_Array.h:846
UT_SmallArray< T, MAX_BYTES > & operator=(const UT_SmallArray< T, MAX_BYTES > &copy)
UT_SmallArray(std::initializer_list< T > init)
Initializer list constructor.
Definition: UT_SmallArray.h:95
UT_SmallArray()
Default construction.
Definition: UT_SmallArray.h:53
#define SYS_NOEXCEPT
Definition: SYS_Compiler.h:55
#define UT_API_TMPL
Definition: UT_API.h:14
static bool isClear(const UT_SmallArray< T, BYTES > &v)
UT_SmallArray(const UT_SmallArray< T, MAX_BYTES > &copy)
Definition: UT_SmallArray.h:69
UT_SmallArray(UT_SmallArray< T, MAX_BYTES > &&movable) SYS_NOEXCEPT
Definition: UT_SmallArray.h:86
UT_SmallArray< T, MAX_BYTES > & operator=(std::initializer_list< T > src)
bool isEmpty() const
Returns true iff there are no occupied elements in the array.
Definition: UT_Array.h:455
GLenum src
Definition: glcorearb.h:1792