[dali_1.0.43] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / public-api / object / property-map.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/public-api/object/property-map.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/vector-wrapper.h>
23
24 namespace Dali
25 {
26
27 namespace
28 {
29 typedef std::vector< StringValuePair > Container;
30 }; // unnamed namespace
31
32 struct Property::Map::Impl
33 {
34   Container mContainer;
35 };
36
37 Property::Map::Map()
38 : mImpl( new Impl )
39 {
40 }
41
42 Property::Map::Map( const Property::Map& other )
43 : mImpl( new Impl )
44 {
45   mImpl->mContainer = other.mImpl->mContainer;
46 }
47
48 Property::Map::~Map()
49 {
50   delete mImpl;
51 }
52
53 unsigned int Property::Map::Count() const
54 {
55   return mImpl->mContainer.size();
56 }
57
58 bool Property::Map::Empty() const
59 {
60   return mImpl->mContainer.empty();
61 }
62
63 Property::Value& Property::Map::GetValue( unsigned int position ) const
64 {
65   DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" );
66
67   return mImpl->mContainer[ position ].second;
68 }
69
70 const std::string& Property::Map::GetKey( unsigned int position ) const
71 {
72   DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" );
73
74   return mImpl->mContainer[ position ].first;
75 }
76
77 StringValuePair& Property::Map::GetPair( unsigned int position ) const
78 {
79   DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" );
80
81   return mImpl->mContainer[ position ];
82 }
83
84 Property::Value* Property::Map::Find( const std::string& key ) const
85 {
86   for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter )
87   {
88     if ( iter->first == key )
89     {
90       return &iter->second;
91     }
92   }
93   return NULL; // Not found
94 }
95
96 Property::Value* Property::Map::Find( const std::string& key, Property::Type type ) const
97 {
98   for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter )
99   {
100     // test type first to shortcut eval (possibly reducing string compares)
101     if( (iter->second.GetType() == type) && (iter->first == key) )
102     {
103       return &iter->second;
104     }
105   }
106   return NULL; // Not found
107 }
108
109 void Property::Map::Clear()
110 {
111   mImpl->mContainer.clear();
112 }
113
114 void Property::Map::Merge( const Property::Map& from )
115 {
116   // Ensure we're not attempting to merge with ourself
117   if ( this != &from )
118   {
119     if ( Count() )
120     {
121       for ( unsigned int i = 0, count = from.Count(); i < count; ++i )
122       {
123         StringValuePair& pair( from.GetPair( i ) );
124         (*this)[ pair.first ] = pair.second;
125       }
126     }
127     else
128     {
129       // If we're empty, then just copy
130       *this = from;
131     }
132   }
133 }
134
135 const Property::Value& Property::Map::operator[]( const std::string& key ) const
136 {
137   for ( Container::const_iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter )
138   {
139     if ( iter->first == key )
140     {
141       return iter->second;
142     }
143   }
144
145   DALI_ASSERT_ALWAYS( ! "Invalid Key" );
146 }
147
148 Property::Value& Property::Map::operator[]( const std::string& key )
149 {
150   for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter )
151   {
152     if ( iter->first == key )
153     {
154       return iter->second;
155     }
156   }
157
158   // Create and return reference to new value
159   mImpl->mContainer.push_back( StringValuePair( key, Value() ) );
160   return (mImpl->mContainer.end() - 1)->second;
161 }
162
163 Property::Map& Property::Map::operator=( const Property::Map& other )
164 {
165   if( this != &other )
166   {
167     delete mImpl;
168     mImpl = new Impl;
169     mImpl->mContainer = other.mImpl->mContainer;
170   }
171   return *this;
172 }
173
174 } // namespace Dali