OpenVDB 9.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
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
19namespace openvdb {
21namespace OPENVDB_VERSION_NAME {
22namespace 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
32template<typename ValueT, typename ChildT, typename Enable = void>
34{
35private:
36 ChildT* mChild;
37 ValueT mValue;
38
39public:
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.)
61template<typename ValueT, typename ChildT>
62class NodeUnion<ValueT, ChildT,
63 typename std::enable_if<std::is_trivially_copyable<ValueT>::value>::type>
64{
65private:
66 union { ChildT* mChild; ValueT mValue; };
67
68public:
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
82template<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.
87template<typename ValueT, typename ChildT, typename Enable = void>
88class NodeUnion
89{
90private:
91 ChildT* mChild;
92 ValueT mValue;
93
94public:
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.)
107template<typename ValueT, typename ChildT>
108class NodeUnion<ValueT, ChildT, typename std::enable_if<std::is_pod<ValueT>::value>::type>
109{
110private:
111 union { ChildT* mChild; ValueT mValue; };
112
113public:
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
127template<typename ValueT, typename ChildT>
128class NodeUnion<ValueT, ChildT, typename std::enable_if<CopyTraits<ValueT>::IsCopyable>::type>
129{
130private:
131 union { ChildT* mChild; ValueT mValue; };
132
133public:
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
155template<typename T> struct CopyTraits { static const bool IsCopyable = false; };
156template<typename T> struct CopyTraits<math::Vec2<T>> { static const bool IsCopyable = true; };
157template<typename T> struct CopyTraits<math::Vec3<T>> { static const bool IsCopyable = true; };
158template<typename T> struct CopyTraits<math::Vec4<T>> { static const bool IsCopyable = true; };
159template<> 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
ValueT value
Definition: GridBuilder.h:1287
ChildT * child
Definition: GridBuilder.h:1286
Default implementation of a NodeUnion that stores the child pointer and the value separately (i....
Definition: NodeUnion.h:34
void setChild(ChildT *child)
Definition: NodeUnion.h:43
ValueT & getValue()
Definition: NodeUnion.h:46
const ValueT & getValue() const
Definition: NodeUnion.h:45
ChildT * getChild() const
Definition: NodeUnion.h:42
NodeUnion()
Definition: NodeUnion.h:40
void setValue(const ValueT &val)
Definition: NodeUnion.h:47
Definition: Exceptions.h:13
Definition: Coord.h:586
Definition: Types.h:256
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202