48#ifndef Sawyer_Attribute_H
49#define Sawyer_Attribute_H
51#include <boost/any.hpp>
52#include <boost/foreach.hpp>
53#include <boost/lexical_cast.hpp>
54#include <Sawyer/Exception.h>
55#include <Sawyer/Map.h>
56#include <Sawyer/Optional.h>
57#include <Sawyer/Sawyer.h>
58#include <Sawyer/Synchronization.h>
169SAWYER_EXPORT
Id id(
const std::string &name);
177SAWYER_EXPORT
const std::string& name(
Id);
188 : Exception::NotFound(attrName +
" does not exist in object") {}
198 : Exception::
AlreadyExists(attrName +
" is already a declared attribute (id=" +
199 boost::lexical_cast<std::string>(
id) +
")") {}
214template<
class SyncTag = SAWYER_THREAD_TAG>
222 mutable typename Sync::Mutex mutex_;
235 typename Sync::LockGuard lock(other.mutex_);
236 values_ = other.values_;
243 typename Sync::LockGuard2 lock(mutex_, other.mutex_);
244 values_ = other.values_;
254 typename Sync::LockGuard lock(mutex_);
255 return values_.
exists(
id);
265 typename Sync::LockGuard lock(mutex_);
273 typename Sync::LockGuard lock(mutex_);
286 typename Sync::LockGuard lock(mutex_);
287 values_.
insert(
id, boost::any(value));
299 typename Sync::LockGuard lock(mutex_);
300 if (!values_.
exists(
id)) {
301 values_.
insert(
id, boost::any(value));
316 typename Sync::LockGuard lock(mutex_);
317 AttrMap::ConstNodeIterator found = values_.
find(
id);
318 if (found == values_.
nodes().end()) {
321 throw DoesNotExist(
"attribute id " + boost::lexical_cast<std::string>(
id) +
" [not declared]");
339 typename Sync::LockGuard lock(mutex_);
353 typename Sync::LockGuard lock(mutex_);
354 AttrMap::ConstNodeIterator found = values_.
find(
id);
355 if (found == values_.
nodes().end())
357 return boost::any_cast<T>(found->value());
367 typename Sync::LockGuard lock(mutex_);
368 AttrMap::ConstNodeIterator found = values_.
find(
id);
369 if (found == values_.
nodes().end())
371 return boost::any_cast<T>(found->value());
378 typename Sync::LockGuard lock(mutex_);
379 return values_.
size();
386 typename Sync::LockGuard lock(mutex_);
387 std::vector<Id> retval;
388 retval.reserve(values_.
size());
389 BOOST_FOREACH (
Id id, values_.
keys())
390 retval.push_back(
id);
Exception thrown when redeclaring an existing attribute.
AlreadyExists(const std::string &attrName, Id id)
Constructor taking an attribute name or description.
Exception for non-existing values.
DoesNotExist(const std::string &attrName)
Constructor taking an attribute name or description.
API and storage for attributes.
std::vector< Id > attributeIds() const
Returns ID numbers for all IDs stored in this container.
bool setAttributeMaybe(Id id, const T &value)
Store an attribute if not already present.
Sawyer::Optional< T > optionalAttribute(Id id) const
Return the attribute as an optional value.
size_t nAttributes() const
Number of attributes stored.
void eraseAttribute(Id id)
Erase an attribute.
T attributeOrDefault(Id id) const
Return an attribute or a default-constructed value.
T attributeOrElse(Id id, const T &dflt) const
Return an attribute or a specified value.
void setAttribute(Id id, const T &value)
Store an attribute.
Storage(const Storage &other)
Copy constructor.
void clearAttributes()
Erase all attributes.
bool attributeExists(Id id) const
Check attribute existence.
Storage & operator=(const Storage &other)
Assignment operator.
Storage()
Default constructor.
T getAttribute(Id id) const
Get an attribute that is known to exist.
Container associating values with keys.
NodeIterator find(const Key &key)
Find a node by key.
bool exists(const Key &key) const
Determine if a key exists.
size_t size() const
Number of nodes, keys, or values in this container.
Optional< Value > getOptional(const Key &key) const
Lookup and return a value or nothing.
Map & erase(const Key &key)
Remove a node with specified key.
boost::iterator_range< NodeIterator > nodes()
Iterators for container nodes.
boost::iterator_range< ConstKeyIterator > keys()
Iterators for container keys.
Map & insert(const Key &key, const Value &value)
Insert or update a key/value pair.
Map & clear()
Remove all nodes.
Error for existing values.
Error for non-existing values.
Holds a value or nothing.
Value orDefault() const
Obtain a value or a default.
const Value & orElse(const Value &dflt) const
Obtain value or something else.
const Id INVALID_ID
Invalid attribute ID.
boost::bad_any_cast WrongQueryType
Exception thrown when wrong data type is queried.
Id declareMaybe(const std::string &name)
Register a new attribute key if not already registered.
const std::string & name(Id)
Returns the name for an attribute ID.
size_t Id
Attribute identification.
Id id(const std::string &name)
Returns the ID for an attribute name.
Id declare(const std::string &name)
Register a new attribute key.
void checkBoost()
Check for valid boost version or abort.
Traits for thread synchronization.