OpenVDB 7.0.0

NodeUnion.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
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 {
20 OPENVDB_USE_VERSION_NAMESPACE
21 namespace OPENVDB_VERSION_NAME {
22 namespace tree {
23
24 #if OPENVDB_ABI_VERSION_NUMBER >= 4
25
26 // Forward declaration of traits class
27 template<typename T> struct CopyTraits;
28
29 // Default implementation that stores the child pointer and the value separately
30 // (i.e., not in a union)
31 // This implementation is not used for POD, math::Vec or math::Coord value types.
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
50
51 // Template specialization for values of POD types (int, float, pointer, etc.)
52 template<typename ValueT, typename ChildT>
53 class NodeUnion<ValueT, ChildT, typename std::enable_if<std::is_pod<ValueT>::value>::type>
54 {
55 private:
56 union { ChildT* mChild; ValueT mValue; };
57
58 public:
59 NodeUnion(): mChild(nullptr) {}
60
61 ChildT* getChild() const { return mChild; }
62 void setChild(ChildT* child) { mChild = child; }
63
64 const ValueT& getValue() const { return mValue; }
65 ValueT& getValue() { return mValue; }
66 void setValue(const ValueT& val) { mValue = val; }
67 };
68
69
70 // Template specialization for values of types such as math::Vec3f and math::Coord
71 // for which CopyTraits<T>::IsCopyable is true
72 template<typename ValueT, typename ChildT>
73 class NodeUnion<ValueT, ChildT, typename std::enable_if<CopyTraits<ValueT>::IsCopyable>::type>
74 {
75 private:
76 union { ChildT* mChild; ValueT mValue; };
77
78 public:
79 NodeUnion(): mChild(nullptr) {}
80 NodeUnion(const NodeUnion& other): mChild(nullptr)
81 { std::memcpy(this, &other, sizeof(*this)); }
82 NodeUnion& operator=(const NodeUnion& rhs)
83 { std::memcpy(this, &rhs, sizeof(*this)); return *this; }
84
85 ChildT* getChild() const { return mChild; }
86 void setChild(ChildT* child) { mChild = child; }
87
88 const ValueT& getValue() const { return mValue; }
89 ValueT& getValue() { return mValue; }
90 void setValue(const ValueT& val) { mValue = val; }
91 };
92
93
100 template<typename T> struct CopyTraits { static const bool IsCopyable = false; };
101 template<typename T> struct CopyTraits<math::Vec2<T>> { static const bool IsCopyable = true; };
102 template<typename T> struct CopyTraits<math::Vec3<T>> { static const bool IsCopyable = true; };
103 template<typename T> struct CopyTraits<math::Vec4<T>> { static const bool IsCopyable = true; };
104 template<> struct CopyTraits<math::Coord> { static const bool IsCopyable = true; };
105
106
108
109
110 #else // OPENVDB_ABI_VERSION_NUMBER <= 3
111
112 // Prior to OpenVDB 4 and the introduction of C++11, values of non-POD types
113 // were heap-allocated and stored by pointer due to C++98 restrictions on unions.
114
115 // Internal implementation of a union of a child node pointer and a value
116 template<bool ValueIsClass, class ValueT, class ChildT> class NodeUnionImpl;
117
118
119 // Partial specialization for values of non-class types
120 // (int, float, pointer, etc.) that stores elements by value
121 template<typename ValueT, typename ChildT>
122 class NodeUnionImpl</*ValueIsClass=*/false, ValueT, ChildT>
123 {
124 private:
125 union { ChildT* child; ValueT value; } mUnion;
126
127 public:
128 NodeUnionImpl() { mUnion.child = nullptr; }
129
130 ChildT* getChild() const { return mUnion.child; }
131 void setChild(ChildT* child) { mUnion.child = child; }
132
133 const ValueT& getValue() const { return mUnion.value; }
134 ValueT& getValue() { return mUnion.value; }
135 void setValue(const ValueT& val) { mUnion.value = val; }
136 };
137
138
139 // Partial specialization for values of class types (std::string,
140 // math::Vec, etc.) that stores elements by pointer
141 template<typename ValueT, typename ChildT>
142 class NodeUnionImpl</*ValueIsClass=*/true, ValueT, ChildT>
143 {
144 private:
145 union { ChildT* child; ValueT* value; } mUnion;
146 bool mHasChild;
147
148 public:
149 NodeUnionImpl() : mHasChild(true) { this->setChild(nullptr); }
150 NodeUnionImpl(const NodeUnionImpl& other) : mHasChild(true)
151 {
152 if (other.mHasChild) {
153 this->setChild(other.getChild());
154 } else {
155 this->setValue(other.getValue());
156 }
157 }
158 NodeUnionImpl& operator=(const NodeUnionImpl& other)
159 {
160 if (other.mHasChild) {
161 this->setChild(other.getChild());
162 } else {
163 this->setValue(other.getValue());
164 }
165 return *this;
166 }
167 ~NodeUnionImpl() { this->setChild(nullptr); }
168
169 ChildT* getChild() const { return mHasChild ? mUnion.child : nullptr; }
170 void setChild(ChildT* child)
171 {
172 if (!mHasChild) delete mUnion.value;
173 mUnion.child = child;
174 mHasChild = true;
175 }
176
177 const ValueT& getValue() const { return *mUnion.value; }
178 ValueT& getValue() { return *mUnion.value; }
179 void setValue(const ValueT& val)
180 {
181 if (!mHasChild) delete mUnion.value;
182 mUnion.value = new ValueT(val);
183 mHasChild = false;
184 }
185 };
186
187
188 template<typename ValueT, typename ChildT>
189 struct NodeUnion: public NodeUnionImpl<std::is_class<ValueT>::value, ValueT, ChildT>
190 {
191 NodeUnion() {}
192 };
193
194 #endif
195
196 } // namespace tree
197 } // namespace OPENVDB_VERSION_NAME
198 } // namespace openvdb
199
200 #endif // OPENVDB_TREE_NODEUNION_HAS_BEEN_INCLUDED
openvdb::v7_0::tree::NodeUnion
Definition: NodeUnion.h:33
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::setValue
void setValue(const ValueT &val)
Definition: NodeUnion.h:66
openvdb::v7_0::math::Vec2
Definition: Vec2.h:23
Types.h
openvdb::v7_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
openvdb::v7_0::tree::NodeUnion::NodeUnion
NodeUnion()
Definition: NodeUnion.h:40
openvdb::v7_0::tree::NodeUnion::setValue
void setValue(const ValueT &val)
Definition: NodeUnion.h:47
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::setValue
void setValue(const ValueT &val)
Definition: NodeUnion.h:90
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::NodeUnion
NodeUnion()
Definition: NodeUnion.h:79
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::operator=
NodeUnion & operator=(const NodeUnion &rhs)
Definition: NodeUnion.h:82
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::getValue
const ValueT & getValue() const
Definition: NodeUnion.h:64
version.h
Library and file format version numbers.
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::getValue
const ValueT & getValue() const
Definition: NodeUnion.h:88
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::setChild
void setChild(ChildT *child)
Definition: NodeUnion.h:86
openvdb::v7_0::math::Vec4
Definition: Mat4.h:24
openvdb::v7_0::tree::NodeUnion::setChild
void setChild(ChildT *child)
Definition: NodeUnion.h:43
openvdb::v7_0::tree::NodeUnion::getValue
ValueT & getValue()
Definition: NodeUnion.h:46
openvdb::v7_0::tree::NodeUnion::getValue
const ValueT & getValue() const
Definition: NodeUnion.h:45
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::getChild
ChildT * getChild() const
Definition: NodeUnion.h:85
openvdb::v7_0::tree::NodeUnion::getChild
ChildT * getChild() const
Definition: NodeUnion.h:42
openvdb::v7_0::math::Vec3
Definition: Mat.h:170
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::mValue
ValueT mValue
Definition: NodeUnion.h:76
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::NodeUnion
NodeUnion(const NodeUnion &other)
Definition: NodeUnion.h:80
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::mValue
ValueT mValue
Definition: NodeUnion.h:56
openvdb::v7_0::tree::CopyTraits
Definition: NodeUnion.h:27
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::NodeUnion
NodeUnion()
Definition: NodeUnion.h:59
std
Definition: Coord.h:587
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::setChild
void setChild(ChildT *child)
Definition: NodeUnion.h:62
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
openvdb
Definition: Exceptions.h:13
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::getChild
ChildT * getChild() const
Definition: NodeUnion.h:61
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< std::is_pod< ValueT >::value >::type >::getValue
ValueT & getValue()
Definition: NodeUnion.h:65
openvdb::v7_0::tree::NodeUnion< ValueT, ChildT, typename std::enable_if< CopyTraits< ValueT >::IsCopyable >::type >::getValue
ValueT & getValue()
Definition: NodeUnion.h:89