HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MetaMap.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 #ifndef OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
32 #define OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
33 
34 #include "Metadata.h"
35 #include "Types.h"
36 #include "Exceptions.h"
37 #include <iosfwd>
38 #include <map>
39 
40 
41 namespace openvdb {
43 namespace OPENVDB_VERSION_NAME {
44 
45 /// Container that maps names (strings) to values of arbitrary types
47 {
48 public:
51 
52  using MetadataMap = std::map<Name, Metadata::Ptr>;
53  using MetaIterator = MetadataMap::iterator;
54  using ConstMetaIterator = MetadataMap::const_iterator;
55  ///< @todo this should really iterate over a map of Metadata::ConstPtrs
56 
57  MetaMap() {}
58  MetaMap(const MetaMap& other);
59  virtual ~MetaMap() {}
60 
61  /// Return a copy of this map whose fields are shared with this map.
62  MetaMap::Ptr copyMeta() const;
63  /// Return a deep copy of this map that shares no data with this map.
64  MetaMap::Ptr deepCopyMeta() const;
65 
66  /// Assign a deep copy of another map to this map.
67  MetaMap& operator=(const MetaMap&);
68 
69  /// Unserialize metadata from the given stream.
70  void readMeta(std::istream&);
71  /// Serialize metadata to the given stream.
72  void writeMeta(std::ostream&) const;
73 
74  /// @brief Insert a new metadata field or overwrite the value of an existing field.
75  /// @details If a field with the given name doesn't already exist, add a new field.
76  /// Otherwise, if the new value's type is the same as the existing field's value type,
77  /// overwrite the existing value with new value.
78  /// @throw TypeError if a field with the given name already exists, but its value type
79  /// is not the same as the new value's
80  /// @throw ValueError if the given field name is empty.
81  void insertMeta(const Name&, const Metadata& value);
82  /// @brief Deep copy all of the metadata fields from the given map into this map.
83  /// @throw TypeError if any field in the given map has the same name as
84  /// but a different value type than one of this map's fields.
85  void insertMeta(const MetaMap&);
86 
87  /// Remove the given metadata field if it exists.
88  void removeMeta(const Name&);
89 
90  //@{
91  /// @brief Return a pointer to the metadata with the given name.
92  /// If no such field exists, return a null pointer.
93  Metadata::Ptr operator[](const Name&);
94  Metadata::ConstPtr operator[](const Name&) const;
95  //@}
96 
97  //@{
98  /// @brief Return a pointer to a TypedMetadata object of type @c T and with the given name.
99  /// If no such field exists or if there is a type mismatch, return a null pointer.
100  template<typename T> typename T::Ptr getMetadata(const Name&);
101  template<typename T> typename T::ConstPtr getMetadata(const Name&) const;
102  //@}
103 
104  /// @brief Return a reference to the value of type @c T stored in the given metadata field.
105  /// @throw LookupError if no field with the given name exists.
106  /// @throw TypeError if the given field is not of type @c T.
107  template<typename T> T& metaValue(const Name&);
108  template<typename T> const T& metaValue(const Name&) const;
109 
110  // Functions for iterating over the metadata
111  MetaIterator beginMeta() { return mMeta.begin(); }
112  MetaIterator endMeta() { return mMeta.end(); }
113  ConstMetaIterator beginMeta() const { return mMeta.begin(); }
114  ConstMetaIterator endMeta() const { return mMeta.end(); }
115 
116  void clearMetadata() { mMeta.clear(); }
117 
118  size_t metaCount() const { return mMeta.size(); }
119 
120  /// Return a string describing this metadata map. Prefix each line with @a indent.
121  std::string str(const std::string& indent = "") const;
122 
123  /// Return @c true if the given map is equivalent to this map.
124  bool operator==(const MetaMap& other) const;
125  /// Return @c true if the given map is different from this map.
126  bool operator!=(const MetaMap& other) const { return !(*this == other); }
127 
128 private:
129  /// @brief Return a pointer to TypedMetadata with the given template parameter.
130  /// @throw LookupError if no field with the given name is found.
131  /// @throw TypeError if the given field is not of type T.
132  template<typename T>
133  typename TypedMetadata<T>::Ptr getValidTypedMetadata(const Name&) const;
134 
135  MetadataMap mMeta;
136 };
137 
138 /// Write a MetaMap to an output stream
139 std::ostream& operator<<(std::ostream&, const MetaMap&);
140 
141 
142 ////////////////////////////////////////
143 
144 
145 inline Metadata::Ptr
147 {
148  MetaIterator iter = mMeta.find(name);
149  return (iter == mMeta.end() ? Metadata::Ptr() : iter->second);
150 }
151 
152 inline Metadata::ConstPtr
154 {
155  ConstMetaIterator iter = mMeta.find(name);
156  return (iter == mMeta.end() ? Metadata::Ptr() : iter->second);
157 }
158 
159 
160 ////////////////////////////////////////
161 
162 
163 template<typename T>
164 inline typename T::Ptr
166 {
167  ConstMetaIterator iter = mMeta.find(name);
168  if (iter == mMeta.end()) return typename T::Ptr{};
169 
170  // To ensure that we get valid conversion if the metadata pointers cross dso
171  // boundaries, we have to check the qualified typename and then do a static
172  // cast. This is slower than doing a dynamic_pointer_cast, but is safer when
173  // pointers cross dso boundaries.
174  if (iter->second->typeName() == T::staticTypeName()) {
175  return StaticPtrCast<T, Metadata>(iter->second);
176  } // else
177  return typename T::Ptr{};
178 }
179 
180 template<typename T>
181 inline typename T::ConstPtr
183 {
184  ConstMetaIterator iter = mMeta.find(name);
185  if (iter == mMeta.end()) return typename T::ConstPtr{};
186 
187  // To ensure that we get valid conversion if the metadata pointers cross dso
188  // boundaries, we have to check the qualified typename and then do a static
189  // cast. This is slower than doing a dynamic_pointer_cast, but is safer when
190  // pointers cross dso boundaries.
191  if (iter->second->typeName() == T::staticTypeName()) {
192  return StaticPtrCast<const T, const Metadata>(iter->second);
193  } // else
194  return typename T::ConstPtr{};
195 }
196 
197 
198 ////////////////////////////////////////
199 
200 
201 template<typename T>
202 inline typename TypedMetadata<T>::Ptr
203 MetaMap::getValidTypedMetadata(const Name &name) const
204 {
205  ConstMetaIterator iter = mMeta.find(name);
206  if (iter == mMeta.end()) OPENVDB_THROW(LookupError, "Cannot find metadata " << name);
207 
208  // To ensure that we get valid conversion if the metadata pointers cross dso
209  // boundaries, we have to check the qualified typename and then do a static
210  // cast. This is slower than doing a dynamic_pointer_cast, but is safer when
211  // pointers cross dso boundaries.
212  typename TypedMetadata<T>::Ptr m;
213  if (iter->second->typeName() == TypedMetadata<T>::staticTypeName()) {
214  m = StaticPtrCast<TypedMetadata<T>, Metadata>(iter->second);
215  }
216  if (!m) OPENVDB_THROW(TypeError, "Invalid type for metadata " << name);
217  return m;
218 }
219 
220 
221 ////////////////////////////////////////
222 
223 
224 template<typename T>
225 inline T&
227 {
228  typename TypedMetadata<T>::Ptr m = getValidTypedMetadata<T>(name);
229  return m->value();
230 }
231 
232 
233 template<typename T>
234 inline const T&
235 MetaMap::metaValue(const Name &name) const
236 {
237  typename TypedMetadata<T>::Ptr m = getValidTypedMetadata<T>(name);
238  return m->value();
239 }
240 
241 } // namespace OPENVDB_VERSION_NAME
242 } // namespace openvdb
243 
244 #endif // OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
245 
246 // Copyright (c) 2012-2018 DreamWorks Animation LLC
247 // All rights reserved. This software is distributed under the
248 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
T & metaValue(const Name &)
Return a reference to the value of type T stored in the given metadata field.
Definition: MetaMap.h:226
Definition: ImfName.h:53
std::ostream & operator<<(std::ostream &ostr, const Metadata &metadata)
Write a Metadata to an output stream.
Definition: Metadata.h:401
ConstMetaIterator endMeta() const
Definition: MetaMap.h:114
T & value()
Return this metadata's value.
Definition: Metadata.h:299
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
Metadata::Ptr operator[](const Name &)
Return a pointer to the metadata with the given name. If no such field exists, return a null pointer...
Definition: MetaMap.h:146
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:189
SharedPtr< const Metadata > ConstPtr
Definition: Metadata.h:54
Container that maps names (strings) to values of arbitrary types.
Definition: MetaMap.h:46
std::shared_ptr< T > SharedPtr
Definition: Types.h:139
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
MetadataMap::iterator MetaIterator
Definition: MetaMap.h:53
GLuint const GLchar * name
Definition: glcorearb.h:785
ConstMetaIterator beginMeta() const
Definition: MetaMap.h:113
SharedPtr< const MetaMap > ConstPtr
Definition: MetaMap.h:50
bool operator!=(const MetaMap &other) const
Return true if the given map is different from this map.
Definition: MetaMap.h:126
GLsizei const GLfloat * value
Definition: glcorearb.h:823
MetadataMap::const_iterator ConstMetaIterator
Definition: MetaMap.h:55
Base class for storing metadata information in a grid.
Definition: Metadata.h:50
SharedPtr< TypedMetadata< T >> Ptr
Definition: Metadata.h:174
std::map< Name, Metadata::Ptr > MetadataMap
Definition: MetaMap.h:52
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:135
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
T::Ptr getMetadata(const Name &)
Return a pointer to a TypedMetadata object of type T and with the given name. If no such field exists...
Definition: MetaMap.h:165