2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/public-api/object/property-map.h>
22 #include <dali/public-api/common/vector-wrapper.h>
29 typedef std::vector< StringValuePair > StringValueContainer;
31 typedef std::pair< Property::Index, Property::Value > IndexValuePair;
32 typedef std::vector< IndexValuePair > IndexValueContainer;
34 }; // unnamed namespace
37 struct Property::Map::Impl
39 StringValueContainer mStringValueContainer;
40 IndexValueContainer mIndexValueContainer;
48 Property::Map::Map( const Property::Map& other )
51 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
52 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
60 Property::Map::SizeType Property::Map::Count() const
62 return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size();
65 bool Property::Map::Empty() const
67 return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty();
70 void Property::Map::Insert( const char* key, const Value& value )
72 mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) );
75 void Property::Map::Insert( const std::string& key, const Value& value )
77 mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) );
80 void Property::Map::Insert( Property::Index key, const Value& value )
82 mImpl->mIndexValueContainer.push_back( std::make_pair( key, value ) );
85 Property::Value& Property::Map::GetValue( SizeType position ) const
87 SizeType numStringKeys = mImpl->mStringValueContainer.size();
88 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
89 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
91 if( position < numStringKeys )
93 return mImpl->mStringValueContainer[ position ].second;
97 return mImpl->mIndexValueContainer[ position-numStringKeys ].second;
101 const std::string& Property::Map::GetKey( SizeType position ) const
103 SizeType numStringKeys = mImpl->mStringValueContainer.size();
104 DALI_ASSERT_ALWAYS( position < numStringKeys && "position out-of-bounds" );
106 return mImpl->mStringValueContainer[ position ].first;
109 Property::Key Property::Map::GetKeyAt( SizeType position ) const
111 SizeType numStringKeys = mImpl->mStringValueContainer.size();
112 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
113 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
115 if( position < numStringKeys )
117 Key key(mImpl->mStringValueContainer[ position ].first);
122 Key key( mImpl->mIndexValueContainer[ position-numStringKeys ].first );
127 StringValuePair& Property::Map::GetPair( SizeType position ) const
129 SizeType numStringKeys = mImpl->mStringValueContainer.size();
131 DALI_ASSERT_ALWAYS( position < ( numStringKeys ) && "position out-of-bounds" );
133 return mImpl->mStringValueContainer[ position ];
136 KeyValuePair Property::Map::GetKeyValue( SizeType position ) const
138 SizeType numStringKeys = mImpl->mStringValueContainer.size();
139 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
141 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
143 if( position < numStringKeys )
145 Key key(mImpl->mStringValueContainer[ position ].first);
146 KeyValuePair keyValue(key, mImpl->mStringValueContainer[ position ].second );
151 Key key( mImpl->mIndexValueContainer[ position-numStringKeys ].first );
152 KeyValuePair keyValue(key, mImpl->mIndexValueContainer[ position-numStringKeys ].second );
157 Property::Value* Property::Map::Find( const char* key ) const
159 for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
161 if ( iter->first == key )
163 return &iter->second;
166 return NULL; // Not found
169 Property::Value* Property::Map::Find( const std::string& key ) const
171 return Find( key.c_str() );
174 Property::Value* Property::Map::Find( Property::Index key ) const
176 for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
178 if ( iter->first == key )
180 return &iter->second;
183 return NULL; // Not found
186 Property::Value* Property::Map::Find( Property::Index indexKey, const std::string& stringKey ) const
188 Property::Value* valuePtr = Find( indexKey );
191 valuePtr = Find( stringKey );
196 Property::Value* Property::Map::Find( const std::string& key, Property::Type type ) const
198 for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
200 if( (iter->second.GetType() == type) && (iter->first == key) )
202 return &iter->second;
205 return NULL; // Not found
208 Property::Value* Property::Map::Find( Property::Index key, Property::Type type ) const
210 for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
212 if( (iter->second.GetType() == type) && (iter->first == key) )
214 return &iter->second;
217 return NULL; // Not found
220 void Property::Map::Clear()
222 mImpl->mStringValueContainer.clear();
223 mImpl->mIndexValueContainer.clear();
226 void Property::Map::Merge( const Property::Map& from )
228 // Ensure we're not attempting to merge with ourself
233 for ( StringValueContainer::const_iterator iter = from.mImpl->mStringValueContainer.begin(), endIter = from.mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
235 (*this)[iter->first] = iter->second;
238 for ( IndexValueContainer::const_iterator iter = from.mImpl->mIndexValueContainer.begin(), endIter = from.mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
240 (*this)[iter->first] = iter->second;
245 // If we're empty, then just copy
251 const Property::Value& Property::Map::operator[]( const std::string& key ) const
253 for ( StringValueContainer::const_iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
255 if ( iter->first == key )
261 DALI_ASSERT_ALWAYS( ! "Invalid Key" );
264 Property::Value& Property::Map::operator[]( const std::string& key )
266 for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
268 if ( iter->first == key )
274 // Create and return reference to new value
275 mImpl->mStringValueContainer.push_back( std::make_pair( key, Property::Value() ) );
276 return (mImpl->mStringValueContainer.end() - 1)->second;
279 const Property::Value& Property::Map::operator[]( Property::Index key ) const
281 for ( IndexValueContainer::const_iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
283 if ( iter->first == key )
289 DALI_ASSERT_ALWAYS( ! "Invalid Key" );
292 Property::Value& Property::Map::operator[]( Property::Index key )
294 for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
296 if ( iter->first == key )
302 // Create and return reference to new value
303 mImpl->mIndexValueContainer.push_back( std::make_pair( key, Property::Value() ) );
304 return (mImpl->mIndexValueContainer.end() - 1)->second;
307 Property::Map& Property::Map::operator=( const Property::Map& other )
313 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
314 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
319 std::ostream& operator<<( std::ostream& stream, const Property::Map& map )
321 stream << "Map(" << map.Count() << ") = {";
324 // Output the String-Value pairs
325 for ( StringValueContainer::iterator iter = map.mImpl->mStringValueContainer.begin(), endIter = map.mImpl->mStringValueContainer.end(); iter != endIter; ++iter )
331 stream<< iter->first << ":"<<iter->second;
334 // Output the Index-Value pairs
335 for ( IndexValueContainer::iterator iter = map.mImpl->mIndexValueContainer.begin(), endIter = map.mImpl->mIndexValueContainer.end(); iter != endIter; ++iter )
341 stream<< iter->first << ":"<<iter->second;