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<int>() == 1 );
DALI_TEST_CHECK( map["world"].Get<int>() == 3 );
+ DALI_TEST_EQUALS( "DALi", map[ 10 ].Get<std::string>(), TEST_LOCATION );
+ DALI_TEST_CHECK( map[100].Get<int>() == 9 );
map.Clear();
DALI_TEST_CHECK( map.Empty() );
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;
}
{
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<int>() == 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<std::string>(), TEST_LOCATION );
+ DALI_TEST_CHECK( constMap.Count() == 3 ); // Ensure count hasn't gone up
// Invalid Key
try
END_TEST;
}
+// deprecated API, only retrieve the value from string-value pairs
int UtcDaliPropertyMapGetValue(void)
{
Property::Map map;
END_TEST;
}
+// deprecated API, only retrieve the key from the string-value pairs
int UtcDaliPropertyMapGetKey(void)
{
Property::Map map;
END_TEST;
}
+// deprecated API, only retrieve the string-value pairs
int UtcDaliPropertyMapGetPair(void)
{
Property::Map map;
{
Property::Map map;
map[ "hello" ] = 1;
+ map[ 10 ] = "DALi";
map[ "world" ] = 2;
+ map[ 100 ] = 9;
Property::Value* value = NULL;
DALI_TEST_CHECK( value );
DALI_TEST_CHECK( value->Get<int>() == 2 );
+ value = map.Find( 100 );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<int>() == 9 );
+
+ value = map.Find( 10 );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( "DALi", value->Get<std::string>(), TEST_LOCATION );
+
value = map.Find( "invalidKey" );
DALI_TEST_CHECK( !value );
Property::Value* value = map.Find( "foo" );
DALI_TEST_CHECK( value );
DALI_TEST_EQUALS( "bar", value->Get<std::string>(), 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<std::string>(), 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<std::string>(), 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<int>() == 9 );
+
END_TEST;
}
{
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<std::string>(), 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<std::string>(), 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<std::string>(), 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<std::string>(), 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<std::string>(), TEST_LOCATION );
+ DALI_TEST_CHECK( map[ 100 ].Get< int >() == 6 );
END_TEST;
}
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;
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;
}
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;
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;
}
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()
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()
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 )
{
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;
void Property::Map::Clear()
{
- mImpl->mContainer.clear();
+ mImpl->mStringValueContainer.clear();
+ mImpl->mIndexValueContainer.clear();
}
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
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 )
{
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 )
{
}
// 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 )
{
delete mImpl;
mImpl = new Impl;
- mImpl->mContainer = other.mImpl->mContainer;
+ mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
+ mImpl->mIndexValueContainer = other.mImpl->mIndexValueContainer;
}
return *this;
}
std::ostream& operator<<( std::ostream& stream, const Property::Map& map )
{
stream << "Map(" << map.Count() << ") = {";
- for( unsigned int i=0; i<map.Count(); ++i )
+
+ int count = 0;
+ // Output the String-Value pairs
+ for ( StringValueContainer::iterator iter = map.mImpl->mStringValueContainer.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 << ":"<<iter->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 << ":"<<iter->second;
+ }
+
stream << "}";
return stream;
typedef std::pair<std::string, Property::Value> 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
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
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
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.
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
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
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
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
*/
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.
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.
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