Loading...
Searching...
No Matches
MetaMap.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
#ifndef OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
#define OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
#include "Metadata.h"
#include "Types.h"
#include "Exceptions.h"
#include <iosfwd>
#include <map>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
/// Container that maps names (strings) to values of arbitrary types
class OPENVDB_API MetaMap
{
public:
using Ptr = SharedPtr<MetaMap>;
using ConstPtr = SharedPtr<const MetaMap>;
using MetadataMap = std::map<Name, Metadata::Ptr>;
using MetaIterator = MetadataMap::iterator;
using ConstMetaIterator = MetadataMap::const_iterator;
///< @todo this should really iterate over a map of Metadata::ConstPtrs
MetaMap() {}
MetaMap(const MetaMap& other);
virtual ~MetaMap() {}
/// Return a copy of this map whose fields are shared with this map.
MetaMap::Ptr copyMeta() const;
/// Return a deep copy of this map that shares no data with this map.
MetaMap::Ptr deepCopyMeta() const;
/// Assign a deep copy of another map to this map.
MetaMap& operator=(const MetaMap&);
/// Unserialize metadata from the given stream.
void readMeta(std::istream&);
/// Serialize metadata to the given stream.
void writeMeta(std::ostream&) const;
/// @brief Insert a new metadata field or overwrite the value of an existing field.
/// @details If a field with the given name doesn't already exist, add a new field.
/// Otherwise, if the new value's type is the same as the existing field's value type,
/// overwrite the existing value with new value.
/// @throw TypeError if a field with the given name already exists, but its value type
/// is not the same as the new value's
/// @throw ValueError if the given field name is empty.
void insertMeta(const Name&, const Metadata& value);
/// @brief Deep copy all of the metadata fields from the given map into this map.
/// @throw TypeError if any field in the given map has the same name as
/// but a different value type than one of this map's fields.
void insertMeta(const MetaMap&);
/// Remove the given metadata field if it exists.
void removeMeta(const Name&);
//@{
/// @brief Return a pointer to the metadata with the given name.
/// If no such field exists, return a null pointer.
Metadata::Ptr operator[](const Name&);
Metadata::ConstPtr operator[](const Name&) const;
//@}
//@{
/// @brief Return a pointer to a TypedMetadata object of type @c T and with the given name.
/// If no such field exists or if there is a type mismatch, return a null pointer.
template<typename T> typename T::Ptr getMetadata(const Name&);
template<typename T> typename T::ConstPtr getMetadata(const Name&) const;
//@}
/// @brief Return a reference to the value of type @c T stored in the given metadata field.
/// @throw LookupError if no field with the given name exists.
/// @throw TypeError if the given field is not of type @c T.
template<typename T> T& metaValue(const Name&);
template<typename T> const T& metaValue(const Name&) const;
// Functions for iterating over the metadata
MetaIterator beginMeta() { return mMeta.begin(); }
MetaIterator endMeta() { return mMeta.end(); }
ConstMetaIterator beginMeta() const { return mMeta.begin(); }
ConstMetaIterator endMeta() const { return mMeta.end(); }
void clearMetadata() { mMeta.clear(); }
size_t metaCount() const { return mMeta.size(); }
/// Return a string describing this metadata map. Prefix each line with @a indent.
std::string str(const std::string& indent = "") const;
/// Return @c true if the given map is equivalent to this map.
bool operator==(const MetaMap& other) const;
/// Return @c true if the given map is different from this map.
bool operator!=(const MetaMap& other) const { return !(*this == other); }
private:
/// @brief Return a pointer to TypedMetadata with the given template parameter.
/// @throw LookupError if no field with the given name is found.
/// @throw TypeError if the given field is not of type T.
template<typename T>
typename TypedMetadata<T>::Ptr getValidTypedMetadata(const Name&) const;
MetadataMap mMeta;
};
/// Write a MetaMap to an output stream
std::ostream& operator<<(std::ostream&, const MetaMap&);
////////////////////////////////////////
inline Metadata::Ptr
MetaMap::operator[](const Name& name)
{
MetaIterator iter = mMeta.find(name);
return (iter == mMeta.end() ? Metadata::Ptr() : iter->second);
}
inline Metadata::ConstPtr
MetaMap::operator[](const Name &name) const
{
ConstMetaIterator iter = mMeta.find(name);
return (iter == mMeta.end() ? Metadata::Ptr() : iter->second);
}
////////////////////////////////////////
template<typename T>
inline typename T::Ptr
MetaMap::getMetadata(const Name &name)
{
ConstMetaIterator iter = mMeta.find(name);
if (iter == mMeta.end()) return typename T::Ptr{};
// To ensure that we get valid conversion if the metadata pointers cross dso
// boundaries, we have to check the qualified typename and then do a static
// cast. This is slower than doing a dynamic_pointer_cast, but is safer when
// pointers cross dso boundaries.
if (iter->second->typeName() == T::staticTypeName()) {
return StaticPtrCast<T, Metadata>(iter->second);
} // else
return typename T::Ptr{};
}
template<typename T>
inline typename T::ConstPtr
MetaMap::getMetadata(const Name &name) const
{
ConstMetaIterator iter = mMeta.find(name);
if (iter == mMeta.end()) return typename T::ConstPtr{};
// To ensure that we get valid conversion if the metadata pointers cross dso
// boundaries, we have to check the qualified typename and then do a static
// cast. This is slower than doing a dynamic_pointer_cast, but is safer when
// pointers cross dso boundaries.
if (iter->second->typeName() == T::staticTypeName()) {
return StaticPtrCast<const T, const Metadata>(iter->second);
} // else
return typename T::ConstPtr{};
}
////////////////////////////////////////
template<typename T>
inline typename TypedMetadata<T>::Ptr
MetaMap::getValidTypedMetadata(const Name &name) const
{
ConstMetaIterator iter = mMeta.find(name);
if (iter == mMeta.end()) OPENVDB_THROW(LookupError, "Cannot find metadata " << name);
// To ensure that we get valid conversion if the metadata pointers cross dso
// boundaries, we have to check the qualified typename and then do a static
// cast. This is slower than doing a dynamic_pointer_cast, but is safer when
// pointers cross dso boundaries.
typename TypedMetadata<T>::Ptr m;
if (iter->second->typeName() == TypedMetadata<T>::staticTypeName()) {
m = StaticPtrCast<TypedMetadata<T>, Metadata>(iter->second);
}
if (!m) OPENVDB_THROW(TypeError, "Invalid type for metadata " << name);
return m;
}
////////////////////////////////////////
template<typename T>
inline T&
MetaMap::metaValue(const Name &name)
{
typename TypedMetadata<T>::Ptr m = getValidTypedMetadata<T>(name);
return m->value();
}
template<typename T>
inline const T&
MetaMap::metaValue(const Name &name) const
{
typename TypedMetadata<T>::Ptr m = getValidTypedMetadata<T>(name);
return m->value();
}
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_METADATA_METAMAP_HAS_BEEN_INCLUDED
value
ValueT value
Definition GridBuilder.h:1290
Metadata.h
OPENVDB_API
#define OPENVDB_API
Definition Platform.h:251
openvdb::v10_0::LookupError
Definition Exceptions.h:60
openvdb::v10_0::MetaMap
Container that maps names (strings) to values of arbitrary types.
Definition MetaMap.h:20
openvdb::v10_0::MetaMap::str
std::string str(const std::string &indent="") const
Return a string describing this metadata map. Prefix each line with indent.
openvdb::v10_0::MetaMap::copyMeta
MetaMap::Ptr copyMeta() const
Return a copy of this map whose fields are shared with this map.
openvdb::v10_0::MetaMap::operator!=
bool operator!=(const MetaMap &other) const
Return true if the given map is different from this map.
Definition MetaMap.h:99
openvdb::v10_0::MetaMap::ConstPtr
SharedPtr< const MetaMap > ConstPtr
Definition MetaMap.h:23
openvdb::v10_0::MetaMap::deepCopyMeta
MetaMap::Ptr deepCopyMeta() const
Return a deep copy of this map that shares no data with this map.
openvdb::v10_0::MetaMap::getMetadata
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:138
openvdb::v10_0::MetaMap::operator[]
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:119
openvdb::v10_0::MetaMap::beginMeta
ConstMetaIterator beginMeta() const
Definition MetaMap.h:86
openvdb::v10_0::MetaMap::MetaIterator
MetadataMap::iterator MetaIterator
Definition MetaMap.h:26
openvdb::v10_0::MetaMap::getMetadata
T::ConstPtr getMetadata(const Name &) const
Definition MetaMap.h:155
openvdb::v10_0::MetaMap::MetadataMap
std::map< Name, Metadata::Ptr > MetadataMap
Definition MetaMap.h:25
openvdb::v10_0::MetaMap::metaValue
T & metaValue(const Name &)
Return a reference to the value of type T stored in the given metadata field.
Definition MetaMap.h:199
openvdb::v10_0::MetaMap::metaValue
const T & metaValue(const Name &) const
Definition MetaMap.h:208
openvdb::v10_0::MetaMap::readMeta
void readMeta(std::istream &)
Unserialize metadata from the given stream.
openvdb::v10_0::MetaMap::operator[]
Metadata::ConstPtr operator[](const Name &) const
Definition MetaMap.h:126
openvdb::v10_0::MetaMap::endMeta
ConstMetaIterator endMeta() const
Definition MetaMap.h:87
openvdb::v10_0::MetaMap::metaCount
size_t metaCount() const
Definition MetaMap.h:91
openvdb::v10_0::MetaMap::clearMetadata
void clearMetadata()
Definition MetaMap.h:89
openvdb::v10_0::MetaMap::MetaMap
MetaMap(const MetaMap &other)
openvdb::v10_0::MetaMap::beginMeta
MetaIterator beginMeta()
Definition MetaMap.h:84
openvdb::v10_0::MetaMap::ConstMetaIterator
MetadataMap::const_iterator ConstMetaIterator
Definition MetaMap.h:27
openvdb::v10_0::MetaMap::writeMeta
void writeMeta(std::ostream &) const
Serialize metadata to the given stream.
openvdb::v10_0::MetaMap::removeMeta
void removeMeta(const Name &)
Remove the given metadata field if it exists.
openvdb::v10_0::MetaMap::Ptr
SharedPtr< MetaMap > Ptr
Definition MetaMap.h:22
openvdb::v10_0::MetaMap::insertMeta
void insertMeta(const MetaMap &)
Deep copy all of the metadata fields from the given map into this map.
openvdb::v10_0::MetaMap::endMeta
MetaIterator endMeta()
Definition MetaMap.h:85
openvdb::v10_0::MetaMap::operator==
bool operator==(const MetaMap &other) const
Return true if the given map is equivalent to this map.
openvdb::v10_0::MetaMap::~MetaMap
virtual ~MetaMap()
Definition MetaMap.h:32
openvdb::v10_0::MetaMap::operator=
MetaMap & operator=(const MetaMap &)
Assign a deep copy of another map to this map.
openvdb::v10_0::MetaMap::MetaMap
MetaMap()
Definition MetaMap.h:30
openvdb::v10_0::MetaMap::insertMeta
void insertMeta(const Name &, const Metadata &value)
Insert a new metadata field or overwrite the value of an existing field.
openvdb::v10_0::Metadata
Base class for storing metadata information in a grid.
Definition Metadata.h:24
openvdb::v10_0::Metadata::ConstPtr
SharedPtr< const Metadata > ConstPtr
Definition Metadata.h:27
openvdb::v10_0::Metadata::Ptr
SharedPtr< Metadata > Ptr
Definition Metadata.h:26
openvdb::v10_0::TypeError
Definition Exceptions.h:64
openvdb::v10_0::TypedMetadata::Ptr
SharedPtr< TypedMetadata< T > > Ptr
Definition Metadata.h:124
openvdb::v10_0::TypedMetadata::value
T & value()
Return this metadata's value.
Definition Metadata.h:249
openvdb::v10_0::TypedMetadata::staticTypeName
static Name staticTypeName()
Definition Metadata.h:147
openvdb::v10_0::Name
std::string Name
Definition Name.h:17
openvdb::v10_0::operator<<
std::ostream & operator<<(std::ostream &ostr, const Metadata &metadata)
Write a Metadata to an output stream.
Definition Metadata.h:351
openvdb::v10_0::SharedPtr
std::shared_ptr< T > SharedPtr
Definition Types.h:114
openvdb::v10_0::StaticPtrCast
SharedPtr< T > StaticPtrCast(const SharedPtr< U > &ptr)
Return a new shared pointer that points to the same object as the given pointer after a static_cast.
Definition Types.h:146
openvdb
Definition Exceptions.h:13
Exceptions.h
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Types.h
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212