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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This file contains the "RCSResourceAttributes" class & its helper classes
26 #ifndef RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
27 #define RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
29 // To avoid conflict using different boost::variant configuration with OC.
30 // It causes compile errors.
31 #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
32 #define BOOST_MPL_LIMIT_LIST_SIZE 30
33 #define BOOST_MPL_LIMIT_VECTOR_SIZE 30
36 #include <unordered_map>
39 #include <boost/variant.hpp>
40 #include <boost/mpl/contains.hpp>
41 #include <boost/mpl/find.hpp>
42 #include <boost/mpl/distance.hpp>
43 #include <boost/mpl/begin_end.hpp>
44 #include <boost/scoped_ptr.hpp>
46 #include <RCSException.h>
54 * RCSResourceAttributes represents the attributes for a resource.
56 * It provides similar usage to c++ standard containers. (iterator,
57 * operators and accessors)<br/>
58 * An attribute value can be one of various types. <br/>
60 * @note If client developer wants to get the RCSResourceAttributes for the resource of
61 * interest following are the steps:
62 * - first call the discover API of DiscoveryManager class.
63 * - After getting the RemoteResourceObject, call getRemoteAttributes() API
64 * of RemoteResourceObject class
70 * @see RCSDiscoveryManager
71 * @see RCSRemoteResourceObject
72 * @see RCSResourceObject
74 class RCSResourceAttributes
77 template< typename T > struct IsSupportedTypeHelper;
79 typedef boost::variant<
85 RCSResourceAttributes,
88 std::vector< double >,
90 std::vector< std::string >,
91 std::vector< RCSResourceAttributes >,
93 std::vector< std::vector< int > >,
94 std::vector< std::vector< std::vector< int > > >,
96 std::vector< std::vector< double > >,
97 std::vector< std::vector< std::vector< double > > >,
99 std::vector< std::vector< bool > >,
100 std::vector< std::vector< std::vector< bool > > >,
102 std::vector< std::vector< std::string > >,
103 std::vector< std::vector< std::vector< std::string > > >,
105 std::vector< std::vector< RCSResourceAttributes > >,
106 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
109 template< typename T, typename V = void,
110 typename = typename std::enable_if<
111 IsSupportedTypeHelper< T >::type::value, V >::type >
112 struct enable_if_supported
117 template< typename VISITOR >
118 class KeyValueVisitorHelper: public boost::static_visitor< >
121 KeyValueVisitorHelper(VISITOR& visitor) noexcept :
126 template< typename T >
127 void operator()(const std::string& key, const T& value) const
129 m_visitor(key, value);
136 template <typename T> struct IndexOfType;
141 * Trait class that identifies whether T is supported by the Value.
143 template< typename T >
144 struct is_supported_type: public std::conditional<
145 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
148 * Identifiers for types of Value.
154 NULL_T, /**< nullptr_t */
156 DOUBLE, /**< double */
158 STRING, /**< std::string */
159 ATTRIBUTES, /**< RCSResourceAttributes */
160 VECTOR /**< std::vector */
164 * A Helper class to identify types of Value.
166 * @see RCSResourceAttributes
173 Type(const Type&) = default;
174 Type(Type&&) = default;
176 Type& operator=(const Type&) = default;
177 Type& operator=(Type&&) = default;
180 * Returns type identifier.
182 * @return Identifier of type.
186 TypeId getId() const noexcept;
189 * Returns the type identifier of a base type of sequence.
191 * For non sequence types, it is equivalent to calling getId.
193 * @return Identifier of type.
198 static TypeId getBaseTypeId(const Type& t) noexcept;
201 * Returns the depth of a type.
203 * The return will be zero for non sequence types.
207 static size_t getDepth(const Type& t) noexcept;
210 * Factory method to create Type instance from T.
212 * @return An instance that has TypeId for T.
214 * @note T must be supported by Value. Otherwise, it won't compile.
216 * @see is_supported_type
218 template < typename T >
219 constexpr static Type typeOf(const T&) noexcept
221 return Type{ IndexOfType< T >::value };
225 * Factory method to create Type instance from T.
227 * @return An instance that has TypeId for T.
229 * @note T must be supported by Value. Otherwise, it won't compile.
231 * @see is_supported_type
233 template < typename T >
234 constexpr static Type typeOf() noexcept
236 return Type{ IndexOfType< T >::value };
240 friend bool operator==(const Type&, const Type&) noexcept;
244 constexpr explicit Type(int which) noexcept :
254 * Value holds a value among various types at a time.
256 * Type helps identify type information of Value.
258 * @see RCSResourceAttributes
260 * @see is_supported_type
265 class ComparisonHelper;
269 Value(Value&&) noexcept;
272 * Constructs a Value if T is a supported type.<br/>
273 * Otherwise it won't compile.
275 template< typename T, typename = typename enable_if_supported< T >::type >
277 m_data{ new ValueVariant{ std::forward< T >(value) } }
283 Value& operator=(const Value&);
284 Value& operator=(Value&&);
286 template< typename T, typename = typename enable_if_supported< T >::type >
287 Value& operator=(T&& rhs)
289 *m_data = std::forward< T >(rhs);
293 Value& operator=(const char*);
294 Value& operator=(std::nullptr_t);
297 * Returns the underlying value as T.
299 * @return const reference to the underlying value.
301 * @throws BadGetException If type of the underlying value is not T.
303 template< typename T >
304 typename std::add_lvalue_reference< const T >::type get() const
306 return checkedGet< T >();
310 * Returns the underlying value as T.
312 * @return reference to the underlying value.
314 * @throws BadGetException If type of the underlying value is not T.
316 template< typename T >
317 typename std::add_lvalue_reference< T >::type get()
319 return checkedGet< T >();
323 * Returns Type information.
327 Type getType() const;
330 * Returns a string representation.
333 std::string toString() const;
336 * Exchanges the content of the object by the content of the parameter.
338 void swap(Value&) noexcept;
341 friend class RCSResourceAttributes;
345 template< typename T, typename = typename enable_if_supported< T >::type >
346 typename std::add_lvalue_reference< T >::type checkedGet() const
350 return boost::get< T >(*m_data);
352 catch (const boost::bad_get&)
354 throw BadGetException{ "Wrong type" };
358 template< typename T, typename U >
359 bool equals(const U& rhs) const
363 return get< T >() == rhs;
365 catch (const BadGetException&)
372 boost::scoped_ptr< ValueVariant > m_data;
377 class const_iterator;
380 RCSResourceAttributes() = default;
381 RCSResourceAttributes(const RCSResourceAttributes&) = default;
382 RCSResourceAttributes(RCSResourceAttributes&&) = default;
384 RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
385 RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
388 * Returns an {@link iterator} referring to the first element.
390 iterator begin() noexcept;
393 * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
395 iterator end() noexcept;
400 const_iterator begin() const noexcept;
405 const_iterator end() const noexcept;
408 * Returns a const_iterator referring to the first element.
410 const_iterator cbegin() const noexcept;
413 * Returns a const_iterator referring to the <i>past-the-end element</i>.
415 const_iterator cend() const noexcept;
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,
423 * inserts a new value with that key and returns a reference to it.
424 * The element is a Value that has null.
426 * @param key Key of the element whose mapped value is accessed.
428 * @return A reference to the mapped value with @a key.
432 Value& operator[](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,
440 * inserts a new value with that key and returns a reference to it.
441 * The value has null.
443 * @param key Key of the element whose mapped value is accessed.
444 * This is moved instead of copied when a new value is inserted.
446 * @return A reference to the mapped value with @a key.
450 Value& operator[](std::string&& key);
455 * If @a key matches the key of a value,
456 * returns a reference to its mapped value. <br/>
457 * If @a key doesn't match the key of any value, throws InvalidKeyException.
459 * @param key Key of the element whose mapped value is accessed.
461 * @throws InvalidKeyException If @a key doesn't match the key of any value.
463 * @return A reference to the mapped value with @a key.
467 Value& at(const std::string& key);
472 * If @a key matches the key of a value,
473 * returns a reference to its mapped value. <br/>
474 * If @a key doesn't match the key of any value, throws InvalidKeyException.
476 * @param key Key of the element whose mapped value is accessed.
478 * @throws InvalidKeyException If @a key doesn't match the key of any value.
480 * @return A const reference to the mapped value with @a key.
484 const Value& at(const std::string& key) const;
487 * Removes all elements.
489 void clear() noexcept;
492 * Removes a single element.
494 * @param key Key of the element to be removed.
496 * @return true if an element is erased, false otherwise.
498 bool erase(const std::string& key);
501 * Checks the container has an element with a Key equivalent to key.
503 * @param key Key to check.
505 * @return true if an element exists, false otherwise.
507 bool contains(const std::string& key) const;
510 * Returns whether it is empty.
514 bool empty() const noexcept;
517 * Returns the number of elements.
521 size_t size() const noexcept;
524 template< typename VISITOR >
525 void visit(VISITOR& visitor) const
527 KeyValueVisitorHelper< VISITOR > helper{ visitor };
529 for (const auto& i : m_values)
531 boost::variant< const std::string& > key{ i.first };
532 boost::apply_visitor(helper, key, *i.second.m_data);
537 std::unordered_map< std::string, Value > m_values;
540 friend class ResourceAttributesConverter;
542 friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
547 * A helper class to avoid obscure comparisons of values which are supported
548 * by RCSResourceAttributes::Value caused by implicitly converting a value
549 * to a RCSResourceAttributes::Value.
552 * @see RCSResourceAttributes
553 * @see is_supported_type
555 class RCSResourceAttributes::Value::ComparisonHelper
558 ComparisonHelper(const Value&);
560 template< typename T >
561 typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
564 return m_valueRef.equals< T >(v);
567 bool equals(const std::string& v) const
569 return m_valueRef.equals< std::string >(v);
572 bool operator==(const ComparisonHelper&) const;
575 const Value& m_valueRef;
578 template< typename T >
579 struct RCSResourceAttributes::IsSupportedTypeHelper
581 typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
584 template < typename T >
585 struct RCSResourceAttributes::IndexOfType
587 static_assert(RCSResourceAttributes::is_supported_type< T >::value,
588 "The type is not supported!");
590 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
591 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
593 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
596 template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
599 * @relates RCSResourceAttributes::Type
601 * Checks if the objects are equal, that is, whether types are exactly same.
603 * @return true if the objects are equal, false otherwise.
605 bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
609 * @relates RCSResourceAttributes::Type
611 * Checks if the objects are not equal, that is, whether types are not exactly same.
613 * @return true if the objects are not equal, false otherwise.
615 bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
619 * @relates RCSResourceAttributes::Value
621 * Checks if the contents are equal, that is,
622 * whether types are matched and underlying values are equal.
624 * @return true if the contents are equal, false otherwise.
626 bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
627 const RCSResourceAttributes::Value::ComparisonHelper&);
630 * @relates RCSResourceAttributes::Value
632 * Checks if the contents are not equal, that is,
633 * whether types are not matched or underlying values are not equal.
635 * @return true if the contents are not equal, false otherwise.
637 bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
638 const RCSResourceAttributes::Value::ComparisonHelper&);
641 template< typename T >
642 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
643 std::is_constructible< std::string, T >::value, bool >::type
644 operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
646 return lhs.equals(rhs);
649 template< typename T >
650 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
651 std::is_constructible< std::string, T >::value, bool >::type
652 operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
657 template< typename T >
658 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
659 std::is_constructible< std::string, T >::value, bool >::type
660 operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
662 return !(lhs == rhs);
665 template< typename T >
666 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
667 std::is_constructible< std::string, T >::value, bool >::type
668 operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
670 return !(rhs == lhs);
675 * @relates RCSResourceAttributes
677 * Checks if the attributes are equal, that is, whether contents are equal.
679 * @return true if the attributes are equal, false otherwise.
681 bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
684 * @relates RCSResourceAttributes
686 * Checks if the attributes are not equal, that is, whether contents are not equal.
688 * @return true if the attributes are not equal, false otherwise.
690 bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
693 * KeyValuePair is a class to access attribute's key and value of an element pointed by
694 * iterators of RCSResourceAttributes.
697 * @see RCSResourceAttributes
699 * @see const_iterator
701 class RCSResourceAttributes::KeyValuePair
704 class KeyVisitor: public boost::static_visitor< const std::string& >
707 result_type operator()(iterator*) const noexcept;
708 result_type operator()(const_iterator*) const noexcept;
711 class ValueVisitor: public boost::static_visitor< Value& >
714 result_type operator()(iterator*) noexcept;
715 result_type operator()(const_iterator*);
718 class ConstValueVisitor: public boost::static_visitor< const Value& >
721 result_type operator()(iterator*) const noexcept;
722 result_type operator()(const_iterator*) const noexcept;
726 const std::string& key() const noexcept;
727 const RCSResourceAttributes::Value& value() const noexcept;
728 RCSResourceAttributes::Value& value();
731 KeyValuePair(const KeyValuePair&) = default;
732 KeyValuePair(boost::variant< iterator*, const_iterator* >&&) noexcept;
734 KeyValuePair& operator=(const KeyValuePair&) = default;
737 boost::variant< iterator*, const_iterator* > m_iterRef;
739 KeyVisitor m_keyVisitor;
740 ValueVisitor m_valueVisitor;
741 ConstValueVisitor m_constValueVisitor;
744 friend class iterator;
745 friend class const_iterator;
750 * A forward iterator to KeyValuePair.
752 * @see RCSResourceAttributes
754 * @see const_iterator
756 class RCSResourceAttributes::iterator:
757 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
760 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
764 iterator(const iterator&) = default;
766 iterator& operator=(const iterator&) = default;
768 reference operator*();
769 pointer operator->();
771 iterator& operator++();
772 iterator operator++(int);
774 bool operator==(const iterator&) const;
775 bool operator!=(const iterator&) const;
778 explicit iterator(base_iterator&&);
782 RCSResourceAttributes::KeyValuePair m_keyValuePair;
785 friend class RCSResourceAttributes;
791 * A forward iterator to const KeyValuePair.
793 * @see RCSResourceAttributes
797 class RCSResourceAttributes::const_iterator:
798 public std::iterator < std::forward_iterator_tag,
799 const RCSResourceAttributes::KeyValuePair >
802 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
806 const_iterator(const const_iterator&) = default;
807 const_iterator(const RCSResourceAttributes::iterator&);
809 const_iterator& operator=(const const_iterator&) = default;
810 const_iterator& operator=(const RCSResourceAttributes::iterator&);
812 reference operator*() const;
813 pointer operator->() const;
815 const_iterator& operator++();
816 const_iterator operator++(int);
818 bool operator==(const const_iterator&) const;
819 bool operator!=(const const_iterator&) const;
822 explicit const_iterator(base_iterator&&);
826 RCSResourceAttributes::KeyValuePair m_keyValuePair;
829 friend class RCSResourceAttributes;
836 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H