OpenVDB  9.0.1
NodeUnion.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file NodeUnion.h
5 ///
6 /// @details NodeUnion is a templated helper class that controls access to either
7 /// the child node pointer or the value for a particular element of a root
8 /// or internal node. For space efficiency, the child pointer and the value
9 /// are unioned when possible, since the two are never in use simultaneously.
10 
11 #ifndef OPENVDB_TREE_NODEUNION_HAS_BEEN_INCLUDED
12 #define OPENVDB_TREE_NODEUNION_HAS_BEEN_INCLUDED
13 
14 #include <openvdb/version.h>
15 #include <openvdb/Types.h>
16 #include <cstring> // for std::memcpy()
17 #include <type_traits>
18 
19 namespace openvdb {
21 namespace OPENVDB_VERSION_NAME {
22 namespace tree {
23 
24 #if OPENVDB_ABI_VERSION_NUMBER >= 8
25 
26 /// @brief Default implementation of a NodeUnion that stores the child pointer
27 /// and the value separately (i.e., not in a union). Types which select this
28 /// specialization usually do not conform to the requirements of a union
29 /// member, that is that the type ValueT is not trivially copyable. This
30 /// implementation is thus NOT used for POD, math::Vec, math::Mat, math::Quat
31 /// or math::Coord types, but is used (for example) with std::string
32 template<typename ValueT, typename ChildT, typename Enable = void>
33 class NodeUnion
34 {
35 private:
36  ChildT* mChild;
37  ValueT mValue;
38 
39 public:
40  NodeUnion(): mChild(nullptr), mValue() {}
41 
42  ChildT* getChild() const { return mChild; }
43  void setChild(ChildT* child) { mChild = child; }
44 
45  const ValueT& getValue() const { return mValue; }
46  ValueT& getValue() { return mValue; }
47  void setValue(const ValueT& val) { mValue = val; }
48 
49  // Small check to ensure this class isn't
50  // selected for some expected types
51  static_assert(!ValueTraits<ValueT>::IsVec &&
56  "Unexpected instantiation of NodeUnion");
57 };
58 
59 /// @brief Template specialization of a NodeUnion that stores the child pointer
60 /// and the value together (int, float, pointer, etc.)
61 template<typename ValueT, typename ChildT>
62 class NodeUnion<ValueT, ChildT,
63  typename std::enable_if<std::is_trivially_copyable<ValueT>::value>::type>
64 {
65 private:
66  union { ChildT* mChild; ValueT mValue; };
67 
68 public:
69  NodeUnion(): mChild(nullptr) {}
70 
71  ChildT* getChild() const { return mChild; }
72  void setChild(ChildT* child) { mChild = child; }
73 
74  const ValueT& getValue() const { return mValue; }
75  ValueT& getValue() { return mValue; }
76  void setValue(const ValueT& val) { mValue = val; }
77 };
78 
79 #else
80 
81 // Forward declaration of traits class
82 template<typename T> struct CopyTraits;
83 
84 // Default implementation that stores the child pointer and the value separately
85 // (i.e., not in a union)
86 // This implementation is not used for POD, math::Vec or math::Coord value types.
87 template<typename ValueT, typename ChildT, typename Enable = void>
88 class NodeUnion
89 {
90 private:
91  ChildT* mChild;
92  ValueT mValue;
93 
94 public:
95  NodeUnion(): mChild(nullptr), mValue() {}
96 
97  ChildT* getChild() const { return mChild; }
98  void setChild(ChildT* child) { mChild = child; }
99 
100  const ValueT& getValue() const { return mValue; }
101  ValueT& getValue() { return mValue; }
102  void setValue(const ValueT& val) { mValue = val; }
103 };
104 
105 
106 // Template specialization for values of POD types (int, float, pointer, etc.)
107 template<typename ValueT, typename ChildT>
108 class NodeUnion<ValueT, ChildT, typename std::enable_if<std::is_pod<ValueT>::value>::type>
109 {
110 private:
111  union { ChildT* mChild; ValueT mValue; };
112 
113 public:
114  NodeUnion(): mChild(nullptr) {}
115 
116  ChildT* getChild() const { return mChild; }
117  void setChild(ChildT* child) { mChild = child; }
118 
119  const ValueT& getValue() const { return mValue; }
120  ValueT& getValue() { return mValue; }
121  void setValue(const ValueT& val) { mValue = val; }
122 };
123 
124 
125 // Template specialization for values of types such as math::Vec3f and math::Coord
126 // for which CopyTraits<T>::IsCopyable is true
127 template<typename ValueT, typename ChildT>
128 class NodeUnion<ValueT, ChildT, typename std::enable_if<CopyTraits<ValueT>::IsCopyable>::type>
129 {
130 private:
131  union { ChildT* mChild; ValueT mValue; };
132 
133 public:
134  NodeUnion(): mChild(nullptr) {}
135  NodeUnion(const NodeUnion& other): mChild(nullptr)
136  { std::memcpy(static_cast<void*>(this), &other, sizeof(*this)); }
137  NodeUnion& operator=(const NodeUnion& rhs)
138  { std::memcpy(static_cast<void*>(this), &rhs, sizeof(*this)); return *this; }
139 
140  ChildT* getChild() const { return mChild; }
141  void setChild(ChildT* child) { mChild = child; }
142 
143  const ValueT& getValue() const { return mValue; }
144  ValueT& getValue() { return mValue; }
145  void setValue(const ValueT& val) { mValue = val; }
146 };
147 
148 
149 /// @details A type T is copyable if
150 /// # T stores member values by value (vs. by pointer or reference)
151 /// and T's true byte size is given by sizeof(T).
152 /// # T has a trivial destructor
153 /// # T has a default constructor
154 /// # T has an assignment operator
155 template<typename T> struct CopyTraits { static const bool IsCopyable = false; };
156 template<typename T> struct CopyTraits<math::Vec2<T>> { static const bool IsCopyable = true; };
157 template<typename T> struct CopyTraits<math::Vec3<T>> { static const bool IsCopyable = true; };
158 template<typename T> struct CopyTraits<math::Vec4<T>> { static const bool IsCopyable = true; };
159 template<> struct CopyTraits<math::Coord> { static const bool IsCopyable = true; };
160 
161 #endif
162 
163 ////////////////////////////////////////
164 
165 
166 } // namespace tree
167 } // namespace OPENVDB_VERSION_NAME
168 } // namespace openvdb
169 
170 #endif // OPENVDB_TREE_NODEUNION_HAS_BEEN_INCLUDED
ChildT * child
Definition: GridBuilder.h:1286
Definition: Types.h:255
ValueT & getValue()
Definition: NodeUnion.h:46
Definition: Coord.h:586
ChildT * getChild() const
Definition: NodeUnion.h:42
void setChild(ChildT *child)
Definition: NodeUnion.h:43
Definition: Exceptions.h:13
ValueT value
Definition: GridBuilder.h:1287
const ValueT & getValue() const
Definition: NodeUnion.h:45
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
NodeUnion()
Definition: NodeUnion.h:40
Default implementation of a NodeUnion that stores the child pointer and the value separately (i...
Definition: NodeUnion.h:33
void setValue(const ValueT &val)
Definition: NodeUnion.h:47
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202