645c228bf8ed8c222fc3c05ab949514b94aff7b5
[platform/upstream/iotivity.git] / service / resource-encapsulation / include / RCSResourceAttributes.h
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 /**
22  * @file
23  *
24  * This file contains the declaration of classes and its members related to RCSResourceAttributes
25  */
26 #ifndef RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
27 #define RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
28
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
34
35 #include <functional>
36 #include <unordered_map>
37 #include <vector>
38
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"
45
46 #include "RCSException.h"
47
48 namespace OIC
49 {
50     namespace Service
51     {
52
53         /**
54         * This represents the attributes for a resource.
55         *
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/>
59         *
60         *
61         * @see Value
62         * @see Type
63         * @see iterator
64         * @see const_iterator
65         * @see RCSDiscoveryManager
66         * @see RCSRemoteResourceObject
67         * @see RCSResourceObject
68         */
69         class RCSResourceAttributes
70         {
71         private:
72             template< typename T > struct IsSupportedTypeHelper;
73
74             typedef boost::variant<
75                 std::nullptr_t,
76                 int,
77                 double,
78                 bool,
79                 std::string,
80                 RCSResourceAttributes,
81
82                 std::vector< int >,
83                 std::vector< double >,
84                 std::vector< bool >,
85                 std::vector< std::string >,
86                 std::vector< RCSResourceAttributes >,
87
88                 std::vector< std::vector< int > >,
89                 std::vector< std::vector< std::vector< int > > >,
90
91                 std::vector< std::vector< double > >,
92                 std::vector< std::vector< std::vector< double > > >,
93
94                 std::vector< std::vector< bool > >,
95                 std::vector< std::vector< std::vector< bool > > >,
96
97                 std::vector< std::vector< std::string > >,
98                 std::vector< std::vector< std::vector< std::string > > >,
99
100                 std::vector< std::vector< RCSResourceAttributes > >,
101                 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
102             > ValueVariant;
103
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
108             {
109                 typedef V type;
110             };
111
112             template< typename VISITOR >
113             class KeyValueVisitorHelper: public boost::static_visitor< >
114             {
115             public:
116                 KeyValueVisitorHelper(VISITOR& visitor) noexcept :
117                         m_visitor( visitor )
118                 {
119                 }
120
121                 template< typename T >
122                 void operator()(const std::string& key, const T& value) const
123                 {
124                     m_visitor(key, value);
125                 }
126
127             private:
128                 VISITOR& m_visitor;
129             };
130
131             template <typename T> struct IndexOfType;
132
133         public:
134
135             /**
136              * Trait class that identifies whether T is supported by the Value.
137              */
138             template< typename T >
139             struct is_supported_type: public std::conditional<
140                 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
141
142             /**
143              * Identifiers for types of Value.
144              *
145              * @see Type
146              */
147             enum class TypeId
148             {
149                 NULL_T, /**< nullptr_t */
150                 INT, /**< int */
151                 DOUBLE, /**< double */
152                 BOOL, /**< bool */
153                 STRING, /**< std::string */
154                 ATTRIBUTES, /**< RCSResourceAttributes */
155                 VECTOR /**< std::vector */
156             };
157
158             /**
159              * A Helper class to identify types of Value.
160              *
161              * @see RCSResourceAttributes
162              * @see Value
163              * @see TypeId
164              */
165             class Type
166             {
167             public:
168                 Type(const Type&) = default;
169                 Type(Type&&) = default;
170
171                 Type& operator=(const Type&) = default;
172                 Type& operator=(Type&&) = default;
173
174                 /**
175                  * Returns type identifier.
176                  *
177                  * @return Identifier of type.
178                  *
179                  * @see getBaseTypeId
180                  */
181                 TypeId getId() const noexcept;
182
183                 /**
184                  * Returns the type identifier of a base type of sequence.
185                  *
186                  * For non sequence types, it is equivalent to calling getId.
187                  *
188                  * @return Identifier of type.
189                  *
190                  * @see getDepth
191                  * @see getId
192                  */
193                 static TypeId getBaseTypeId(const Type& t) noexcept;
194
195                 /**
196                  * Returns the depth of a type.
197                  *
198                  * The return will be zero for non sequence types.
199                  *
200                  * @see getBaseTypeId
201                  */
202                 static size_t getDepth(const Type& t) noexcept;
203
204                 /**
205                  * Factory method to create Type instance from T.
206                  *
207                  * @return An instance that has TypeId for T.
208                  *
209                  * @note T must be supported by Value. Otherwise, it won't compile.
210                  *
211                  * @see is_supported_type
212                  */
213                 template < typename T >
214                 constexpr static Type typeOf(const T&) noexcept
215                 {
216                     return Type{ IndexOfType< T >::value };
217                 }
218
219                 /**
220                  * Factory method to create Type instance from T.
221                  *
222                  * @return An instance that has TypeId for T.
223                  *
224                  * @note T must be supported by Value. Otherwise, it won't compile.
225                  *
226                  * @see is_supported_type
227                  */
228                 template < typename T >
229                 constexpr static Type typeOf() noexcept
230                 {
231                     return Type{ IndexOfType< T >::value };
232                 }
233
234                 //! @cond
235                 friend bool operator==(const Type&, const Type&) noexcept;
236                 //! @endcond
237
238             private:
239                 constexpr explicit Type(int which) noexcept :
240                     m_which{ which }
241                 {
242                 }
243
244             private:
245                 int m_which;
246             };
247
248             /**
249              * Value holds a value among various types at a time.
250              *
251              * Type helps identify type information of Value.
252              *
253              * Supported types are below
254              * @code
255                 int
256                 double
257                 bool
258                 std::string
259                 RCSResourceAttributes
260
261                 std::vector< int >
262                 std::vector< double >
263                 std::vector< bool >
264                 std::vector< std::string >
265                 std::vector< RCSResourceAttributes >
266
267                 std::vector< std::vector< int > >
268                 std::vector< std::vector< std::vector< int > > >
269
270                 std::vector< std::vector< double > >
271                 std::vector< std::vector< std::vector< double > > >
272
273                 std::vector< std::vector< bool > >
274                 std::vector< std::vector< std::vector< bool > > >
275
276                 std::vector< std::vector< std::string > >
277                 std::vector< std::vector< std::vector< std::string > > >
278
279                 std::vector< std::vector< RCSResourceAttributes > >
280                 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
281              * @endcode
282              *
283              * @see RCSResourceAttributes
284              * @see Type
285              * @see is_supported_type
286              */
287             class Value
288             {
289             public:
290                 class ComparisonHelper;
291
292                 Value();
293                 Value(const Value&);
294                 Value(Value&&) noexcept;
295
296                 /**
297                  * Constructs a Value if T is a supported type.<br/>
298                  *       Otherwise it won't compile.
299                  */
300                 template< typename T, typename = typename enable_if_supported< T >::type >
301                 Value(T&& value) :
302                         m_data{ new ValueVariant{ std::forward< T >(value) } }
303                 {
304                 }
305
306                 Value(const char*);
307
308                 Value& operator=(const Value&);
309                 Value& operator=(Value&&);
310
311                 template< typename T, typename = typename enable_if_supported< T >::type >
312                 Value& operator=(T&& rhs)
313                 {
314                     *m_data = std::forward< T >(rhs);
315                     return *this;
316                 }
317
318                 Value& operator=(const char*);
319                 Value& operator=(std::nullptr_t);
320
321                 /**
322                  * Returns the underlying value as T.
323                  *
324                  * @return const reference to the underlying value.
325                  *
326                  * @throws BadGetException If type of the underlying value is not T.
327                  */
328                 template< typename T >
329                 typename std::add_lvalue_reference< const T >::type get() const
330                 {
331                     return checkedGet< T >();
332                 }
333
334                 /**
335                  * Returns the underlying value as T.
336                  *
337                  * @return reference to the underlying value.
338                  *
339                  * @throws BadGetException If type of the underlying value is not T.
340                  */
341                 template< typename T >
342                 typename std::add_lvalue_reference< T >::type get()
343                 {
344                     return checkedGet< T >();
345                 }
346
347                 /**
348                  * Returns Type information.
349                  *
350                  * @see Type
351                  */
352                 Type getType() const;
353
354                 /**
355                  * Returns a string representation.
356                  *
357                  */
358                 std::string toString() const;
359
360                 /**
361                  * Exchanges the content of the object by the content of the parameter.
362                  */
363                 void swap(Value&) noexcept;
364
365                 //! @cond
366                 friend class RCSResourceAttributes;
367                 //! @endcond
368
369             private:
370                 template< typename T, typename = typename enable_if_supported< T >::type >
371                 typename std::add_lvalue_reference< T >::type checkedGet() const
372                 {
373                     try
374                     {
375                         return boost::get< T >(*m_data);
376                     }
377                     catch (const boost::bad_get&)
378                     {
379                         throw RCSBadGetException{ "Wrong type" };
380                     }
381                 }
382
383                 template< typename T, typename U >
384                 bool equals(const U& rhs) const
385                 {
386                     try
387                     {
388                         return get< T >() == rhs;
389                     }
390                     catch (const RCSBadGetException&)
391                     {
392                         return false;
393                     }
394                 }
395
396             private:
397                 boost::scoped_ptr< ValueVariant > m_data;
398             };
399
400             class KeyValuePair;
401             class iterator;
402             class const_iterator;
403
404         public:
405             RCSResourceAttributes() = default;
406             RCSResourceAttributes(const RCSResourceAttributes&) = default;
407             RCSResourceAttributes(RCSResourceAttributes&&) = default;
408
409             RCSResourceAttributes& operator=(const RCSResourceAttributes&) = default;
410             RCSResourceAttributes& operator=(RCSResourceAttributes&&) = default;
411
412             /**
413              * Returns an {@link iterator} referring to the first element.
414              */
415             iterator begin() noexcept;
416
417             /**
418              * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
419              */
420             iterator end() noexcept;
421
422             /**
423              * @copydoc cbegin()
424              */
425             const_iterator begin() const noexcept;
426
427             /**
428              * @copydoc cend()
429              */
430             const_iterator end() const noexcept;
431
432             /**
433              * Returns a const_iterator referring to the first element.
434              */
435             const_iterator cbegin() const noexcept;
436
437             /**
438              * Returns a const_iterator referring to the <i>past-the-end element</i>.
439              */
440             const_iterator cend() const noexcept;
441
442             /**
443              * Accesses a value.
444              *
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.
450              *
451              * @param key Key of the element whose mapped value is accessed.
452              *
453              * @return A reference to the mapped value with @a key.
454              *
455              * @see at
456              */
457             Value& operator[](const std::string& key);
458
459             /**
460              * Accesses a value.
461              *
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.
467              *
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.
470              *
471              * @return A reference to the mapped value with @a key.
472              *
473              * @see at
474              */
475             Value& operator[](std::string&& key);
476
477             /**
478              * Accesses a value.
479              *
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.
483              *
484              * @param key Key of the element whose mapped value is accessed.
485              *
486              * @throws InvalidKeyException If @a key doesn't match the key of any value.
487              *
488              * @return A reference to the mapped value with @a key.
489              *
490              * @see operator[]
491              */
492             Value& at(const std::string& key);
493
494             /**
495               * Accesses a value.
496               *
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.
500               *
501               * @param key Key of the element whose mapped value is accessed.
502               *
503               * @throws InvalidKeyException If @a key doesn't match the key of any value.
504               *
505               * @return A const reference to the mapped value with @a key.
506               *
507               * @see operator[]
508               */
509             const Value& at(const std::string& key) const;
510
511             /**
512              * Removes all elements.
513              */
514             void clear() noexcept;
515
516             /**
517              * Removes a single element.
518              *
519              * @param key Key of the element to be removed.
520              *
521              * @return true if an element is erased, false otherwise.
522              */
523             bool erase(const std::string& key);
524
525             /**
526              * Checks this contains an element for the specified key.
527              *
528              * @param key Key to check.
529              *
530              * @return true if an element exists, false otherwise.
531              */
532             bool contains(const std::string& key) const;
533
534             /**
535              * Returns whether it is empty.
536              *
537              * @see size
538              */
539             bool empty() const noexcept;
540
541             /**
542              * Returns the number of elements.
543              *
544              * @see empty
545              */
546             size_t size() const noexcept;
547
548         private:
549             template< typename VISITOR >
550             void visit(VISITOR& visitor) const
551             {
552                 KeyValueVisitorHelper< VISITOR > helper{ visitor };
553
554                 for (const auto& i : m_values)
555                 {
556                     boost::variant< const std::string& > key{ i.first };
557                     boost::apply_visitor(helper, key, *i.second.m_data);
558                 }
559             }
560
561         private:
562             std::unordered_map< std::string, Value > m_values;
563
564             //! @cond
565             friend class ResourceAttributesConverter;
566
567             friend bool operator==(const RCSResourceAttributes&, const RCSResourceAttributes&);
568             //! @endcond
569         };
570
571         /**
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.
575          *
576          * @see Value
577          * @see RCSResourceAttributes
578          * @see is_supported_type
579          */
580         class RCSResourceAttributes::Value::ComparisonHelper
581         {
582         public:
583             ComparisonHelper(const Value&);
584
585             ComparisonHelper(const ComparisonHelper&) = delete;
586             ComparisonHelper& operator=(const ComparisonHelper&) = delete;
587
588             template< typename T >
589             typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
590                     const T& v) const
591             {
592                 return m_valueRef.equals< T >(v);
593             }
594
595             bool equals(const std::string& v) const
596             {
597                 return m_valueRef.equals< std::string >(v);
598             }
599
600             bool operator==(const ComparisonHelper&) const;
601
602         private:
603             const Value& m_valueRef;
604         };
605
606         //! @cond
607         template< typename T >
608         struct RCSResourceAttributes::IsSupportedTypeHelper
609         {
610             typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
611         };
612
613         template < typename T >
614         struct RCSResourceAttributes::IndexOfType
615         {
616             static_assert(RCSResourceAttributes::is_supported_type< T >::value,
617                 "The type is not supported!");
618
619             typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
620             typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
621
622             static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
623         };
624
625         template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
626         //! @endcond
627
628         /**
629          * @relates RCSResourceAttributes::Type
630          *
631          * Checks if the objects are equal, that is, whether types are exactly same.
632          *
633          * @return true if the objects are equal, false otherwise.
634          */
635         bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
636                 noexcept;
637
638         /**
639          * @relates RCSResourceAttributes::Type
640          *
641          * Checks if the objects are not equal, that is, whether types are not exactly same.
642          *
643          * @return true if the objects are not equal, false otherwise.
644          */
645         bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
646                 noexcept;
647
648         /**
649          * @relates RCSResourceAttributes::Value
650          *
651          * Checks if the contents are equal, that is,
652          * whether types are matched and underlying values are equal.
653          *
654          * @return true if the contents are equal, false otherwise.
655          */
656         bool operator==(const RCSResourceAttributes::Value::ComparisonHelper&,
657                 const RCSResourceAttributes::Value::ComparisonHelper&);
658
659         /**
660          * @relates RCSResourceAttributes::Value
661          *
662          * Checks if the contents are not equal, that is,
663          * whether types are not matched or underlying values are not equal.
664          *
665          * @return true if the contents are not equal, false otherwise.
666          */
667         bool operator!=(const RCSResourceAttributes::Value::ComparisonHelper&,
668                 const RCSResourceAttributes::Value::ComparisonHelper&);
669
670         //! @cond
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)
675         {
676             return lhs.equals(rhs);
677         }
678
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)
683         {
684             return rhs == lhs;
685         }
686
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)
691         {
692             return !(lhs == rhs);
693         }
694
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)
699         {
700             return !(rhs == lhs);
701         }
702         //! @endcond
703
704         /**
705           * @relates RCSResourceAttributes
706           *
707           * Checks if the attributes are equal, that is, whether contents are equal.
708           *
709           * @return true if the attributes are equal, false otherwise.
710           */
711         bool operator==(const RCSResourceAttributes& lhs, const RCSResourceAttributes& rhs);
712
713         /**
714           * @relates RCSResourceAttributes
715           *
716           * Checks if the attributes are not equal, that is, whether contents are not equal.
717           *
718           * @return true if the attributes are not equal, false otherwise.
719           */
720         bool operator!=(const RCSResourceAttributes&, const RCSResourceAttributes&);
721
722         /**
723          * KeyValuePair is a class to access attribute's key and value of an element pointed by
724          * iterators of RCSResourceAttributes.
725          *
726          *
727          * @see RCSResourceAttributes
728          * @see iterator
729          * @see const_iterator
730          */
731         class RCSResourceAttributes::KeyValuePair
732         {
733         private:
734             class KeyVisitor: public boost::static_visitor< const std::string& >
735             {
736             public:
737                 result_type operator()(iterator*) const noexcept;
738                 result_type operator()(const_iterator*) const noexcept;
739             };
740
741             class ValueVisitor: public boost::static_visitor< Value& >
742             {
743             public:
744                 result_type operator()(iterator*) noexcept;
745                 result_type operator()(const_iterator*);
746             };
747
748             class ConstValueVisitor: public boost::static_visitor< const Value& >
749             {
750             public:
751                 result_type operator()(iterator*) const noexcept;
752                 result_type operator()(const_iterator*) const noexcept;
753             };
754
755         public:
756             const std::string& key() const noexcept;
757             const RCSResourceAttributes::Value& value() const noexcept;
758             RCSResourceAttributes::Value& value();
759
760         private:
761             KeyValuePair(const KeyValuePair&) = default;
762             KeyValuePair(boost::variant< iterator*, const_iterator* >&&) noexcept;
763
764             KeyValuePair& operator=(const KeyValuePair&) = default;
765
766         private:
767             boost::variant< iterator*, const_iterator* > m_iterRef;
768
769             KeyVisitor m_keyVisitor;
770             ValueVisitor m_valueVisitor;
771             ConstValueVisitor m_constValueVisitor;
772
773             //! @cond
774             friend class iterator;
775             friend class const_iterator;
776             //! @endcond
777         };
778
779         /**
780          * A forward iterator to KeyValuePair.
781          *
782          * @see RCSResourceAttributes
783          * @see KeyValuePair
784          * @see const_iterator
785          */
786         class RCSResourceAttributes::iterator:
787                 public std::iterator< std::forward_iterator_tag, RCSResourceAttributes::KeyValuePair >
788         {
789         private:
790             typedef std::unordered_map< std::string, Value >::iterator base_iterator;
791
792         public:
793             iterator();
794             iterator(const iterator&) = default;
795
796             iterator& operator=(const iterator&) = default;
797
798             reference operator*();
799             pointer operator->();
800
801             iterator& operator++();
802             iterator operator++(int);
803
804             bool operator==(const iterator&) const;
805             bool operator!=(const iterator&) const;
806
807         private:
808             explicit iterator(base_iterator&&);
809
810         private:
811             base_iterator m_cur;
812             RCSResourceAttributes::KeyValuePair m_keyValuePair;
813
814             //! @cond
815             friend class RCSResourceAttributes;
816             //! @endcond
817         };
818
819
820         /**
821          * A forward iterator to const KeyValuePair.
822          *
823          * @see RCSResourceAttributes
824          * @see KeyValuePair
825          * @see iterator
826          */
827         class RCSResourceAttributes::const_iterator:
828                 public std::iterator < std::forward_iterator_tag,
829                                        const RCSResourceAttributes::KeyValuePair >
830         {
831         private:
832             typedef std::unordered_map< std::string, Value >::const_iterator base_iterator;
833
834         public:
835             const_iterator();
836             const_iterator(const const_iterator&) = default;
837             const_iterator(const RCSResourceAttributes::iterator&);
838
839             const_iterator& operator=(const const_iterator&) = default;
840             const_iterator& operator=(const RCSResourceAttributes::iterator&);
841
842             reference operator*() const;
843             pointer operator->() const;
844
845             const_iterator& operator++();
846             const_iterator operator++(int);
847
848             bool operator==(const const_iterator&) const;
849             bool operator!=(const const_iterator&) const;
850
851         private:
852             explicit const_iterator(base_iterator&&);
853
854         private:
855             base_iterator m_cur;
856             RCSResourceAttributes::KeyValuePair m_keyValuePair;
857
858             //! @cond
859             friend class RCSResourceAttributes;
860             //! @endcond
861         };
862
863     }
864 }
865
866 #endif // RES_ENCAPSULATION_RESOURCEATTRIBUTES_H