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, typename MOVE = std::false_type >
113 class KeyValueVisitorHelper: public boost::static_visitor< >
116 KeyValueVisitorHelper(VISITOR& visitor) BOOST_NOEXCEPT :
121 template< typename T, typename M = MOVE >
122 typename std::enable_if< std::is_same< M, std::false_type >::value >::type
123 operator()(const std::string& key, const T& value) const
125 m_visitor(key, value);
128 template< typename T, typename M = MOVE >
129 typename std::enable_if< std::is_same< M, std::true_type >::value >::type
130 operator()(const std::string& key, T& value)
132 m_visitor(key, std::move(value));
139 template <typename T> struct IndexOfType;
144 * Trait class that identifies whether T is supported by the Value.
146 template< typename T >
147 struct is_supported_type: public std::conditional<
148 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
151 * Identifiers for types of Value.
157 NULL_T, /**< nullptr_t */
159 DOUBLE, /**< double */
161 STRING, /**< std::string */
162 ATTRIBUTES, /**< RCSResourceAttributes */
163 VECTOR /**< std::vector */
167 * A Helper class to identify types of Value.
169 * @see RCSResourceAttributes
176 Type(const Type&) = default;
177 Type(Type&&) = default;
179 Type& operator=(const Type&) = default;
180 Type& operator=(Type&&) = default;
183 * Returns type identifier.
185 * @return Identifier of type.
189 TypeId getId() const BOOST_NOEXCEPT;
192 * Returns the type identifier of a base type of sequence.
194 * For non sequence types, it is equivalent to calling getId.
196 * @return Identifier of type.
201 static TypeId getBaseTypeId(const Type& t) BOOST_NOEXCEPT;
204 * Returns the depth of a type.
206 * The return will be zero for non sequence types.
210 static size_t getDepth(const Type& t) BOOST_NOEXCEPT;
213 * Factory method to create Type instance from T.
215 * @return An instance that has TypeId for T.
217 * @note T must be supported by Value. Otherwise, it won't compile.
219 * @see is_supported_type
221 template < typename T >
222 constexpr static Type typeOf(const T&) BOOST_NOEXCEPT
224 return Type{ IndexOfType< T >::value };
228 * Factory method to create Type instance from T.
230 * @return An instance that has TypeId for T.
232 * @note T must be supported by Value. Otherwise, it won't compile.
234 * @see is_supported_type
236 template < typename T >
237 constexpr static Type typeOf() BOOST_NOEXCEPT
239 return Type{ IndexOfType< T >::value };
243 friend bool operator==(const Type&, const Type&) BOOST_NOEXCEPT;
247 constexpr explicit Type(int which) BOOST_NOEXCEPT :
257 * Value holds a value among various types at a time.
259 * Type helps identify type information of Value.
261 * Supported types are below
267 RCSResourceAttributes
270 std::vector< double >
272 std::vector< std::string >
273 std::vector< RCSResourceAttributes >
275 std::vector< std::vector< int > >
276 std::vector< std::vector< std::vector< int > > >
278 std::vector< std::vector< double > >
279 std::vector< std::vector< std::vector< double > > >
281 std::vector< std::vector< bool > >
282 std::vector< std::vector< std::vector< bool > > >
284 std::vector< std::vector< std::string > >
285 std::vector< std::vector< std::vector< std::string > > >
287 std::vector< std::vector< RCSResourceAttributes > >
288 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
291 * @see RCSResourceAttributes
293 * @see is_supported_type
298 class ComparisonHelper;
302 Value(Value&&) BOOST_NOEXCEPT;
305 * Constructs a Value if T is a supported type.<br/>
306 * Otherwise it won't compile.
308 template< typename T, typename = typename enable_if_supported< T >::type >
310 m_data{ new ValueVariant{ std::forward< T >(value) } }
316 Value& operator=(const Value&);
317 Value& operator=(Value&&);
319 template< typename T, typename = typename enable_if_supported< T >::type >
320 Value& operator=(T&& rhs)
322 *m_data = std::forward< T >(rhs);
326 Value& operator=(const char*);
327 Value& operator=(std::nullptr_t);
330 * Returns the underlying value as T.
332 * @return const reference to the underlying value.
334 * @throws BadGetException If type of the underlying value is not T.
336 template< typename T >
337 typename std::add_lvalue_reference< const T >::type get() const
339 return checkedGet< T >();
343 * Returns the underlying value as T.
345 * @return reference to the underlying value.
347 * @throws BadGetException If type of the underlying value is not T.
349 template< typename T >
350 typename std::add_lvalue_reference< T >::type get()
352 return checkedGet< T >();
356 * Returns Type information.
360 Type getType() const;
363 * Returns a string representation.
366 std::string toString() const;
369 * Exchanges the content of the object by the content of the parameter.
371 void swap(Value&) BOOST_NOEXCEPT;
374 friend class RCSResourceAttributes;
378 template< typename T, typename = typename enable_if_supported< T >::type >
379 typename std::add_lvalue_reference< T >::type checkedGet() const
383 return boost::get< T >(*m_data);
385 catch (const boost::bad_get&)
387 throw RCSBadGetException{ "Wrong type" };
391 template< typename T, typename U >
392 bool equals(const U& rhs) const
396 return get< T >() == rhs;
398 catch (const RCSBadGetException&)
405 boost::scoped_ptr< ValueVariant > m_data;
410 class const_iterator;
413 RCSResourceAttributes() = default;
414 RCSResourceAttributes(const RCSResourceAttributes&) = default;
415 RCSResourceAttributes(RCSResourceAttributes&&) = default;
417 RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
418 RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
421 * Returns an {@link iterator} referring to the first element.
423 iterator begin() BOOST_NOEXCEPT;
426 * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
428 iterator end() BOOST_NOEXCEPT;
433 const_iterator begin() const BOOST_NOEXCEPT;
438 const_iterator end() const BOOST_NOEXCEPT;
441 * Returns a const_iterator referring to the first element.
443 const_iterator cbegin() const BOOST_NOEXCEPT;
446 * Returns a const_iterator referring to the <i>past-the-end element</i>.
448 const_iterator cend() const BOOST_NOEXCEPT;
453 * If @a key matches the key of a value,
454 * returns a reference to its mapped value. <br/>
455 * If @a key doesn't match the key of any value,
456 * inserts a new value with that key and returns a reference to it.
457 * The element is a Value that has null.
459 * @param key Key of the element whose mapped value is accessed.
461 * @return A reference to the mapped value with @a key.
465 Value& operator[](const std::string& key);
470 * If @a key matches the key of a value,
471 * returns a reference to its mapped value. <br/>
472 * If @a key doesn't match the key of any value,
473 * inserts a new value with that key and returns a reference to it.
474 * The value has null.
476 * @param key Key of the element whose mapped value is accessed.
477 * This is moved instead of copied when a new value is inserted.
479 * @return A reference to the mapped value with @a key.
483 Value& operator[](std::string&& key);
488 * If @a key matches the key of a value,
489 * returns a reference to its mapped value. <br/>
490 * If @a key doesn't match the key of any value, throws InvalidKeyException.
492 * @param key Key of the element whose mapped value is accessed.
494 * @throws InvalidKeyException If @a key doesn't match the key of any value.
496 * @return A reference to the mapped value with @a key.
500 Value& at(const std::string& key);
505 * If @a key matches the key of a value,
506 * returns a reference to its mapped value. <br/>
507 * If @a key doesn't match the key of any value, throws InvalidKeyException.
509 * @param key Key of the element whose mapped value is accessed.
511 * @throws InvalidKeyException If @a key doesn't match the key of any value.
513 * @return A const reference to the mapped value with @a key.
517 const Value& at(const std::string& key) const;
520 * Removes all elements.
522 void clear() BOOST_NOEXCEPT;
525 * Removes a single element.
527 * @param key Key of the element to be removed.
529 * @return true if an element is erased, false otherwise.
531 bool erase(const std::string& key);
534 * Removes a single element.
536 * @param pos Iterator to the element to remove.
538 * @return Iterator following the last removed element.
540 iterator erase(const_iterator pos);
543 * Checks this contains an element for the specified key.
545 * @param key Key to check.
547 * @return true if an element exists, false otherwise.
549 bool contains(const std::string& key) const;
552 * Returns whether it is empty.
556 bool empty() const BOOST_NOEXCEPT;
559 * Returns the number of elements.
563 size_t size() const BOOST_NOEXCEPT;
566 template< typename VISITOR >
567 void visit(VISITOR& visitor) const
569 KeyValueVisitorHelper< VISITOR > helper{ visitor };
571 for (const auto& i : m_values)
573 boost::variant< const std::string& > key{ i.first };
574 boost::apply_visitor(helper, key, *i.second.m_data);
578 template< typename VISITOR >
579 void visitToMove(VISITOR& visitor)
581 KeyValueVisitorHelper< VISITOR, std::true_type > helper{ visitor };
583 for (auto& i : m_values)
585 boost::variant< const std::string& > key{ i.first };
586 boost::apply_visitor(helper, key, *i.second.m_data);
591 std::unordered_map< std::string, Value > m_values;
594 friend class ResourceAttributesConverter;
596 friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
601 * A helper class to avoid obscure comparisons of values which are supported
602 * by RCSResourceAttributes::Value caused by implicitly converting a value
603 * to a RCSResourceAttributes::Value.
606 * @see RCSResourceAttributes
607 * @see is_supported_type
609 class RCSResourceAttributes::Value::ComparisonHelper
612 ComparisonHelper(const Value&);
614 ComparisonHelper(const ComparisonHelper&) = delete;
615 ComparisonHelper& operator=(const ComparisonHelper&) = delete;
617 template< typename T >
618 typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
621 return m_valueRef.equals< T >(v);
624 bool equals(const std::string& v) const
626 return m_valueRef.equals< std::string >(v);
629 bool operator==(const ComparisonHelper&) const;
632 const Value& m_valueRef;
636 template< typename T >
637 struct RCSResourceAttributes::IsSupportedTypeHelper
639 typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
642 template < typename T >
643 struct RCSResourceAttributes::IndexOfType
645 static_assert(RCSResourceAttributes::is_supported_type< T >::value,
646 "The type is not supported!");
648 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
649 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
651 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
654 template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
658 * @relates RCSResourceAttributes::Type
660 * Checks if the objects are equal, that is, whether types are exactly same.
662 * @return true if the objects are equal, false otherwise.
664 bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
668 * @relates RCSResourceAttributes::Type
670 * Checks if the objects are not equal, that is, whether types are not exactly same.
672 * @return true if the objects are not equal, false otherwise.
674 bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
678 * @relates RCSResourceAttributes::Value
680 * Checks if the contents are equal, that is,
681 * whether types are matched and underlying values are equal.
683 * @return true if the contents are equal, false otherwise.
685 bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
686 const RCSResourceAttributes::Value::ComparisonHelper&);
689 * @relates RCSResourceAttributes::Value
691 * Checks if the contents are not equal, that is,
692 * whether types are not matched or underlying values are not equal.
694 * @return true if the contents are not equal, false otherwise.
696 bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
697 const RCSResourceAttributes::Value::ComparisonHelper&);
700 template< typename T >
701 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
702 std::is_constructible< std::string, T >::value, bool >::type
703 operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
705 return lhs.equals(rhs);
708 template< typename T >
709 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
710 std::is_constructible< std::string, T >::value, bool >::type
711 operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
716 template< typename T >
717 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
718 std::is_constructible< std::string, T >::value, bool >::type
719 operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
721 return !(lhs == rhs);
724 template< typename T >
725 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
726 std::is_constructible< std::string, T >::value, bool >::type
727 operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
729 return !(rhs == lhs);
734 * @relates RCSResourceAttributes
736 * Checks if the attributes are equal, that is, whether contents are equal.
738 * @return true if the attributes are equal, false otherwise.
740 bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
743 * @relates RCSResourceAttributes
745 * Checks if the attributes are not equal, that is, whether contents are not equal.
747 * @return true if the attributes are not equal, false otherwise.
749 bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
752 * KeyValuePair is a class to access attribute's key and value of an element pointed by
753 * iterators of RCSResourceAttributes.
756 * @see RCSResourceAttributes
758 * @see const_iterator
760 class RCSResourceAttributes::KeyValuePair
763 class KeyVisitor: public boost::static_visitor< const std::string& >
766 result_type operator()(iterator*) const BOOST_NOEXCEPT;
767 result_type operator()(const_iterator*) const BOOST_NOEXCEPT;
770 class ValueVisitor: public boost::static_visitor< Value& >
773 result_type operator()(iterator*) BOOST_NOEXCEPT;
774 result_type operator()(const_iterator*);
777 class ConstValueVisitor: public boost::static_visitor< const Value& >
780 result_type operator()(iterator*) const BOOST_NOEXCEPT;
781 result_type operator()(const_iterator*) const BOOST_NOEXCEPT;
785 const std::string& key() const BOOST_NOEXCEPT;
786 const RCSResourceAttributes::Value& value() const BOOST_NOEXCEPT;
787 RCSResourceAttributes::Value& value();
790 KeyValuePair(const KeyValuePair&) = default;
791 KeyValuePair(boost::variant< iterator*, const_iterator* >&&) BOOST_NOEXCEPT;
793 KeyValuePair& operator=(const KeyValuePair&) = default;
796 boost::variant< iterator*, const_iterator* > m_iterRef;
798 KeyVisitor m_keyVisitor;
799 ValueVisitor m_valueVisitor;
800 ConstValueVisitor m_constValueVisitor;
803 friend class iterator;
804 friend class const_iterator;
809 * A forward iterator to KeyValuePair.
811 * @see RCSResourceAttributes
813 * @see const_iterator
815 class RCSResourceAttributes::iterator:
816 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
819 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
823 iterator(const iterator&);
825 iterator& operator=(const iterator&);
827 reference operator*();
828 pointer operator->();
830 iterator& operator++();
831 iterator operator++(int);
833 bool operator==(const iterator&) const;
834 bool operator!=(const iterator&) const;
837 explicit iterator(base_iterator&&);
841 RCSResourceAttributes::KeyValuePair m_keyValuePair;
844 friend class RCSResourceAttributes;
850 * A forward iterator to const KeyValuePair.
852 * @see RCSResourceAttributes
856 class RCSResourceAttributes::const_iterator:
857 public std::iterator< std::forward_iterator_tag,
858 const RCSResourceAttributes::KeyValuePair >
861 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
865 const_iterator(const const_iterator&);
866 const_iterator(const RCSResourceAttributes::iterator&);
868 const_iterator& operator=(const const_iterator&);
869 const_iterator& operator=(const RCSResourceAttributes::iterator&);
871 reference operator*() const;
872 pointer operator->() const;
874 const_iterator& operator++();
875 const_iterator operator++(int);
877 bool operator==(const const_iterator&) const;
878 bool operator!=(const const_iterator&) const;
881 explicit const_iterator(base_iterator&&);
885 RCSResourceAttributes::KeyValuePair m_keyValuePair;
888 friend class RCSResourceAttributes;
895 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H