2 * Copyright (c) 2020 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>
31 typedef std::vector<StringValuePair> StringValueContainer;
33 using IndexValuePair = std::pair<Property::Index, Property::Value>;
34 using IndexValueContainer = std::vector<IndexValuePair>;
36 }; // unnamed namespace
38 struct Property::Map::Impl
40 StringValueContainer mStringValueContainer;
41 IndexValueContainer mIndexValueContainer;
49 Property::Map::Map(const std::initializer_list<KeyValuePair>& values)
52 for(auto&& value : values)
54 const auto& key = value.first;
57 case Property::Key::INDEX:
59 Property::Map::Insert(key.indexKey, value.second);
62 case Property::Key::STRING:
64 Property::Map::Insert(key.stringKey, value.second);
71 Property::Map::Map(const Property::Map& other)
74 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
75 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
78 Property::Map::Map(Property::Map&& other)
81 other.mImpl = nullptr;
89 Property::Map::SizeType Property::Map::Count() const
91 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
92 return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size();
95 bool Property::Map::Empty() const
97 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
98 return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty();
101 void Property::Map::Insert(const char* key, const Value& value)
103 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
104 mImpl->mStringValueContainer.push_back(std::make_pair(key, value));
107 void Property::Map::Insert(const std::string& key, const Value& value)
109 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
110 mImpl->mStringValueContainer.push_back(std::make_pair(key, value));
113 void Property::Map::Insert(Property::Index key, const Value& value)
115 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
116 mImpl->mIndexValueContainer.push_back(std::make_pair(key, value));
119 Property::Value& Property::Map::GetValue(SizeType position) const
121 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
122 SizeType numStringKeys = mImpl->mStringValueContainer.size();
123 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
124 DALI_ASSERT_ALWAYS(position < (numStringKeys + numIndexKeys) && "position out-of-bounds");
126 if(position < numStringKeys)
128 return mImpl->mStringValueContainer[position].second;
132 return mImpl->mIndexValueContainer[position - numStringKeys].second;
136 const std::string& Property::Map::GetKey(SizeType position) const
138 DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetKey() is deprecated and will be removed from next release.\n");
140 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
141 SizeType numStringKeys = mImpl->mStringValueContainer.size();
142 DALI_ASSERT_ALWAYS(position < numStringKeys && "position out-of-bounds");
144 return mImpl->mStringValueContainer[position].first;
147 Property::Key Property::Map::GetKeyAt(SizeType position) const
149 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
151 SizeType numStringKeys = mImpl->mStringValueContainer.size();
152 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
153 DALI_ASSERT_ALWAYS(position < (numStringKeys + numIndexKeys) && "position out-of-bounds");
155 if(position < numStringKeys)
157 Key key(mImpl->mStringValueContainer[position].first);
162 Key key(mImpl->mIndexValueContainer[position - numStringKeys].first);
167 StringValuePair& Property::Map::GetPair(SizeType position) const
169 DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetPair() is deprecated and will be removed from next release.\n");
171 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
173 SizeType numStringKeys = mImpl->mStringValueContainer.size();
175 DALI_ASSERT_ALWAYS(position < (numStringKeys) && "position out-of-bounds");
177 return mImpl->mStringValueContainer[position];
180 KeyValuePair Property::Map::GetKeyValue(SizeType position) const
182 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
184 SizeType numStringKeys = mImpl->mStringValueContainer.size();
185 SizeType numIndexKeys = mImpl->mIndexValueContainer.size();
187 DALI_ASSERT_ALWAYS(position < (numStringKeys + numIndexKeys) && "position out-of-bounds");
189 if(position < numStringKeys)
191 Key key(mImpl->mStringValueContainer[position].first);
192 KeyValuePair keyValue(key, mImpl->mStringValueContainer[position].second);
197 Key key(mImpl->mIndexValueContainer[position - numStringKeys].first);
198 KeyValuePair keyValue(key, mImpl->mIndexValueContainer[position - numStringKeys].second);
203 Property::Value* Property::Map::Find(const char* key) const
205 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
207 for(auto&& iter : mImpl->mStringValueContainer)
209 if(iter.first == key)
214 return nullptr; // Not found
217 Property::Value* Property::Map::Find(const std::string& key) const
219 return Find(key.c_str());
222 Property::Value* Property::Map::Find(Property::Index key) const
224 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
226 for(auto&& iter : mImpl->mIndexValueContainer)
228 if(iter.first == key)
233 return nullptr; // Not found
236 Property::Value* Property::Map::Find(Property::Index indexKey, const std::string& stringKey) const
238 Property::Value* valuePtr = Find(indexKey);
241 valuePtr = Find(stringKey);
246 Property::Value* Property::Map::Find(const std::string& key, Property::Type type) const
248 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
250 for(auto&& iter : mImpl->mStringValueContainer)
252 if((iter.second.GetType() == type) && (iter.first == key))
257 return nullptr; // Not found
260 Property::Value* Property::Map::Find(Property::Index key, Property::Type type) const
262 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
264 for(auto&& iter : mImpl->mIndexValueContainer)
266 if((iter.second.GetType() == type) && (iter.first == key))
271 return nullptr; // Not found
274 void Property::Map::Clear()
276 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
278 mImpl->mStringValueContainer.clear();
279 mImpl->mIndexValueContainer.clear();
282 void Property::Map::Merge(const Property::Map& from)
284 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
286 // Ensure we're not attempting to merge with ourself
291 for(auto&& iter : from.mImpl->mStringValueContainer)
293 (*this)[iter.first] = iter.second;
296 for(auto&& iter : from.mImpl->mIndexValueContainer)
298 (*this)[iter.first] = iter.second;
303 // If we're empty, then just copy
309 const Property::Value& Property::Map::operator[](const std::string& key) const
311 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
313 for(auto&& iter : mImpl->mStringValueContainer)
315 if(iter.first == key)
321 DALI_ASSERT_ALWAYS(!"Invalid Key");
324 Property::Value& Property::Map::operator[](const std::string& key)
326 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
328 for(auto&& iter : mImpl->mStringValueContainer)
330 if(iter.first == key)
336 // Create and return reference to new value
337 mImpl->mStringValueContainer.push_back(std::make_pair(key, Property::Value()));
338 return (mImpl->mStringValueContainer.end() - 1)->second;
341 const Property::Value& Property::Map::operator[](Property::Index key) const
343 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
345 for(auto&& iter : mImpl->mIndexValueContainer)
347 if(iter.first == key)
353 DALI_ASSERT_ALWAYS(!"Invalid Key");
356 Property::Value& Property::Map::operator[](Property::Index key)
358 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
360 for(auto&& iter : mImpl->mIndexValueContainer)
362 if(iter.first == key)
368 // Create and return reference to new value
369 mImpl->mIndexValueContainer.push_back(std::make_pair(key, Property::Value()));
370 return (mImpl->mIndexValueContainer.end() - 1)->second;
373 Property::Map& Property::Map::operator=(const Property::Map& other)
375 DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
379 mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
380 mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
385 Property::Map& Property::Map::operator=(Property::Map&& other)
391 other.mImpl = nullptr;
396 std::ostream& operator<<(std::ostream& stream, const Property::Map& map)
398 stream << "Map(" << map.Count() << ") = {";
403 // Output the String-Value pairs
404 for(auto&& iter : map.mImpl->mStringValueContainer)
410 stream << iter.first << ":" << iter.second;
413 // Output the Index-Value pairs
414 for(auto&& iter : map.mImpl->mIndexValueContainer)
420 stream << iter.first << ":" << iter.second;