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 declaration of classes and its members related to RCSResourceAttributes
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 * This 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/>
65 * @see RCSDiscoveryManager
66 * @see RCSRemoteResourceObject
67 * @see RCSResourceObject
69 class RCSResourceAttributes
72 template< typename T > struct IsSupportedTypeHelper;
74 typedef boost::variant<
80 RCSResourceAttributes,
83 std::vector< double >,
85 std::vector< std::string >,
86 std::vector< RCSResourceAttributes >,
88 std::vector< std::vector< int > >,
89 std::vector< std::vector< std::vector< int > > >,
91 std::vector< std::vector< double > >,
92 std::vector< std::vector< std::vector< double > > >,
94 std::vector< std::vector< bool > >,
95 std::vector< std::vector< std::vector< bool > > >,
97 std::vector< std::vector< std::string > >,
98 std::vector< std::vector< std::vector< std::string > > >,
100 std::vector< std::vector< RCSResourceAttributes > >,
101 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
104 template< typename T, typename V = void,
105 typename = typename std::enable_if<
106 IsSupportedTypeHelper< T >::type::value, V >::type >
107 struct enable_if_supported
112 template< typename VISITOR >
113 class KeyValueVisitorHelper: public boost::static_visitor< >
116 KeyValueVisitorHelper(VISITOR& visitor) noexcept :
121 template< typename T >
122 void operator()(const std::string& key, const T& value) const
124 m_visitor(key, value);
131 template <typename T> struct IndexOfType;
136 * Trait class that identifies whether T is supported by the Value.
138 template< typename T >
139 struct is_supported_type: public std::conditional<
140 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
143 * Identifiers for types of Value.
149 NULL_T, /**< nullptr_t */
151 DOUBLE, /**< double */
153 STRING, /**< std::string */
154 ATTRIBUTES, /**< RCSResourceAttributes */
155 VECTOR /**< std::vector */
159 * A Helper class to identify types of Value.
161 * @see RCSResourceAttributes
168 Type(const Type&) = default;
169 Type(Type&&) = default;
171 Type& operator=(const Type&) = default;
172 Type& operator=(Type&&) = default;
175 * Returns type identifier.
177 * @return Identifier of type.
181 TypeId getId() const noexcept;
184 * Returns the type identifier of a base type of sequence.
186 * For non sequence types, it is equivalent to calling getId.
188 * @return Identifier of type.
193 static TypeId getBaseTypeId(const Type& t) noexcept;
196 * Returns the depth of a type.
198 * The return will be zero for non sequence types.
202 static size_t getDepth(const Type& t) noexcept;
205 * Factory method to create Type instance from T.
207 * @return An instance that has TypeId for T.
209 * @note T must be supported by Value. Otherwise, it won't compile.
211 * @see is_supported_type
213 template < typename T >
214 constexpr static Type typeOf(const T&) noexcept
216 return Type{ IndexOfType< T >::value };
220 * Factory method to create Type instance from T.
222 * @return An instance that has TypeId for T.
224 * @note T must be supported by Value. Otherwise, it won't compile.
226 * @see is_supported_type
228 template < typename T >
229 constexpr static Type typeOf() noexcept
231 return Type{ IndexOfType< T >::value };
235 friend bool operator==(const Type&, const Type&) noexcept;
239 constexpr explicit Type(int which) noexcept :
249 * Value holds a value among various types at a time.
251 * Type helps identify type information of Value.
253 * Supported types are below
259 RCSResourceAttributes
262 std::vector< double >
264 std::vector< std::string >
265 std::vector< RCSResourceAttributes >
267 std::vector< std::vector< int > >
268 std::vector< std::vector< std::vector< int > > >
270 std::vector< std::vector< double > >
271 std::vector< std::vector< std::vector< double > > >
273 std::vector< std::vector< bool > >
274 std::vector< std::vector< std::vector< bool > > >
276 std::vector< std::vector< std::string > >
277 std::vector< std::vector< std::vector< std::string > > >
279 std::vector< std::vector< RCSResourceAttributes > >
280 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
283 * @see RCSResourceAttributes
285 * @see is_supported_type
290 class ComparisonHelper;
294 Value(Value&&) noexcept;
297 * Constructs a Value if T is a supported type.<br/>
298 * Otherwise it won't compile.
300 template< typename T, typename = typename enable_if_supported< T >::type >
302 m_data{ new ValueVariant{ std::forward< T >(value) } }
308 Value& operator=(const Value&);
309 Value& operator=(Value&&);
311 template< typename T, typename = typename enable_if_supported< T >::type >
312 Value& operator=(T&& rhs)
314 *m_data = std::forward< T >(rhs);
318 Value& operator=(const char*);
319 Value& operator=(std::nullptr_t);
322 * Returns the underlying value as T.
324 * @return const reference to the underlying value.
326 * @throws BadGetException If type of the underlying value is not T.
328 template< typename T >
329 typename std::add_lvalue_reference< const T >::type get() const
331 return checkedGet< T >();
335 * Returns the underlying value as T.
337 * @return reference to the underlying value.
339 * @throws BadGetException If type of the underlying value is not T.
341 template< typename T >
342 typename std::add_lvalue_reference< T >::type get()
344 return checkedGet< T >();
348 * Returns Type information.
352 Type getType() const;
355 * Returns a string representation.
358 std::string toString() const;
361 * Exchanges the content of the object by the content of the parameter.
363 void swap(Value&) noexcept;
366 friend class RCSResourceAttributes;
370 template< typename T, typename = typename enable_if_supported< T >::type >
371 typename std::add_lvalue_reference< T >::type checkedGet() const
375 return boost::get< T >(*m_data);
377 catch (const boost::bad_get&)
379 throw RCSBadGetException{ "Wrong type" };
383 template< typename T, typename U >
384 bool equals(const U& rhs) const
388 return get< T >() == rhs;
390 catch (const RCSBadGetException&)
397 boost::scoped_ptr< ValueVariant > m_data;
402 class const_iterator;
405 RCSResourceAttributes() = default;
406 RCSResourceAttributes(const RCSResourceAttributes&) = default;
407 RCSResourceAttributes(RCSResourceAttributes&&) = default;
409 RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
410 RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
413 * Returns an {@link iterator} referring to the first element.
415 iterator begin() noexcept;
418 * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
420 iterator end() noexcept;
425 const_iterator begin() const noexcept;
430 const_iterator end() const noexcept;
433 * Returns a const_iterator referring to the first element.
435 const_iterator cbegin() const noexcept;
438 * Returns a const_iterator referring to the <i>past-the-end element</i>.
440 const_iterator cend() const noexcept;
445 * If @a key matches the key of a value,
446 * returns a reference to its mapped value. <br/>
447 * If @a key doesn't match the key of any value,
448 * inserts a new value with that key and returns a reference to it.
449 * The element is a Value that has null.
451 * @param key Key of the element whose mapped value is accessed.
453 * @return A reference to the mapped value with @a key.
457 Value& operator[](const std::string& key);
462 * If @a key matches the key of a value,
463 * returns a reference to its mapped value. <br/>
464 * If @a key doesn't match the key of any value,
465 * inserts a new value with that key and returns a reference to it.
466 * The value has null.
468 * @param key Key of the element whose mapped value is accessed.
469 * This is moved instead of copied when a new value is inserted.
471 * @return A reference to the mapped value with @a key.
475 Value& operator[](std::string&& key);
480 * If @a key matches the key of a value,
481 * returns a reference to its mapped value. <br/>
482 * If @a key doesn't match the key of any value, throws InvalidKeyException.
484 * @param key Key of the element whose mapped value is accessed.
486 * @throws InvalidKeyException If @a key doesn't match the key of any value.
488 * @return A reference to the mapped value with @a key.
492 Value& at(const std::string& key);
497 * If @a key matches the key of a value,
498 * returns a reference to its mapped value. <br/>
499 * If @a key doesn't match the key of any value, throws InvalidKeyException.
501 * @param key Key of the element whose mapped value is accessed.
503 * @throws InvalidKeyException If @a key doesn't match the key of any value.
505 * @return A const reference to the mapped value with @a key.
509 const Value& at(const std::string& key) const;
512 * Removes all elements.
514 void clear() noexcept;
517 * Removes a single element.
519 * @param key Key of the element to be removed.
521 * @return true if an element is erased, false otherwise.
523 bool erase(const std::string& key);
526 * Checks the container has an element with a Key equivalent to key.
528 * @param key Key to check.
530 * @return true if an element exists, false otherwise.
532 bool contains(const std::string& key) const;
535 * Returns whether it is empty.
539 bool empty() const noexcept;
542 * Returns the number of elements.
546 size_t size() const noexcept;
549 template< typename VISITOR >
550 void visit(VISITOR& visitor) const
552 KeyValueVisitorHelper< VISITOR > helper{ visitor };
554 for (const auto& i : m_values)
556 boost::variant< const std::string& > key{ i.first };
557 boost::apply_visitor(helper, key, *i.second.m_data);
562 std::unordered_map< std::string, Value > m_values;
565 friend class ResourceAttributesConverter;
567 friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
572 * A helper class to avoid obscure comparisons of values which are supported
573 * by RCSResourceAttributes::Value caused by implicitly converting a value
574 * to a RCSResourceAttributes::Value.
577 * @see RCSResourceAttributes
578 * @see is_supported_type
580 class RCSResourceAttributes::Value::ComparisonHelper
583 ComparisonHelper(const Value&);
585 template< typename T >
586 typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
589 return m_valueRef.equals< T >(v);
592 bool equals(const std::string& v) const
594 return m_valueRef.equals< std::string >(v);
597 bool operator==(const ComparisonHelper&) const;
600 const Value& m_valueRef;
603 template< typename T >
604 struct RCSResourceAttributes::IsSupportedTypeHelper
606 typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
609 template < typename T >
610 struct RCSResourceAttributes::IndexOfType
612 static_assert(RCSResourceAttributes::is_supported_type< T >::value,
613 "The type is not supported!");
615 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
616 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
618 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
621 template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
624 * @relates RCSResourceAttributes::Type
626 * Checks if the objects are equal, that is, whether types are exactly same.
628 * @return true if the objects are equal, false otherwise.
630 bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
634 * @relates RCSResourceAttributes::Type
636 * Checks if the objects are not equal, that is, whether types are not exactly same.
638 * @return true if the objects are not equal, false otherwise.
640 bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
644 * @relates RCSResourceAttributes::Value
646 * Checks if the contents are equal, that is,
647 * whether types are matched and underlying values are equal.
649 * @return true if the contents are equal, false otherwise.
651 bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
652 const RCSResourceAttributes::Value::ComparisonHelper&);
655 * @relates RCSResourceAttributes::Value
657 * Checks if the contents are not equal, that is,
658 * whether types are not matched or underlying values are not equal.
660 * @return true if the contents are not equal, false otherwise.
662 bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
663 const RCSResourceAttributes::Value::ComparisonHelper&);
666 template< typename T >
667 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
668 std::is_constructible< std::string, T >::value, bool >::type
669 operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
671 return lhs.equals(rhs);
674 template< typename T >
675 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
676 std::is_constructible< std::string, T >::value, bool >::type
677 operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
682 template< typename T >
683 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
684 std::is_constructible< std::string, T >::value, bool >::type
685 operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
687 return !(lhs == rhs);
690 template< typename T >
691 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
692 std::is_constructible< std::string, T >::value, bool >::type
693 operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
695 return !(rhs == lhs);
700 * @relates RCSResourceAttributes
702 * Checks if the attributes are equal, that is, whether contents are equal.
704 * @return true if the attributes are equal, false otherwise.
706 bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
709 * @relates RCSResourceAttributes
711 * Checks if the attributes are not equal, that is, whether contents are not equal.
713 * @return true if the attributes are not equal, false otherwise.
715 bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
718 * KeyValuePair is a class to access attribute's key and value of an element pointed by
719 * iterators of RCSResourceAttributes.
722 * @see RCSResourceAttributes
724 * @see const_iterator
726 class RCSResourceAttributes::KeyValuePair
729 class KeyVisitor: public boost::static_visitor< const std::string& >
732 result_type operator()(iterator*) const noexcept;
733 result_type operator()(const_iterator*) const noexcept;
736 class ValueVisitor: public boost::static_visitor< Value& >
739 result_type operator()(iterator*) noexcept;
740 result_type operator()(const_iterator*);
743 class ConstValueVisitor: public boost::static_visitor< const Value& >
746 result_type operator()(iterator*) const noexcept;
747 result_type operator()(const_iterator*) const noexcept;
751 const std::string& key() const noexcept;
752 const RCSResourceAttributes::Value& value() const noexcept;
753 RCSResourceAttributes::Value& value();
756 KeyValuePair(const KeyValuePair&) = default;
757 KeyValuePair(boost::variant< iterator*, const_iterator* >&&) noexcept;
759 KeyValuePair& operator=(const KeyValuePair&) = default;
762 boost::variant< iterator*, const_iterator* > m_iterRef;
764 KeyVisitor m_keyVisitor;
765 ValueVisitor m_valueVisitor;
766 ConstValueVisitor m_constValueVisitor;
769 friend class iterator;
770 friend class const_iterator;
775 * A forward iterator to KeyValuePair.
777 * @see RCSResourceAttributes
779 * @see const_iterator
781 class RCSResourceAttributes::iterator:
782 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
785 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
789 iterator(const iterator&) = default;
791 iterator& operator=(const iterator&) = default;
793 reference operator*();
794 pointer operator->();
796 iterator& operator++();
797 iterator operator++(int);
799 bool operator==(const iterator&) const;
800 bool operator!=(const iterator&) const;
803 explicit iterator(base_iterator&&);
807 RCSResourceAttributes::KeyValuePair m_keyValuePair;
810 friend class RCSResourceAttributes;
816 * A forward iterator to const KeyValuePair.
818 * @see RCSResourceAttributes
822 class RCSResourceAttributes::const_iterator:
823 public std::iterator < std::forward_iterator_tag,
824 const RCSResourceAttributes::KeyValuePair >
827 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
831 const_iterator(const const_iterator&) = default;
832 const_iterator(const RCSResourceAttributes::iterator&);
834 const_iterator& operator=(const const_iterator&) = default;
835 const_iterator& operator=(const RCSResourceAttributes::iterator&);
837 reference operator*() const;
838 pointer operator->() const;
840 const_iterator& operator++();
841 const_iterator operator++(int);
843 bool operator==(const const_iterator&) const;
844 bool operator!=(const const_iterator&) const;
847 explicit const_iterator(base_iterator&&);
851 RCSResourceAttributes::KeyValuePair m_keyValuePair;
854 friend class RCSResourceAttributes;
861 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H