ROSE 0.11.145.147
Attribute.h
1// WARNING: Changes to this file must be contributed back to Sawyer or else they will
2// be clobbered by the next update from Sawyer. The Sawyer repository is at
3// https://gitlab.com/charger7534/sawyer.git.
4
5
6
7
8// This header file originally came from the ROSE project, which is released under a BSD license that requires the following
9// notification. All subsequent modifications are licensed as described in Sawyer's top-level "LICENSE" file.
10//
11// License for original version: Revised BSD License (non-advertising clause)
12// License for original version:
13// License for original version: This software is distributed under the revised Berkeley Software Distribution
14// License for original version: (BSD) license by Lawrence Livermore National Laboratory LLNL (managed by the
15// License for original version: University of California). The revised BSD license is the same as the original
16// License for original version: BSD license, but without the famous advertising clause that was a problem
17// License for original version: historically (see www.gnu.org/philosophy/bsd.html for details). Our goal
18// License for original version: has been to select as liberal a license as possible for the ROSE project.
19// License for original version:
20// License for original version: Copyright (c) 2005, 2006, 2007, Regents of the University of California
21// License for original version: All rights reserved.
22// License for original version:
23// License for original version: Revised BSD License:
24// License for original version:
25// License for original version: Redistribution and use in source and binary forms, with or without modification,
26// License for original version: are permitted provided that the following conditions are met:
27// License for original version:
28// License for original version: * Redistributions of source code must retain the above copyright notice,
29// License for original version: this list of conditions and the following disclaimer.
30// License for original version: * Redistributions in binary form must reproduce the above copyright notice,
31// License for original version: this list of conditions and the following disclaimer in the documentation
32// License for original version: and/or other materials provided with the distribution.
33// License for original version: * Neither the name of the University of California nor the names of its
34// License for original version: contributors may be used to endorse or promote products derived from
35// License for original version: this software without specific prior written permission.
36// License for original version:
37// License for original version: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
38// License for original version: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39// License for original version: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40// License for original version: IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
41// License for original version: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
42// License for original version: BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43// License for original version: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44// License for original version: OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45// License for original version: OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46// License for original version: OF THE POSSIBILITY OF SUCH DAMAGE.
47
48#ifndef Sawyer_Attribute_H
49#define Sawyer_Attribute_H
50
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>
59#include <string>
60#include <vector>
61
62namespace Sawyer {
63
135namespace Attribute {
136
140typedef size_t Id;
141
143SAWYER_EXPORT extern const Id INVALID_ID;
144
154SAWYER_EXPORT Id declare(const std::string &name);
155
161SAWYER_EXPORT Id declareMaybe(const std::string &name);
162
169SAWYER_EXPORT Id id(const std::string &name);
170
177SAWYER_EXPORT const std::string& name(Id);
178
182class SAWYER_EXPORT DoesNotExist: public Exception::NotFound {
183public:
184 ~DoesNotExist() throw () {}
185
187 explicit DoesNotExist(const std::string &attrName)
188 : Exception::NotFound(attrName + " does not exist in object") {}
189};
190
192class SAWYER_EXPORT AlreadyExists: public Exception::AlreadyExists {
193public:
194 ~AlreadyExists() throw () {}
195
197 AlreadyExists(const std::string &attrName, Id id)
198 : Exception::AlreadyExists(attrName + " is already a declared attribute (id=" +
199 boost::lexical_cast<std::string>(id) + ")") {}
200};
201
203typedef boost::bad_any_cast WrongQueryType;
204
214template<class SyncTag = SAWYER_THREAD_TAG>
215class Storage {
216public:
218
219private:
221 AttrMap values_;
222 mutable typename Sync::Mutex mutex_;
223
224public:
229 ~Storage() {} // possibly required for MSVC linking
230
234 Storage(const Storage &other) {
235 typename Sync::LockGuard lock(other.mutex_);
236 values_ = other.values_;
237 }
238
242 Storage& operator=(const Storage &other) {
243 typename Sync::LockGuard2 lock(mutex_, other.mutex_);
244 values_ = other.values_;
245 return *this;
246 }
247
253 bool attributeExists(Id id) const {
254 typename Sync::LockGuard lock(mutex_);
255 return values_.exists(id);
256 }
257
265 typename Sync::LockGuard lock(mutex_);
266 values_.erase(id);
267 }
268
273 typename Sync::LockGuard lock(mutex_);
274 values_.clear();
275 }
276
284 template<typename T>
285 void setAttribute(Id id, const T &value) {
286 typename Sync::LockGuard lock(mutex_);
287 values_.insert(id, boost::any(value));
288 }
289
297 template<typename T>
298 bool setAttributeMaybe(Id id, const T &value) {
299 typename Sync::LockGuard lock(mutex_);
300 if (!values_.exists(id)) {
301 values_.insert(id, boost::any(value));
302 return true;
303 }
304 return false;
305 }
306
314 template<typename T>
315 T getAttribute(Id id) const {
316 typename Sync::LockGuard lock(mutex_);
317 AttrMap::ConstNodeIterator found = values_.find(id);
318 if (found == values_.nodes().end()) {
319 std::string name = Attribute::name(id);
320 if (name.empty()) {
321 throw DoesNotExist("attribute id " + boost::lexical_cast<std::string>(id) + " [not declared]");
322 } else {
323 throw DoesNotExist(name);
324 }
325 }
326 checkBoost();
327 return boost::any_cast<T>(values_.getOptional(id).orDefault());
328 }
329
337 template<typename T>
338 T attributeOrElse(Id id, const T &dflt) const {
339 typename Sync::LockGuard lock(mutex_);
340 checkBoost();
341 return boost::any_cast<T>(values_.getOptional(id).orElse(dflt));
342 }
343
351 template<typename T>
352 T attributeOrDefault(Id id) const {
353 typename Sync::LockGuard lock(mutex_);
354 AttrMap::ConstNodeIterator found = values_.find(id);
355 if (found == values_.nodes().end())
356 return T();
357 return boost::any_cast<T>(found->value());
358 }
359
365 template<typename T>
367 typename Sync::LockGuard lock(mutex_);
368 AttrMap::ConstNodeIterator found = values_.find(id);
369 if (found == values_.nodes().end())
370 return Sawyer::Nothing();
371 return boost::any_cast<T>(found->value());
372 }
373
377 size_t nAttributes() const {
378 typename Sync::LockGuard lock(mutex_);
379 return values_.size();
380 }
381
385 std::vector<Id> attributeIds() const {
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);
391 return retval;
392 }
393};
394
395} // namespace
396} // namespace
397
398#endif
Exception thrown when redeclaring an existing attribute.
Definition Attribute.h:192
AlreadyExists(const std::string &attrName, Id id)
Constructor taking an attribute name or description.
Definition Attribute.h:197
Exception for non-existing values.
Definition Attribute.h:182
DoesNotExist(const std::string &attrName)
Constructor taking an attribute name or description.
Definition Attribute.h:187
API and storage for attributes.
Definition Attribute.h:215
std::vector< Id > attributeIds() const
Returns ID numbers for all IDs stored in this container.
Definition Attribute.h:385
bool setAttributeMaybe(Id id, const T &value)
Store an attribute if not already present.
Definition Attribute.h:298
Sawyer::Optional< T > optionalAttribute(Id id) const
Return the attribute as an optional value.
Definition Attribute.h:366
size_t nAttributes() const
Number of attributes stored.
Definition Attribute.h:377
void eraseAttribute(Id id)
Erase an attribute.
Definition Attribute.h:264
T attributeOrDefault(Id id) const
Return an attribute or a default-constructed value.
Definition Attribute.h:352
T attributeOrElse(Id id, const T &dflt) const
Return an attribute or a specified value.
Definition Attribute.h:338
void setAttribute(Id id, const T &value)
Store an attribute.
Definition Attribute.h:285
Storage(const Storage &other)
Copy constructor.
Definition Attribute.h:234
void clearAttributes()
Erase all attributes.
Definition Attribute.h:272
bool attributeExists(Id id) const
Check attribute existence.
Definition Attribute.h:253
Storage & operator=(const Storage &other)
Assignment operator.
Definition Attribute.h:242
Storage()
Default constructor.
Definition Attribute.h:228
T getAttribute(Id id) const
Get an attribute that is known to exist.
Definition Attribute.h:315
Container associating values with keys.
Definition Sawyer/Map.h:72
NodeIterator find(const Key &key)
Find a node by key.
Definition Sawyer/Map.h:480
bool exists(const Key &key) const
Determine if a key exists.
Definition Sawyer/Map.h:493
size_t size() const
Number of nodes, keys, or values in this container.
Definition Sawyer/Map.h:438
Optional< Value > getOptional(const Key &key) const
Lookup and return a value or nothing.
Definition Sawyer/Map.h:602
Map & erase(const Key &key)
Remove a node with specified key.
Definition Sawyer/Map.h:744
boost::iterator_range< NodeIterator > nodes()
Iterators for container nodes.
Definition Sawyer/Map.h:387
boost::iterator_range< ConstKeyIterator > keys()
Iterators for container keys.
Definition Sawyer/Map.h:400
Map & insert(const Key &key, const Value &value)
Insert or update a key/value pair.
Definition Sawyer/Map.h:646
Map & clear()
Remove all nodes.
Definition Sawyer/Map.h:732
Error for existing values.
Error for non-existing values.
Represents no value.
Definition Optional.h:36
Holds a value or nothing.
Definition Optional.h:56
Value orDefault() const
Obtain a value or a default.
Definition Optional.h:305
const Value & orElse(const Value &dflt) const
Obtain value or something else.
Definition Optional.h:267
const Id INVALID_ID
Invalid attribute ID.
boost::bad_any_cast WrongQueryType
Exception thrown when wrong data type is queried.
Definition Attribute.h:203
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.
Definition Attribute.h:140
Id id(const std::string &name)
Returns the ID for an attribute name.
Id declare(const std::string &name)
Register a new attribute key.
Sawyer support library.
void checkBoost()
Check for valid boost version or abort.
Traits for thread synchronization.