From: Xiangyin Ma Date: Wed, 15 Jun 2016 17:27:45 +0000 (+0100) Subject: Extend Property::Map to support Index-Value pairs X-Git-Tag: dali_1.1.39~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=658e0928dbb62f89681f015e0946b23b59459dc7 Extend Property::Map to support Index-Value pairs Change-Id: I34039e8f6a41e3d41a364c668652c12cbeaba535 --- diff --git a/automated-tests/src/dali/utc-Dali-PropertyMap.cpp b/automated-tests/src/dali/utc-Dali-PropertyMap.cpp index 94c5437..f9cae36 100644 --- a/automated-tests/src/dali/utc-Dali-PropertyMap.cpp +++ b/automated-tests/src/dali/utc-Dali-PropertyMap.cpp @@ -39,12 +39,16 @@ int UtcDaliPropertyMapPopulate(void) DALI_TEST_CHECK( map.Empty() ); map[ "hello" ] = 1; + map[ 10 ] = "DALi"; map[ "world" ] = "world"; + map[ 100 ] = 9; map[ "world" ] = 3; // same item as line above DALI_TEST_CHECK( !map.Empty() ); // Should no longer be empty - DALI_TEST_CHECK( map.Count() == 2 ); // Should only have two items, not three!! + DALI_TEST_CHECK( map.Count() == 4 ); // Should only have four items, not five!! DALI_TEST_CHECK( map["hello"].Get() == 1 ); DALI_TEST_CHECK( map["world"].Get() == 3 ); + DALI_TEST_EQUALS( "DALi", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( map[100].Get() == 9 ); map.Clear(); DALI_TEST_CHECK( map.Empty() ); @@ -56,20 +60,22 @@ int UtcDaliPropertyMapCopyAndAssignment(void) Property::Map map; map[ "hello" ] = 1; map[ "world" ] = 2; + map[ 10 ] = "DALi"; Property::Map assignedMap; assignedMap[ "foo" ] = 3; - DALI_TEST_CHECK( assignedMap.Count() == 1 ); - assignedMap = map; + assignedMap[ 100 ] = 9; DALI_TEST_CHECK( assignedMap.Count() == 2 ); + assignedMap = map; + DALI_TEST_CHECK( assignedMap.Count() == 3 ); Property::Map copiedMap( map ); - DALI_TEST_CHECK( copiedMap.Count() == 2 ); + DALI_TEST_CHECK( copiedMap.Count() == 3 ); // Self assignment - DALI_TEST_CHECK( map.Count() == 2 ); + DALI_TEST_CHECK( map.Count() == 3 ); map = map; - DALI_TEST_CHECK( map.Count() == 2 ); + DALI_TEST_CHECK( map.Count() == 3 ); END_TEST; } @@ -78,12 +84,16 @@ int UtcDaliPropertyMapConstOperator(void) { Property::Map map; map[ "hello" ] = 1; + map[ 10 ] = "DALi"; map[ "world" ] = 2; - DALI_TEST_CHECK( map.Count() == 2 ); + DALI_TEST_CHECK( map.Count() == 3 ); const Property::Map& constMap( map ); DALI_TEST_CHECK( constMap[ "world" ].Get() == 2 ); - DALI_TEST_CHECK( constMap.Count() == 2 ); // Ensure count hasn't gone up + DALI_TEST_CHECK( constMap.Count() == 3 ); // Ensure count hasn't gone up + + DALI_TEST_EQUALS( "DALi", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( constMap.Count() == 3 ); // Ensure count hasn't gone up // Invalid Key try @@ -99,6 +109,7 @@ int UtcDaliPropertyMapConstOperator(void) END_TEST; } +// deprecated API, only retrieve the value from string-value pairs int UtcDaliPropertyMapGetValue(void) { Property::Map map; @@ -124,6 +135,7 @@ int UtcDaliPropertyMapGetValue(void) END_TEST; } +// deprecated API, only retrieve the key from the string-value pairs int UtcDaliPropertyMapGetKey(void) { Property::Map map; @@ -147,6 +159,7 @@ int UtcDaliPropertyMapGetKey(void) END_TEST; } +// deprecated API, only retrieve the string-value pairs int UtcDaliPropertyMapGetPair(void) { Property::Map map; @@ -176,7 +189,9 @@ int UtcDaliPropertyMapFind(void) { Property::Map map; map[ "hello" ] = 1; + map[ 10 ] = "DALi"; map[ "world" ] = 2; + map[ 100 ] = 9; Property::Value* value = NULL; @@ -188,6 +203,14 @@ int UtcDaliPropertyMapFind(void) DALI_TEST_CHECK( value ); DALI_TEST_CHECK( value->Get() == 2 ); + value = map.Find( 100 ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == 9 ); + + value = map.Find( 10 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( "DALi", value->Get(), TEST_LOCATION ); + value = map.Find( "invalidKey" ); DALI_TEST_CHECK( !value ); @@ -203,12 +226,25 @@ int UtcDaliPropertyMapInsertP(void) Property::Value* value = map.Find( "foo" ); DALI_TEST_CHECK( value ); DALI_TEST_EQUALS( "bar", value->Get(), TEST_LOCATION ); + map.Insert( std::string("foo2"), "testing" ); DALI_TEST_EQUALS( 2u, map.Count(), TEST_LOCATION ); value = map.Find( "foo2" ); DALI_TEST_CHECK( value ); DALI_TEST_EQUALS( "testing", value->Get(), TEST_LOCATION ); + map.Insert( 10, "DALi" ); + DALI_TEST_EQUALS( 3u, map.Count(), TEST_LOCATION ); + value = map.Find( 10 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( "DALi", value->Get(), TEST_LOCATION ); + + map.Insert( 100, 9 ); + DALI_TEST_EQUALS( 4u, map.Count(), TEST_LOCATION ); + value = map.Find( 100 ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == 9 ); + END_TEST; } @@ -216,60 +252,67 @@ int UtcDaliPropertyMapMerge(void) { Property::Map map; map[ "hello" ] = 1; + map[ 10 ] = "DALi"; map[ "world" ] = 2; - DALI_TEST_CHECK( map.Count() == 2 ); + DALI_TEST_CHECK( map.Count() == 3 ); // Create another map with the same keys but different values Property::Map map2; - map[ "hello" ] = 3; - map[ "world" ] = 4; + map2[ "hello" ] = 3; + map2[ "world" ] = 4; + map[ 10 ] = "3DEngine"; // Merge map2 into map1, count should still be 2, map values should be from map2 map.Merge( map2 ); - DALI_TEST_CHECK( map.Count() == 2 ); + DALI_TEST_CHECK( map.Count() == 3 ); DALI_TEST_CHECK( map[ "hello" ].Get< int >() == 3 ); DALI_TEST_CHECK( map[ "world"].Get< int >() == 4 ); + DALI_TEST_EQUALS( "3DEngine", map[ 10 ].Get(), TEST_LOCATION ); // Create another map with different keys Property::Map map3; map3[ "foo" ] = 5; - map3[ "bar" ] = 6; + map3[ 100 ] = 6; // Merge map3 into map1, count should increase, existing values should match previous and new values should match map3 map.Merge( map3 ); - DALI_TEST_CHECK( map.Count() == 4 ); + DALI_TEST_CHECK( map.Count() == 5 ); DALI_TEST_CHECK( map[ "hello" ].Get< int >() == 3 ); DALI_TEST_CHECK( map[ "world"].Get< int >() == 4 ); DALI_TEST_CHECK( map[ "foo"].Get< int >() == 5 ); - DALI_TEST_CHECK( map[ "bar"].Get< int >() == 6 ); + DALI_TEST_EQUALS( "3DEngine", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( map[ 100].Get< int >() == 6 ); // Create an empty map and attempt to merge, should be successful, nothing should change Property::Map map4; DALI_TEST_CHECK( map4.Empty() ); map.Merge( map4 ); DALI_TEST_CHECK( map4.Empty() ); - DALI_TEST_CHECK( map.Count() == 4 ); + DALI_TEST_CHECK( map.Count() == 5 ); DALI_TEST_CHECK( map[ "hello" ].Get< int >() == 3 ); DALI_TEST_CHECK( map[ "world"].Get< int >() == 4 ); DALI_TEST_CHECK( map[ "foo"].Get< int >() == 5 ); - DALI_TEST_CHECK( map[ "bar"].Get< int >() == 6 ); + DALI_TEST_EQUALS( "3DEngine", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( map[ 100 ].Get< int >() == 6 ); // Merge map into map4, map4 should be the same as map now. map4.Merge( map ); - DALI_TEST_CHECK( map4.Count() == 4 ); + DALI_TEST_CHECK( map4.Count() == 5 ); DALI_TEST_CHECK( map4[ "hello" ].Get< int >() == 3 ); DALI_TEST_CHECK( map4[ "world"].Get< int >() == 4 ); DALI_TEST_CHECK( map4[ "foo"].Get< int >() == 5 ); - DALI_TEST_CHECK( map4[ "bar"].Get< int >() == 6 ); + DALI_TEST_EQUALS( "3DEngine", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( map4[ 100 ].Get< int >() == 6 ); // Attempt to merge into itself, should be successful, nothing should change map.Merge( map ); - DALI_TEST_CHECK( map.Count() == 4 ); + DALI_TEST_CHECK( map.Count() == 5 ); DALI_TEST_CHECK( map[ "hello" ].Get< int >() == 3 ); DALI_TEST_CHECK( map[ "world"].Get< int >() == 4 ); DALI_TEST_CHECK( map[ "foo"].Get< int >() == 5 ); - DALI_TEST_CHECK( map[ "bar"].Get< int >() == 6 ); + DALI_TEST_EQUALS( "3DEngine", map[ 10 ].Get(), TEST_LOCATION ); + DALI_TEST_CHECK( map[ 100 ].Get< int >() == 6 ); END_TEST; } @@ -279,7 +322,9 @@ int UtcDaliPropertyMapOstream01(void) Property::Map map; map.Insert("duration", 5.0f); + map.Insert( 10, "DALi" ); map.Insert("delay", 1.0f); + map.Insert( 100, 9 ); map.Insert("value", 100); std::ostringstream oss; @@ -287,7 +332,8 @@ int UtcDaliPropertyMapOstream01(void) tet_printf("Testing ouput of map: %s\n", oss.str().c_str()); - DALI_TEST_EQUALS( oss.str().compare("Map(3) = {duration:5, delay:1, value:100}"), 0, TEST_LOCATION ); + // string-value pairs first, then index-value pairs + DALI_TEST_EQUALS( oss.str().compare("Map(5) = {duration:5, delay:1, value:100, 10:DALi, 100:9}"), 0, TEST_LOCATION ); END_TEST; } @@ -299,7 +345,9 @@ int UtcDaliPropertyMapOstream02(void) map2.Insert("duration", 5.0f); map2.Insert("delay", 1.0f); + map2.Insert( 10, "DALi" ); map.Insert("timePeriod", map2); + map.Insert( 100, 9 ); map.Insert("value", 100); std::ostringstream oss; @@ -307,7 +355,8 @@ int UtcDaliPropertyMapOstream02(void) tet_printf("Testing ouput of map: %s\n", oss.str().c_str()); - DALI_TEST_EQUALS( oss.str().compare("Map(2) = {timePeriod:Map(2) = {duration:5, delay:1}, value:100}"), 0, TEST_LOCATION ); + // string-value pairs first, then index-value pairs + DALI_TEST_EQUALS( oss.str().compare("Map(3) = {timePeriod:Map(3) = {duration:5, delay:1, 10:DALi}, value:100, 100:9}"), 0, TEST_LOCATION ); END_TEST; } diff --git a/dali/public-api/object/property-map.cpp b/dali/public-api/object/property-map.cpp index 6caeb11..f892aae 100644 --- a/dali/public-api/object/property-map.cpp +++ b/dali/public-api/object/property-map.cpp @@ -26,12 +26,17 @@ namespace Dali namespace { -typedef std::vector< StringValuePair > Container; +typedef std::vector< StringValuePair > StringValueContainer; + +typedef std::pair< Property::Index, Property::Value > IndexValuePair; +typedef std::vector< IndexValuePair > IndexValueContainer; + }; // unnamed namespace struct Property::Map::Impl { - Container mContainer; + StringValueContainer mStringValueContainer; + IndexValueContainer mIndexValueContainer; }; Property::Map::Map() @@ -42,7 +47,8 @@ Property::Map::Map() Property::Map::Map( const Property::Map& other ) : mImpl( new Impl ) { - mImpl->mContainer = other.mImpl->mContainer; + mImpl->mStringValueContainer = other.mImpl->mStringValueContainer; + mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer; } Property::Map::~Map() @@ -52,48 +58,53 @@ Property::Map::~Map() Property::Map::SizeType Property::Map::Count() const { - return mImpl->mContainer.size(); + return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size(); } bool Property::Map::Empty() const { - return mImpl->mContainer.empty(); + return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty(); } void Property::Map::Insert( const char* key, const Value& value ) { - mImpl->mContainer.push_back( std::make_pair( key, value ) ); + mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) ); } void Property::Map::Insert( const std::string& key, const Value& value ) { - mImpl->mContainer.push_back( std::make_pair( key, value ) ); + mImpl->mStringValueContainer.push_back( std::make_pair( key, value ) ); +} + +void Property::Map::Insert( Property::Index key, const Value& value ) +{ + mImpl->mIndexValueContainer.push_back( std::make_pair( key, value ) ); } Property::Value& Property::Map::GetValue( SizeType position ) const { - DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" ); + DALI_ASSERT_ALWAYS( position < mImpl->mStringValueContainer.size() && "position out-of-bounds" ); - return mImpl->mContainer[ position ].second; + return mImpl->mStringValueContainer[ position ].second; } const std::string& Property::Map::GetKey( SizeType position ) const { - DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" ); + DALI_ASSERT_ALWAYS( position < mImpl->mStringValueContainer.size() && "position out-of-bounds" ); - return mImpl->mContainer[ position ].first; + return mImpl->mStringValueContainer[ position ].first; } StringValuePair& Property::Map::GetPair( SizeType position ) const { - DALI_ASSERT_ALWAYS( position < Count() && "position out-of-bounds" ); + DALI_ASSERT_ALWAYS( position < mImpl->mStringValueContainer.size() && "position out-of-bounds" ); - return mImpl->mContainer[ position ]; + return mImpl->mStringValueContainer[ position ]; } Property::Value* Property::Map::Find( const char* key ) const { - for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter ) + for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) { if ( iter->first == key ) { @@ -106,14 +117,36 @@ Property::Value* Property::Map::Find( const char* key ) const Property::Value* Property::Map::Find( const std::string& key ) const { return Find( key.c_str() ); +} +Property::Value* Property::Map::Find( Property::Index key ) const +{ + for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) + { + if ( iter->first == key ) + { + return &iter->second; + } + } + return NULL; // Not found } Property::Value* Property::Map::Find( const std::string& key, Property::Type type ) const { - for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter ) + for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) + { + if( (iter->second.GetType() == type) && (iter->first == key) ) + { + return &iter->second; + } + } + return NULL; // Not found +} + +Property::Value* Property::Map::Find( Property::Index key, Property::Type type ) const +{ + for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) { - // test type first to shortcut eval (possibly reducing string compares) if( (iter->second.GetType() == type) && (iter->first == key) ) { return &iter->second; @@ -124,7 +157,8 @@ Property::Value* Property::Map::Find( const std::string& key, Property::Type typ void Property::Map::Clear() { - mImpl->mContainer.clear(); + mImpl->mStringValueContainer.clear(); + mImpl->mIndexValueContainer.clear(); } void Property::Map::Merge( const Property::Map& from ) @@ -134,10 +168,14 @@ void Property::Map::Merge( const Property::Map& from ) { if ( Count() ) { - for ( unsigned int i = 0, count = from.Count(); i < count; ++i ) + for ( StringValueContainer::const_iterator iter = from.mImpl->mStringValueContainer.begin(), endIter = from.mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) { - StringValuePair& pair( from.GetPair( i ) ); - (*this)[ pair.first ] = pair.second; + (*this)[iter->first] = iter->second; + } + + for ( IndexValueContainer::const_iterator iter = from.mImpl->mIndexValueContainer.begin(), endIter = from.mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) + { + (*this)[iter->first] = iter->second; } } else @@ -150,7 +188,7 @@ void Property::Map::Merge( const Property::Map& from ) const Property::Value& Property::Map::operator[]( const std::string& key ) const { - for ( Container::const_iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter ) + for ( StringValueContainer::const_iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) { if ( iter->first == key ) { @@ -163,7 +201,35 @@ const Property::Value& Property::Map::operator[]( const std::string& key ) const Property::Value& Property::Map::operator[]( const std::string& key ) { - for ( Container::iterator iter = mImpl->mContainer.begin(), endIter = mImpl->mContainer.end(); iter != endIter; ++iter ) + for ( StringValueContainer::iterator iter = mImpl->mStringValueContainer.begin(), endIter = mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) + { + if ( iter->first == key ) + { + return iter->second; + } + } + + // Create and return reference to new value + mImpl->mStringValueContainer.push_back( std::make_pair( key, Property::Value() ) ); + return (mImpl->mStringValueContainer.end() - 1)->second; +} + +const Property::Value& Property::Map::operator[]( Property::Index key ) const +{ + for ( IndexValueContainer::const_iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) + { + if ( iter->first == key ) + { + return iter->second; + } + } + + DALI_ASSERT_ALWAYS( ! "Invalid Key" ); +} + +Property::Value& Property::Map::operator[]( Property::Index key ) +{ + for ( IndexValueContainer::iterator iter = mImpl->mIndexValueContainer.begin(), endIter = mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) { if ( iter->first == key ) { @@ -172,8 +238,8 @@ Property::Value& Property::Map::operator[]( const std::string& key ) } // Create and return reference to new value - mImpl->mContainer.push_back( std::make_pair( key, Property::Value() ) ); - return (mImpl->mContainer.end() - 1)->second; + mImpl->mIndexValueContainer.push_back( std::make_pair( key, Property::Value() ) ); + return (mImpl->mIndexValueContainer.end() - 1)->second; } Property::Map& Property::Map::operator=( const Property::Map& other ) @@ -182,7 +248,8 @@ Property::Map& Property::Map::operator=( const Property::Map& other ) { delete mImpl; mImpl = new Impl; - mImpl->mContainer = other.mImpl->mContainer; + mImpl->mStringValueContainer = other.mImpl->mStringValueContainer; + mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer; } return *this; } @@ -190,14 +257,28 @@ Property::Map& Property::Map::operator=( const Property::Map& other ) std::ostream& operator<<( std::ostream& stream, const Property::Map& map ) { stream << "Map(" << map.Count() << ") = {"; - for( unsigned int i=0; imStringValueContainer.begin(), endIter = map.mImpl->mStringValueContainer.end(); iter != endIter; ++iter ) { - if( i>0 ) + if( count++ > 0 ) { - stream << ", "; + stream<<", "; } - stream << map.GetKey(i) << ":" << map.GetValue( i ); + stream<< iter->first << ":"<second; } + + // Output the Index-Value pairs + for ( IndexValueContainer::iterator iter = map.mImpl->mIndexValueContainer.begin(), endIter = map.mImpl->mIndexValueContainer.end(); iter != endIter; ++iter ) + { + if( count++ > 0 ) + { + stream<<", "; + } + stream<< iter->first << ":"<second; + } + stream << "}"; return stream; diff --git a/dali/public-api/object/property-map.h b/dali/public-api/object/property-map.h index 902947d..15a3291 100644 --- a/dali/public-api/object/property-map.h +++ b/dali/public-api/object/property-map.h @@ -36,7 +36,7 @@ namespace Dali typedef std::pair StringValuePair; /** - * @brief A Map of property values. + * @brief A Map of property values, the key type could be String or Property::Index. * @SINCE_1_0.0 */ class DALI_IMPORT_API Property::Map @@ -82,7 +82,7 @@ public: bool Empty() const; /** - * @brief Inserts the key-value pair in the Map. + * @brief Inserts the key-value pair in the Map, with the key type as string. * * Does not check for duplicates * @SINCE_1_0.0 @@ -92,7 +92,7 @@ public: void Insert( const char* key, const Value& value ); /** - * @brief Inserts the key-value pair in the Map. + * @brief Inserts the key-value pair in the Map, with the key type as string. * * Does not check for duplicates * @SINCE_1_0.0 @@ -102,7 +102,19 @@ public: void Insert( const std::string& key, const Value& value ); /** - * @brief Retrieve the value at the specified position. + * @brief Inserts the key-value pair in the Map, with the key type as index. + * + * Does not check for duplicates + * @SINCE_1_1.39 + * @param key to insert + * @param value to insert + */ + void Insert( Property::Index key, const Value& value ); + + /** + * DEPRECATED_1_1.39. Retrieve the value with key instead of position, Use Find( key ) instead. + * + * @brief Retrieve the value of the string-value pair at the specified position. * * @SINCE_1_0.0 * @return A reference to the value at the specified position. @@ -112,6 +124,8 @@ public: Value& GetValue( SizeType position ) const; /** + * DEPRECATED_1_1.39 Position based retrieval is no longer supported after extending the key type to both Index and String. + * * @brief Retrieve the key at the specified position. * * @SINCE_1_0.0 @@ -122,6 +136,8 @@ public: const std::string& GetKey( SizeType position ) const; /** + * DEPRECATED_1_1.39 Position based retrieval is no longer supported after extending the key type to both Index and String. + * * @brief Retrieve the key & the value at the specified position. * * @SINCE_1_0.0 @@ -152,6 +168,16 @@ public: Value* Find( const std::string& key ) const; /** + * @brief Finds the value for the specified key if it exists. + * + * @SINCE_1_1.39 + * @param[in] key The key to find. + * + * @return A const pointer to the value if it exists, NULL otherwise + */ + Value* Find( Property::Index key ) const; + + /** * @brief Finds the value for the specified key if it exists and its type is type * * @SINCE_1_0.0 @@ -163,6 +189,17 @@ public: Value* Find( const std::string& key, Property::Type type ) const; /** + * @brief Finds the value for the specified key if it exists and its type is type + * + * @SINCE_1_1.39 + * @param[in] key The key to find. + * @param[in] type The type to check. + * + * @return A const pointer to the value if it exists, NULL otherwise + */ + Value* Find( Property::Index key, Property::Type type ) const; + + /** * @brief Clears the map. * @SINCE_1_0.0 */ @@ -179,7 +216,7 @@ public: void Merge( const Map& from ); /** - * @brief Const operator to access element with the specified key. + * @brief Const operator to access element with the specified string key. * * @SINCE_1_0.0 * @param[in] key The key whose value to access. @@ -191,7 +228,7 @@ public: const Value& operator[]( const std::string& key ) const; /** - * @brief Operator to access the element with the specified key. + * @brief Operator to access the element with the specified string key. * * @SINCE_1_0.0 * @param[in] key The key whose value to access. @@ -203,6 +240,30 @@ public: Value& operator[]( const std::string& key ); /** + * @brief Const operator to access element with the specified index key. + * + * @SINCE_1_1.39 + * @param[in] key The key whose value to access. + * + * @return The value for the element with the specified key, if key doesn't exist, then Property::NONE is returned. + * + * @note Will assert if invalid-key is given. + */ + const Value& operator[]( Property::Index key ) const; + + /** + * @brief Operator to access the element with the specified index key. + * + * @SINCE_1_1.39 + * @param[in] key The key whose value to access. + * + * @return A reference to the value for the element with the specified key. + * + * @note If an element with the key does not exist, then it is created. + */ + Value& operator[]( Property::Index key ); + + /** * @brief Assignment Operator * * @SINCE_1_0.0