1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #ifndef RES_MANIPULATION_RESOURCEATTRIBUTES_H
22 #define RES_MANIPULATION_RESOURCEATTRIBUTES_H
24 // To avoid conflict using different boost::variant configuration with OC.
25 // It causes compile errors.
26 #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
27 #define BOOST_MPL_LIMIT_LIST_SIZE 30
28 #define BOOST_MPL_LIMIT_VECTOR_SIZE 30
31 #include <unordered_map>
33 #include <boost/variant.hpp>
34 #include <boost/mpl/contains.hpp>
35 #include <boost/mpl/find.hpp>
36 #include <boost/mpl/distance.hpp>
37 #include <boost/mpl/begin_end.hpp>
38 #include <boost/scoped_ptr.hpp>
40 #include <RCSException.h>
44 * This file contains the "ResourceAttributes" class & its helper classes
51 * Thrown when getting value with wrong template parameter.
53 class BadGetException: public RCSException
56 BadGetException(const std::string& what) : RCSException{ what } {}
57 BadGetException(std::string&& what) : RCSException{ std::move(what) } {}
61 * Thrown when a key is invalid.
63 class InvalidKeyException: public RCSException
66 InvalidKeyException(const std::string& what) : RCSException{ what } {}
67 InvalidKeyException(std::string&& what) : RCSException{ std::move(what) } {}
71 * ResourceAttributes represents the attributes for a resource.
73 * It provides similar usage to c++ standard containers. (iterator,
74 * operators and accessors)<br/>
75 * An attribute value can be one of various types. <br/>
77 * @note If client developer wants to get the ResourceAttributes for the resource of
78 * interest following are the steps:
79 * - first call the discover API of DiscoveryManager class.
80 * - After getting the RemoteResourceObject, call getRemoteAttributes() API
81 * of RemoteResourceObject class
87 * @see DiscoveryManager
88 * @see RemoteResourceObject
91 class ResourceAttributes
94 template< typename T > struct IsSupportedTypeHelper;
96 typedef boost::variant<
105 template< typename T, typename V = void,
106 typename = typename std::enable_if<
107 IsSupportedTypeHelper< T >::type::value, V >::type >
108 struct enable_if_supported
113 template< typename VISITOR >
114 class KeyValueVisitorHelper: public boost::static_visitor< >
117 KeyValueVisitorHelper(VISITOR& visitor) :
122 template< typename T >
123 void operator()(const std::string& key, const T& value) const
125 m_visitor(key, value);
132 template <typename T> struct IndexOfType;
137 * Trait class that identifies whether T is supported by the Value.
139 template< typename T >
140 struct is_supported_type: public std::conditional<
141 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
144 * Identifier for types of Value.
150 NULL_T, /**< nullptr_t */
152 DOUBLE, /**< double */
154 STRING, /**< std::string */
155 ATTRIBUTES, /**< ResourceAttributes */
156 VECTOR /**< std::vector */
160 * A Helper class to identify types of Value.
162 * @see ResourceAttributes
169 Type(const Type&) = default;
170 Type(Type&&) = default;
172 Type& operator=(const Type&) = default;
173 Type& operator=(Type&&) = default;
176 * Returns type identifier.
178 * @return Identifier of type.
180 TypeId getId() const;
183 * Factory method to create Type instance from T.
185 * @return An instance that has TypeId for T.
187 * @note T must be supported by Value. Otherwise, it won't be compiled.
189 * @see is_supported_type
191 template < typename T >
192 static Type typeOf(const T& value)
198 friend bool operator==(const Type&, const Type&);
202 template < typename T >
203 explicit Type(const T&) :
204 m_which{ IndexOfType< T >::value }
213 * Value holds a value among various types at a time.
215 * Type helps identify type information of Value.
217 * @see ResourceAttributes
219 * @see is_supported_type
229 * Constructs a Value if T is a supported type.<br/>
230 * Otherwise it won't be compiled.
232 template< typename T, typename = typename enable_if_supported< T >::type >
234 m_data{ new ValueVariant{ std::forward< T >(value) } }
238 Value(const char* value);
240 Value& operator=(const Value&);
241 Value& operator=(Value&&);
243 template< typename T, typename = typename enable_if_supported< T >::type >
244 Value& operator=(T&& rhs)
246 *m_data = std::forward< T >(rhs);
250 Value& operator=(const char*);
251 Value& operator=(std::nullptr_t);
254 * Returns the underlying value as T.
256 * @return const reference to the underlying value.
258 * @throws BadGetException If type of the underlying value is not T.
260 template< typename T >
261 typename std::add_lvalue_reference< const T >::type get() const
263 return checkedGet< T >();
267 * Returns the underlying value as T.
269 * @return reference to the underlying value.
271 * @throws BadGetException If type of the underlying value is not T.
273 template< typename T >
274 typename std::add_lvalue_reference< T >::type get()
276 return checkedGet< T >();
280 * Returns Type information.
284 Type getType() const;
287 * Returns a string representation.
290 std::string toString() const;
293 * Exchanges the content of the object by the content of the parameter.
298 friend bool operator==(const Value&, const Value&);
300 template< typename T >
301 friend typename std::enable_if< ResourceAttributes::is_supported_type< T >::value,
302 bool >::type operator==(const Value&, const T&);
304 bool operator==(const char*) const;
306 friend class ResourceAttributes;
310 template< typename T, typename = typename enable_if_supported< T >::type >
311 typename std::add_lvalue_reference< T >::type checkedGet() const
315 return boost::get< T >(*m_data);
317 catch (const boost::bad_get&)
319 throw BadGetException{ "Wrong type" };
323 template< typename T, typename U >
324 bool equals(const U& rhs) const
328 return get< T >() == rhs;
330 catch (const BadGetException&)
337 boost::scoped_ptr< ValueVariant > m_data;
342 class const_iterator;
345 ResourceAttributes() = default;
346 ResourceAttributes(const ResourceAttributes&) = default;
347 ResourceAttributes(ResourceAttributes&&) = default;
349 ResourceAttributes& operator=(const ResourceAttributes&) = default;
350 ResourceAttributes& operator=(ResourceAttributes&&) = default;
353 * Returns an {@link iterator} referring to the first element.
358 * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
365 const_iterator begin() const;
370 const_iterator end() const;
373 * Returns a const_iterator referring to the first element.
375 const_iterator cbegin() const;
378 * Returns a const_iterator referring to the <i>past-the-end element</i>.
380 const_iterator cend() const;
385 * If @a key matches the key of a value,
386 * returns a reference to its mapped value. <br/>
387 * If @a key doesn't match the key of any value,
388 * inserts a new value with that key and returns a reference to it.
389 * The element is a Value that has null.
391 * @param key Key of the element whose mapped value is accessed.
393 * @return A reference to the mapped value with @a key.
397 Value& operator[](const std::string& key);
402 * If @a key matches the key of a value,
403 * returns a reference to its mapped value. <br/>
404 * If @a key doesn't match the key of any value,
405 * inserts a new value with that key and returns a reference to it.
406 * The value has null.
408 * @param key Key of the element whose mapped value is accessed.
409 * This is moved instead of copied when a new value is inserted.
411 * @return A reference to the mapped value with @a key.
415 Value& operator[](std::string&& key);
420 * If @a key matches the key of a value,
421 * returns a reference to its mapped value. <br/>
422 * If @a key doesn't match the key of any value, throws InvalidKeyException.
424 * @param key Key of the element whose mapped value is accessed.
426 * @throws InvalidKeyException If @a key doesn't match the key of any value.
428 * @return A reference to the mapped value with @a key.
432 Value& at(const std::string& key);
437 * If @a key matches the key of a value,
438 * returns a reference to its mapped value. <br/>
439 * If @a key doesn't match the key of any value, throws InvalidKeyException.
441 * @param key Key of the element whose mapped value is accessed.
443 * @throws InvalidKeyException If @a key doesn't match the key of any value.
445 * @return A const reference to the mapped value with @a key.
449 const Value& at(const std::string& key) const;
452 * Removes all elements.
457 * Removes a single element.
459 * @param key Key of the element to be removed.
461 * @return true if an element is erased, false otherwise.
463 bool erase(const std::string& key);
466 * Checks the container has an element with a Key equivalent to key.
468 * @param key Key to check.
470 * @return true if an element exists, false otherwise.
472 bool contains(const std::string& key) const;
475 * Returns whether it is empty.
482 * Returns the number of elements.
489 template< typename VISITOR >
490 void visit(VISITOR& visitor) const
492 KeyValueVisitorHelper< VISITOR > helper{ visitor };
494 for (const auto& i : m_values)
496 boost::variant< const std::string& > key{ i.first };
497 boost::apply_visitor(helper, key, *i.second.m_data);
502 std::unordered_map< std::string, Value > m_values;
505 friend class ResourceAttributesConverter;
507 friend bool operator==(const ResourceAttributes&, const ResourceAttributes&);
511 template< typename T >
512 struct ResourceAttributes::IsSupportedTypeHelper
514 typedef boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type> type;
517 template <typename T>
518 struct ResourceAttributes::IndexOfType
520 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
521 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
523 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
527 * @relates ResourceAttributes::Type
529 * Checks if the objects are equal, that is, whether types are exactly same.
531 * @return true if the objects are equal, false otherwise.
533 bool operator==(const ResourceAttributes::Type&, const ResourceAttributes::Type&);
536 * @relates ResourceAttributes::Type
538 * Checks if the objects are not equal, that is, whether types are not exactly same.
540 * @return true if the objects are not equal, false otherwise.
542 bool operator!=(const ResourceAttributes::Type&, const ResourceAttributes::Type&);
546 * @relates ResourceAttributes::Value
548 * Checks if the contents are equal, that is,
549 * whether types are matched and underlying values are equal.
551 * @return true if the contents are equal, false otherwise.
553 bool operator==(const ResourceAttributes::Value&, const ResourceAttributes::Value&);
556 * @relates ResourceAttributes::Value
558 * Checks if the contents are not equal, that is,
559 * whether types are not matched or underlying values are not equal.
561 * @return true if the contents are not equal, false otherwise.
563 bool operator!=(const ResourceAttributes::Value&, const ResourceAttributes::Value&);
566 template< typename T >
567 typename std::enable_if< ResourceAttributes::is_supported_type< T >::value, bool >::type
568 operator==(const ResourceAttributes::Value& lhs, const T& rhs)
570 return lhs.equals< T >(rhs);
573 template< typename T >
574 bool operator==(const T& lhs, const ResourceAttributes::Value& rhs)
579 template< typename T >
580 typename std::enable_if< ResourceAttributes::is_supported_type< T >::value, bool >::type
581 operator!=(const T& lhs, const ResourceAttributes::Value& rhs)
583 return !(rhs == lhs);
586 bool operator!=(const char*, const ResourceAttributes::Value&);
588 bool operator==(const char* lhs, const ResourceAttributes::Value& rhs);
592 * @relates ResourceAttributes
594 * Checks if the attributes are equal, that is, whether contents are equal.
596 * @return true if the attributes are equal, false otherwise.
598 bool operator==(const ResourceAttributes& lhs, const ResourceAttributes& rhs);
601 * @relates ResourceAttributes
603 * Checks if the attributes are not equal, that is, whether contents are not equal.
605 * @return true if the attributes are not equal, false otherwise.
607 bool operator!=(const ResourceAttributes&, const ResourceAttributes&);
610 * KeyValuePair is a class to access attribute's key and value of an element pointed by
611 * iterators of ResourceAttributes.
614 * @see ResourceAttributes
616 * @see const_iterator
618 class ResourceAttributes::KeyValuePair
621 class KeyVisitor: public boost::static_visitor< const std::string& >
624 result_type operator()(iterator*) const;
625 result_type operator()(const_iterator*) const;
628 class ValueVisitor: public boost::static_visitor< Value& >
631 result_type operator()(iterator*);
632 result_type operator()(const_iterator*);
635 class ConstValueVisitor: public boost::static_visitor< const Value& >
638 result_type operator()(iterator*) const;
639 result_type operator()(const_iterator*) const;
643 const std::string& key() const;
644 const ResourceAttributes::Value& value() const;
645 ResourceAttributes::Value& value();
648 KeyValuePair(const KeyValuePair&) = default;
649 KeyValuePair(boost::variant< iterator*, const_iterator* >&&);
651 KeyValuePair& operator=(const KeyValuePair&) = default;
654 boost::variant< iterator*, const_iterator* > m_iterRef;
656 KeyVisitor m_keyVisitor;
657 ValueVisitor m_valueVisitor;
658 ConstValueVisitor m_constValueVisitor;
661 friend class iterator;
662 friend class const_iterator;
667 * A forward iterator to KeyValuePair.
669 * @see ResourceAttributes
671 * @see const_iterator
673 class ResourceAttributes::iterator:
674 public std::iterator< std::forward_iterator_tag, ResourceAttributes::KeyValuePair >
677 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
681 iterator(const iterator&) = default;
683 iterator& operator=(const iterator&) = default;
685 reference operator*();
686 pointer operator->();
688 iterator& operator++();
689 iterator operator++(int);
691 bool operator==(const iterator&) const;
692 bool operator!=(const iterator&) const;
695 explicit iterator(base_iterator&&);
699 ResourceAttributes::KeyValuePair m_keyValuePair;
702 friend class ResourceAttributes;
708 * A forward iterator to const KeyValuePair.
710 * @see ResourceAttributes
714 class ResourceAttributes::const_iterator:
715 public std::iterator < std::forward_iterator_tag,
716 const ResourceAttributes::KeyValuePair >
719 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
723 const_iterator(const const_iterator&) = default;
724 const_iterator(const ResourceAttributes::iterator&);
726 const_iterator& operator=(const const_iterator&) = default;
727 const_iterator& operator=(const ResourceAttributes::iterator&);
729 reference operator*() const;
730 pointer operator->() const;
732 const_iterator& operator++();
733 const_iterator operator++(int);
735 bool operator==(const const_iterator&) const;
736 bool operator!=(const const_iterator&) const;
739 explicit const_iterator(base_iterator&&);
743 ResourceAttributes::KeyValuePair m_keyValuePair;
746 friend class ResourceAttributes;
753 #endif // RES_MANIPULATION_RESOURCEATTRIBUTES_H