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>
38 #include <boost/variant.hpp>
39 #include <boost/mpl/contains.hpp>
40 #include <boost/mpl/find.hpp>
41 #include <boost/mpl/distance.hpp>
42 #include <boost/mpl/begin_end.hpp>
43 #include <boost/scoped_ptr.hpp>
45 #include <RCSException.h>
53 * RCSResourceAttributes represents the attributes for a resource.
55 * It provides similar usage to c++ standard containers. (iterator,
56 * operators and accessors)<br/>
57 * An attribute value can be one of various types. <br/>
59 * @note If client developer wants to get the RCSResourceAttributes for the resource of
60 * interest following are the steps:
61 * - first call the discover API of DiscoveryManager class.
62 * - After getting the RemoteResourceObject, call getRemoteAttributes() API
63 * of RemoteResourceObject class
69 * @see RCSDiscoveryManager
70 * @see RCSRemoteResourceObject
71 * @see RCSResourceObject
73 class RCSResourceAttributes
76 template< typename T > struct IsSupportedTypeHelper;
78 typedef boost::variant<
87 template< typename T, typename V = void,
88 typename = typename std::enable_if<
89 IsSupportedTypeHelper< T >::type::value, V >::type >
90 struct enable_if_supported
95 template< typename VISITOR >
96 class KeyValueVisitorHelper: public boost::static_visitor< >
99 KeyValueVisitorHelper(VISITOR& visitor) :
104 template< typename T >
105 void operator()(const std::string& key, const T& value) const
107 m_visitor(key, value);
114 template <typename T> struct IndexOfType;
119 * Trait class that identifies whether T is supported by the Value.
121 template< typename T >
122 struct is_supported_type: public std::conditional<
123 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
126 * Identifier for types of Value.
132 NULL_T, /**< nullptr_t */
134 DOUBLE, /**< double */
136 STRING, /**< std::string */
137 ATTRIBUTES, /**< RCSResourceAttributes */
138 VECTOR /**< std::vector */
142 * A Helper class to identify types of Value.
144 * @see RCSResourceAttributes
151 Type(const Type&) = default;
152 Type(Type&&) = default;
154 Type& operator=(const Type&) = default;
155 Type& operator=(Type&&) = default;
158 * Returns type identifier.
160 * @return Identifier of type.
162 TypeId getId() const;
165 * Factory method to create Type instance from T.
167 * @return An instance that has TypeId for T.
169 * @note T must be supported by Value. Otherwise, it won't be compiled.
171 * @see is_supported_type
173 template < typename T >
174 static Type typeOf(const T& value)
180 friend bool operator==(const Type&, const Type&);
184 template < typename T >
185 explicit Type(const T&) :
186 m_which{ IndexOfType< T >::value }
195 * Value holds a value among various types at a time.
197 * Type helps identify type information of Value.
199 * @see RCSResourceAttributes
201 * @see is_supported_type
206 class ComparisonHelper;
213 * Constructs a Value if T is a supported type.<br/>
214 * Otherwise it won't be compiled.
216 template< typename T, typename = typename enable_if_supported< T >::type >
218 m_data{ new ValueVariant{ std::forward< T >(value) } }
222 Value(const char* value);
224 Value& operator=(const Value&);
225 Value& operator=(Value&&);
227 template< typename T, typename = typename enable_if_supported< T >::type >
228 Value& operator=(T&& rhs)
230 *m_data = std::forward< T >(rhs);
234 Value& operator=(const char*);
235 Value& operator=(std::nullptr_t);
238 * Returns the underlying value as T.
240 * @return const reference to the underlying value.
242 * @throws BadGetException If type of the underlying value is not T.
244 template< typename T >
245 typename std::add_lvalue_reference< const T >::type get() const
247 return checkedGet< T >();
251 * Returns the underlying value as T.
253 * @return reference to the underlying value.
255 * @throws BadGetException If type of the underlying value is not T.
257 template< typename T >
258 typename std::add_lvalue_reference< T >::type get()
260 return checkedGet< T >();
264 * Returns Type information.
268 Type getType() const;
271 * Returns a string representation.
274 std::string toString() const;
277 * Exchanges the content of the object by the content of the parameter.
282 friend class RCSResourceAttributes;
286 template< typename T, typename = typename enable_if_supported< T >::type >
287 typename std::add_lvalue_reference< T >::type checkedGet() const
291 return boost::get< T >(*m_data);
293 catch (const boost::bad_get&)
295 throw BadGetException{ "Wrong type" };
299 template< typename T, typename U >
300 bool equals(const U& rhs) const
304 return get< T >() == rhs;
306 catch (const BadGetException&)
313 boost::scoped_ptr< ValueVariant > m_data;
318 class const_iterator;
321 RCSResourceAttributes() = default;
322 RCSResourceAttributes(const RCSResourceAttributes&) = default;
323 RCSResourceAttributes(RCSResourceAttributes&&) = default;
325 RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
326 RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
329 * Returns an {@link iterator} referring to the first element.
334 * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
341 const_iterator begin() const;
346 const_iterator end() const;
349 * Returns a const_iterator referring to the first element.
351 const_iterator cbegin() const;
354 * Returns a const_iterator referring to the <i>past-the-end element</i>.
356 const_iterator cend() const;
361 * If @a key matches the key of a value,
362 * returns a reference to its mapped value. <br/>
363 * If @a key doesn't match the key of any value,
364 * inserts a new value with that key and returns a reference to it.
365 * The element is a Value that has null.
367 * @param key Key of the element whose mapped value is accessed.
369 * @return A reference to the mapped value with @a key.
373 Value& operator[](const std::string& key);
378 * If @a key matches the key of a value,
379 * returns a reference to its mapped value. <br/>
380 * If @a key doesn't match the key of any value,
381 * inserts a new value with that key and returns a reference to it.
382 * The value has null.
384 * @param key Key of the element whose mapped value is accessed.
385 * This is moved instead of copied when a new value is inserted.
387 * @return A reference to the mapped value with @a key.
391 Value& operator[](std::string&& key);
396 * If @a key matches the key of a value,
397 * returns a reference to its mapped value. <br/>
398 * If @a key doesn't match the key of any value, throws InvalidKeyException.
400 * @param key Key of the element whose mapped value is accessed.
402 * @throws InvalidKeyException If @a key doesn't match the key of any value.
404 * @return A reference to the mapped value with @a key.
408 Value& at(const std::string& key);
413 * If @a key matches the key of a value,
414 * returns a reference to its mapped value. <br/>
415 * If @a key doesn't match the key of any value, throws InvalidKeyException.
417 * @param key Key of the element whose mapped value is accessed.
419 * @throws InvalidKeyException If @a key doesn't match the key of any value.
421 * @return A const reference to the mapped value with @a key.
425 const Value& at(const std::string& key) const;
428 * Removes all elements.
433 * Removes a single element.
435 * @param key Key of the element to be removed.
437 * @return true if an element is erased, false otherwise.
439 bool erase(const std::string& key);
442 * Checks the container has an element with a Key equivalent to key.
444 * @param key Key to check.
446 * @return true if an element exists, false otherwise.
448 bool contains(const std::string& key) const;
451 * Returns whether it is empty.
458 * Returns the number of elements.
465 template< typename VISITOR >
466 void visit(VISITOR& visitor) const
468 KeyValueVisitorHelper< VISITOR > helper{ visitor };
470 for (const auto& i : m_values)
472 boost::variant< const std::string& > key{ i.first };
473 boost::apply_visitor(helper, key, *i.second.m_data);
478 std::unordered_map< std::string, Value > m_values;
481 friend class ResourceAttributesConverter;
483 friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
488 * A helper class to avoid obscure comparisons of values which are supported
489 * by RCSResourceAttributes::Value caused by implicitly converting a value
490 * to a RCSResourceAttributes::Value.
493 * @see RCSResourceAttributes
494 * @see is_supported_type
496 class RCSResourceAttributes::Value::ComparisonHelper
499 ComparisonHelper(const Value&);
501 template< typename T >
502 typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
505 return m_valueRef.equals< T >(v);
508 bool equals(const std::string& v) const
510 return m_valueRef.equals< std::string >(v);
513 bool operator==(const ComparisonHelper&) const;
516 const Value& m_valueRef;
519 template< typename T >
520 struct RCSResourceAttributes::IsSupportedTypeHelper
522 typedef boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type> type;
525 template <typename T>
526 struct RCSResourceAttributes::IndexOfType
528 typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
529 typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
531 static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
535 * @relates RCSResourceAttributes::Type
537 * Checks if the objects are equal, that is, whether types are exactly same.
539 * @return true if the objects are equal, false otherwise.
541 bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
544 * @relates RCSResourceAttributes::Type
546 * Checks if the objects are not equal, that is, whether types are not exactly same.
548 * @return true if the objects are not equal, false otherwise.
550 bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
553 * @relates RCSResourceAttributes::Value
555 * Checks if the contents are equal, that is,
556 * whether types are matched and underlying values are equal.
558 * @return true if the contents are equal, false otherwise.
560 bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
561 const RCSResourceAttributes::Value::ComparisonHelper&);
564 * @relates RCSResourceAttributes::Value
566 * Checks if the contents are not equal, that is,
567 * whether types are not matched or underlying values are not equal.
569 * @return true if the contents are not equal, false otherwise.
571 bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
572 const RCSResourceAttributes::Value::ComparisonHelper&);
575 template< typename T >
576 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
577 std::is_constructible< std::string, T >::value, bool >::type
578 operator==(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
580 return lhs.equals(rhs);
583 template< typename T >
584 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
585 std::is_constructible< std::string, T >::value, bool >::type
586 operator==(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
591 template< typename T >
592 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
593 std::is_constructible< std::string, T >::value, bool >::type
594 operator!=(const RCSResourceAttributes::Value::ComparisonHelper& lhs, const T& rhs)
596 return !(lhs == rhs);
599 template< typename T >
600 typename std::enable_if< RCSResourceAttributes::is_supported_type< T >::value ||
601 std::is_constructible< std::string, T >::value, bool >::type
602 operator!=(const T& lhs, const RCSResourceAttributes::Value::ComparisonHelper& rhs)
604 return !(rhs == lhs);
609 * @relates RCSResourceAttributes
611 * Checks if the attributes are equal, that is, whether contents are equal.
613 * @return true if the attributes are equal, false otherwise.
615 bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
618 * @relates RCSResourceAttributes
620 * Checks if the attributes are not equal, that is, whether contents are not equal.
622 * @return true if the attributes are not equal, false otherwise.
624 bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
627 * KeyValuePair is a class to access attribute's key and value of an element pointed by
628 * iterators of RCSResourceAttributes.
631 * @see RCSResourceAttributes
633 * @see const_iterator
635 class RCSResourceAttributes::KeyValuePair
638 class KeyVisitor: public boost::static_visitor< const std::string& >
641 result_type operator()(iterator*) const;
642 result_type operator()(const_iterator*) const;
645 class ValueVisitor: public boost::static_visitor< Value& >
648 result_type operator()(iterator*);
649 result_type operator()(const_iterator*);
652 class ConstValueVisitor: public boost::static_visitor< const Value& >
655 result_type operator()(iterator*) const;
656 result_type operator()(const_iterator*) const;
660 const std::string& key() const;
661 const RCSResourceAttributes::Value& value() const;
662 RCSResourceAttributes::Value& value();
665 KeyValuePair(const KeyValuePair&) = default;
666 KeyValuePair(boost::variant< iterator*, const_iterator* >&&);
668 KeyValuePair& operator=(const KeyValuePair&) = default;
671 boost::variant< iterator*, const_iterator* > m_iterRef;
673 KeyVisitor m_keyVisitor;
674 ValueVisitor m_valueVisitor;
675 ConstValueVisitor m_constValueVisitor;
678 friend class iterator;
679 friend class const_iterator;
684 * A forward iterator to KeyValuePair.
686 * @see RCSResourceAttributes
688 * @see const_iterator
690 class RCSResourceAttributes::iterator:
691 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
694 typedef std::unordered_map< std::string, Value >::iterator base_iterator;
698 iterator(const iterator&) = default;
700 iterator& operator=(const iterator&) = default;
702 reference operator*();
703 pointer operator->();
705 iterator& operator++();
706 iterator operator++(int);
708 bool operator==(const iterator&) const;
709 bool operator!=(const iterator&) const;
712 explicit iterator(base_iterator&&);
716 RCSResourceAttributes::KeyValuePair m_keyValuePair;
719 friend class RCSResourceAttributes;
725 * A forward iterator to const KeyValuePair.
727 * @see RCSResourceAttributes
731 class RCSResourceAttributes::const_iterator:
732 public std::iterator < std::forward_iterator_tag,
733 const RCSResourceAttributes::KeyValuePair >
736 typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
740 const_iterator(const const_iterator&) = default;
741 const_iterator(const RCSResourceAttributes::iterator&);
743 const_iterator& operator=(const const_iterator&) = default;
744 const_iterator& operator=(const RCSResourceAttributes::iterator&);
746 reference operator*() const;
747 pointer operator->() const;
749 const_iterator& operator++();
750 const_iterator operator++(int);
752 bool operator==(const const_iterator&) const;
753 bool operator!=(const const_iterator&) const;
756 explicit const_iterator(base_iterator&&);
760 RCSResourceAttributes::KeyValuePair m_keyValuePair;
763 friend class RCSResourceAttributes;
770 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H