2 * Copyright (c) 2019 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/integration-api/debug.h>
25 #include <dali/public-api/common/vector-wrapper.h>
32 typedef std::vector< StringValuePair > StringValueContainer;
34 typedef std::pair< Property::Index, Property::Value > IndexValuePair;
35 typedef std::vector< IndexValuePair > IndexValueContainer;
37 }; // unnamed namespace
40 struct Property::Map::Impl
42 StringValueContainer mStringValueContainer;
43 IndexValueContainer mIndexValueContainer;
51 Property::Map::Map( const Property::Map& other )
54 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
55 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
58 Property::Map::Map( Property::Map&& other )
59 : mImpl( other.mImpl )
61 other.mImpl = nullptr;
69 Property::Map::SizeType Property::Map::Count() const
71 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
72 return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size();
75 bool Property::Map::Empty() const
77 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
78 return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty();
81 void Property::Map::Insert( const char* key, const Value& value )
83 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
84 mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) );
87 void Property::Map::Insert( const std::string& key, const Value& value )
89 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
90 mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) );
93 void Property::Map::Insert( Property::Index key, const Value& value )
95 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
96 mImpl->mIndexValueContainer.push_back( std::make_pair( key, value ) );
99 Property::Value& Property::Map::GetValue( SizeType position ) const
101 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
102 SizeType numStringKeys = mImpl->mStringValueContainer.size();
103 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
104 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
106 if( position < numStringKeys )
108 return mImpl->mStringValueContainer[ position ].second;
112 return mImpl->mIndexValueContainer[ position-numStringKeys ].second;
116 const std::string& Property::Map::GetKey( SizeType position ) const
118 DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetKey() is deprecated and will be removed from next release.\n" );
120 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
121 SizeType numStringKeys = mImpl->mStringValueContainer.size();
122 DALI_ASSERT_ALWAYS( position < numStringKeys && "position out-of-bounds" );
124 return mImpl->mStringValueContainer[ position ].first;
127 Property::Key Property::Map::GetKeyAt( SizeType position ) const
129 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
131 SizeType numStringKeys = mImpl->mStringValueContainer.size();
132 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
133 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
135 if( position < numStringKeys )
137 Key key(mImpl->mStringValueContainer[ position ].first);
142 Key key( mImpl->mIndexValueContainer[ position-numStringKeys ].first );
147 StringValuePair& Property::Map::GetPair( SizeType position ) const
149 DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetPair() is deprecated and will be removed from next release.\n" );
151 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
153 SizeType numStringKeys = mImpl->mStringValueContainer.size();
155 DALI_ASSERT_ALWAYS( position < ( numStringKeys ) && "position out-of-bounds" );
157 return mImpl->mStringValueContainer[ position ];
160 KeyValuePair Property::Map::GetKeyValue( SizeType position ) const
162 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
164 SizeType numStringKeys = mImpl->mStringValueContainer.size();
165 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
167 DALI_ASSERT_ALWAYS( position < ( numStringKeys + numIndexKeys ) && "position out-of-bounds" );
169 if( position < numStringKeys )
171 Key key(mImpl->mStringValueContainer[ position ].first);
172 KeyValuePair keyValue(key, mImpl->mStringValueContainer[ position ].second );
177 Key key( mImpl->mIndexValueContainer[ position-numStringKeys ].first );
178 KeyValuePair keyValue(key, mImpl->mIndexValueContainer[ position-numStringKeys ].second );
183 Property::Value* Property::Map::Find( const char* key ) const
185 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
187 for( auto&& iter : mImpl->mStringValueContainer )
189 if ( iter.first == key )
194 return NULL; // Not found
197 Property::Value* Property::Map::Find( const std::string& key ) const
199 return Find( key.c_str() );
202 Property::Value* Property::Map::Find( Property::Index key ) const
204 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
206 for( auto&& iter : mImpl->mIndexValueContainer )
208 if ( iter.first == key )
213 return NULL; // Not found
216 Property::Value* Property::Map::Find( Property::Index indexKey, const std::string& stringKey ) const
218 Property::Value* valuePtr = Find( indexKey );
221 valuePtr = Find( stringKey );
226 Property::Value* Property::Map::Find( const std::string& key, Property::Type type ) const
228 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
230 for( auto&& iter : mImpl->mStringValueContainer )
232 if( (iter.second.GetType() == type) && (iter.first == key) )
237 return NULL; // Not found
240 Property::Value* Property::Map::Find( Property::Index key, Property::Type type ) const
242 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
244 for( auto&& iter : mImpl->mIndexValueContainer )
246 if( (iter.second.GetType() == type) && (iter.first == key) )
251 return NULL; // Not found
254 void Property::Map::Clear()
256 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
258 mImpl->mStringValueContainer.clear();
259 mImpl->mIndexValueContainer.clear();
262 void Property::Map::Merge( const Property::Map& from )
264 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
266 // Ensure we're not attempting to merge with ourself
271 for( auto&& iter : from.mImpl->mStringValueContainer )
273 (*this)[iter.first] = iter.second;
276 for( auto&& iter : from.mImpl->mIndexValueContainer )
278 (*this)[iter.first] = iter.second;
283 // If we're empty, then just copy
289 const Property::Value& Property::Map::operator[]( const std::string& key ) const
291 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
293 for( auto&& iter : mImpl->mStringValueContainer )
295 if ( iter.first == key )
301 DALI_ASSERT_ALWAYS( ! "Invalid Key" );
304 Property::Value& Property::Map::operator[]( const std::string& key )
306 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
308 for( auto&& iter : mImpl->mStringValueContainer )
310 if ( iter.first == key )
316 // Create and return reference to new value
317 mImpl->mStringValueContainer.push_back( std::make_pair( key, Property::Value() ) );
318 return (mImpl->mStringValueContainer.end() - 1)->second;
321 const Property::Value& Property::Map::operator[]( Property::Index key ) const
323 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
325 for( auto&& iter : mImpl->mIndexValueContainer )
327 if ( iter.first == key )
333 DALI_ASSERT_ALWAYS( ! "Invalid Key" );
336 Property::Value& Property::Map::operator[]( Property::Index key )
338 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
340 for( auto&& iter : mImpl->mIndexValueContainer )
342 if ( iter.first == key )
348 // Create and return reference to new value
349 mImpl->mIndexValueContainer.push_back( std::make_pair( key, Property::Value() ) );
350 return (mImpl->mIndexValueContainer.end() - 1)->second;
353 Property::Map& Property::Map::operator=( const Property::Map& other )
355 DALI_ASSERT_DEBUG( mImpl && "Cannot use an object previously used as an r-value" );
359 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
360 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
365 Property::Map& Property::Map::operator=( Property::Map&& other )
371 other.mImpl = nullptr;
376 std::ostream& operator<<( std::ostream& stream, const Property::Map& map )
378 stream << "Map(" << map.Count() << ") = {";
383 // Output the String-Value pairs
384 for( auto&& iter : map.mImpl->mStringValueContainer )
390 stream<< iter.first << ":" << iter.second;
393 // Output the Index-Value pairs
394 for( auto&& iter : map.mImpl->mIndexValueContainer )
400 stream<< iter.first << ":" << iter.second;