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 this contains an element for the specified 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 ComparisonHelper(const ComparisonHelper&) = delete;
586 ComparisonHelper& operator=(const ComparisonHelper&) = delete;
588 template< typename T >
589 typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
592 return m_valueRef.equals< T >(v);
595 bool equals(const std::string& v) const
597 return m_valueRef.equals< std::string >(v);
600 bool operator==(const ComparisonHelper&) const;
603 const Value& m_valueRef;
607 template< typename T >
608 struct RCSResourceAttributes::IsSupportedTypeHelper
610 typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
613 template < typename T >
614 struct RCSResourceAttributes::IndexOfType
616 static_assert(RCSResourceAttributes::is_supported_type< T >::value,
617 "The type is not supported!");
619 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
620 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
622 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
625 template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
629 * @relates RCSResourceAttributes::Type
631 * Checks if the objects are equal, that is, whether types are exactly same.
633 * @return true if the objects are equal, false otherwise.
635 bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
639 * @relates RCSResourceAttributes::Type
641 * Checks if the objects are not equal, that is, whether types are not exactly same.
643 * @return true if the objects are not equal, false otherwise.
645 bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
649 * @relates RCSResourceAttributes::Value
651 * Checks if the contents are equal, that is,
652 * whether types are matched and underlying values are equal.
654 * @return true if the contents are equal, false otherwise.
656 bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
657 const RCSResourceAttributes::Value::ComparisonHelper&);
660 * @relates RCSResourceAttributes::Value
662 * Checks if the contents are not equal, that is,
663 * whether types are not matched or underlying values are not equal.
665 * @return true if the contents are not equal, false otherwise.
667 bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
668 const RCSResourceAttributes::Value::ComparisonHelper&);
671 template< typename T >
672 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
673 std::is_constructible< std::string, T >::value, bool >::type
674 operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
676 return lhs.equals(rhs);
679 template< typename T >
680 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
681 std::is_constructible< std::string, T >::value, bool >::type
682 operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
687 template< typename T >
688 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
689 std::is_constructible< std::string, T >::value, bool >::type
690 operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
692 return !(lhs == rhs);
695 template< typename T >
696 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
697 std::is_constructible< std::string, T >::value, bool >::type
698 operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
700 return !(rhs == lhs);
705 * @relates RCSResourceAttributes
707 * Checks if the attributes are equal, that is, whether contents are equal.
709 * @return true if the attributes are equal, false otherwise.
711 bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
714 * @relates RCSResourceAttributes
716 * Checks if the attributes are not equal, that is, whether contents are not equal.
718 * @return true if the attributes are not equal, false otherwise.
720 bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
723 * KeyValuePair is a class to access attribute's key and value of an element pointed by
724 * iterators of RCSResourceAttributes.
727 * @see RCSResourceAttributes
729 * @see const_iterator
731 class RCSResourceAttributes::KeyValuePair
734 class KeyVisitor: public boost::static_visitor< const std::string& >
737 result_type operator()(iterator*) const noexcept;
738 result_type operator()(const_iterator*) const noexcept;
741 class ValueVisitor: public boost::static_visitor< Value& >
744 result_type operator()(iterator*) noexcept;
745 result_type operator()(const_iterator*);
748 class ConstValueVisitor: public boost::static_visitor< const Value& >
751 result_type operator()(iterator*) const noexcept;
752 result_type operator()(const_iterator*) const noexcept;
756 const std::string& key() const noexcept;
757 const RCSResourceAttributes::Value& value() const noexcept;
758 RCSResourceAttributes::Value& value();
761 KeyValuePair(const KeyValuePair&) = default;
762 KeyValuePair(boost::variant< iterator*, const_iterator* >&&) noexcept;
764 KeyValuePair& operator=(const KeyValuePair&) = default;
767 boost::variant< iterator*, const_iterator* > m_iterRef;
769 KeyVisitor m_keyVisitor;
770 ValueVisitor m_valueVisitor;
771 ConstValueVisitor m_constValueVisitor;
774 friend class iterator;
775 friend class const_iterator;
780 * A forward iterator to KeyValuePair.
782 * @see RCSResourceAttributes
784 * @see const_iterator
786 class RCSResourceAttributes::iterator:
787 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
790 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
794 iterator(const iterator&) = default;
796 iterator& operator=(const iterator&) = default;
798 reference operator*();
799 pointer operator->();
801 iterator& operator++();
802 iterator operator++(int);
804 bool operator==(const iterator&) const;
805 bool operator!=(const iterator&) const;
808 explicit iterator(base_iterator&&);
812 RCSResourceAttributes::KeyValuePair m_keyValuePair;
815 friend class RCSResourceAttributes;
821 * A forward iterator to const KeyValuePair.
823 * @see RCSResourceAttributes
827 class RCSResourceAttributes::const_iterator:
828 public std::iterator < std::forward_iterator_tag,
829 const RCSResourceAttributes::KeyValuePair >
832 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
836 const_iterator(const const_iterator&) = default;
837 const_iterator(const RCSResourceAttributes::iterator&);
839 const_iterator& operator=(const const_iterator&) = default;
840 const_iterator& operator=(const RCSResourceAttributes::iterator&);
842 reference operator*() const;
843 pointer operator->() const;
845 const_iterator& operator++();
846 const_iterator operator++(int);
848 bool operator==(const const_iterator&) const;
849 bool operator!=(const const_iterator&) const;
852 explicit const_iterator(base_iterator&&);
856 RCSResourceAttributes::KeyValuePair m_keyValuePair;
859 friend class RCSResourceAttributes;
866 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H