Allow to use moved Property::Map & Property::Array 06/316306/7
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 12 Dec 2024 11:35:54 +0000 (20:35 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Mon, 6 Jan 2025 02:21:11 +0000 (02:21 +0000)
Until now, we make those value's mImpl as nullptr.
So their was a lots of DALI_ASSERT_DEBUG() to check
whether they are moved or not.

Those codes might not be fair than other moved objects implementation.

we allow to use moved object like WeakHandle, or Dali::Vector.
Let we also allow to use them.

And let we make surely assert by DALI_ASSERT_ALWAYS if we need, instead DALI_ASSERT_DEBUG

Change-Id: If08853a1635a8c33317edc1d25531223f7c427ed
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-PropertyArray.cpp
automated-tests/src/dali/utc-Dali-PropertyMap.cpp
automated-tests/src/dali/utc-Dali-PropertyValue.cpp
dali/internal/common/hash-utils.h
dali/public-api/object/property-array.cpp
dali/public-api/object/property-map.cpp

index 4cb6716590d0b6dbaf808c77856c1107d85de951..05a87b7f6b74ac6c7d906203032ddebebbdb06bf 100644 (file)
@@ -279,6 +279,21 @@ int UtcDaliPropertyArrayOstream02(void)
   END_TEST;
 }
 
+int UtcDaliPropertyArrayOstream03(void)
+{
+  std::ostringstream oss;
+
+  Property::Array array1;
+  array1.PushBack(0);
+
+  Property::Array array2(std::move(array1));
+
+  oss << array1;
+  DALI_TEST_EQUALS(oss.str().compare("Array(0) = []"), 0, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliPropertyArrayCopyConstructor(void)
 {
   Property::Array array1;
@@ -324,19 +339,10 @@ int UtcDaliPropertyArrayMoveConstructor(void)
   Property::Array array2(std::move(array1));
   DALI_TEST_EQUALS(3u, array2.Size(), TEST_LOCATION);
 
-  // Calling any methods on array1 will debug assert
+  // Calling some methods on array1 will debug assert
   const char* exceptionMessage = "Cannot use an object previously used as an r-value";
-  DALI_TEST_ASSERTION(array1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.PushBack(Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Clear(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Reserve(1), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Resize(1), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Capacity(), exceptionMessage);
   DALI_TEST_ASSERTION(array1[0], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Array&>(array1)[0], exceptionMessage);
-  DALI_TEST_ASSERTION(Property::Array temp; array1 = temp, exceptionMessage);
-
   END_TEST;
 }
 
@@ -355,18 +361,10 @@ int UtcDaliPropertyArrayMoveAssignmentOperator(void)
   array2 = std::move(array1);
   DALI_TEST_EQUALS(3u, array2.Size(), TEST_LOCATION);
 
-  // Calling any methods on array1 will debug assert
+  // Calling some methods on array1 will debug assert
   const char* exceptionMessage = "Cannot use an object previously used as an r-value";
-  DALI_TEST_ASSERTION(array1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.PushBack(Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Clear(), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Reserve(1), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Resize(1), exceptionMessage);
-  DALI_TEST_ASSERTION(array1.Capacity(), exceptionMessage);
   DALI_TEST_ASSERTION(array1[0], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Array&>(array1)[0], exceptionMessage);
-  DALI_TEST_ASSERTION(Property::Array temp; array1 = temp, exceptionMessage);
 
   // Self std::move assignment make compile warning over gcc-13. Let we ignore the warning.
 #if(__GNUC__ >= 13)
@@ -383,6 +381,107 @@ int UtcDaliPropertyArrayMoveAssignmentOperator(void)
   END_TEST;
 }
 
+int UtcDaliPropertyArrayMovedArrayP1(void)
+{
+  Property::Array array1;
+  array1.PushBack(0);
+  array1.PushBack(1);
+  array1.PushBack(2);
+  DALI_TEST_EQUALS(3u, array1.Size(), TEST_LOCATION);
+
+  Property::Array array2(std::move(array1));
+  DALI_TEST_EQUALS(3u, array2.Size(), TEST_LOCATION);
+
+  // Calling some methods on array1 will debug assert
+  const char* exceptionMessage = "Cannot use an object previously used as an r-value";
+  DALI_TEST_ASSERTION(array1[0], exceptionMessage);
+  DALI_TEST_ASSERTION(const_cast<const Property::Array&>(array1)[0], exceptionMessage);
+
+  // Call some API to moved array
+  Property::Array emptyArray;
+  DALI_TEST_EQUALS(emptyArray.GetHash(), array1.GetHash(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Capacity(), TEST_LOCATION);
+  DALI_TEST_EQUALS(true, array1.Empty(), TEST_LOCATION);
+  array1.Clear();
+
+  // Test reserve
+  array1.Reserve(4u);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(4u, array1.Capacity(), TEST_LOCATION);
+
+  array2 = std::move(array1);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Capacity(), TEST_LOCATION);
+
+  // Test resize
+  array1.Resize(2u);
+  DALI_TEST_EQUALS(2u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2u, array1.Capacity(), TEST_LOCATION);
+
+  array2 = std::move(array1);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Capacity(), TEST_LOCATION);
+
+  // Test PushBack
+  array1.PushBack(0);
+  array1.PushBack(1);
+  array1.PushBack(2);
+  DALI_TEST_EQUALS(3u, array1.Size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2, array1[2].Get<int32_t>(), TEST_LOCATION);
+
+  array2 = std::move(array1);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Capacity(), TEST_LOCATION);
+
+  // Test copy operator
+  DALI_TEST_EQUALS(3u, array2.Size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2, array2[2].Get<int32_t>(), TEST_LOCATION);
+
+  array1 = array2;
+
+  DALI_TEST_EQUALS(3u, array1.Size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2, array1[2].Get<int32_t>(), TEST_LOCATION);
+
+  array2 = std::move(array1);
+  DALI_TEST_EQUALS(0u, array1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array1.Capacity(), TEST_LOCATION);
+
+  // Test copy moved array
+  Property::Array array3 = array1;
+  DALI_TEST_EQUALS(0u, array3.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array3.Capacity(), TEST_LOCATION);
+
+  Property::Array array4;
+  array4 = array1;
+  DALI_TEST_EQUALS(0u, array4.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array4.Capacity(), TEST_LOCATION);
+
+  // Test move operator
+  DALI_TEST_EQUALS(3u, array2.Size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2, array2[2].Get<int32_t>(), TEST_LOCATION);
+
+  array1 = std::move(array2);
+
+  DALI_TEST_EQUALS(3u, array1.Size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2, array1[2].Get<int32_t>(), TEST_LOCATION);
+
+  // Test move moved array
+  DALI_TEST_EQUALS(0u, array2.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array2.Capacity(), TEST_LOCATION);
+
+  Property::Array array5 = std::move(array2);
+  DALI_TEST_EQUALS(0u, array5.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array5.Capacity(), TEST_LOCATION);
+
+  array3 = std::move(array2);
+
+  DALI_TEST_EQUALS(0u, array3.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, array3.Capacity(), TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliPropertyArrayInitializerListConstructor(void)
 {
   Property::Array array{1, 2, "hello"};
index 22f2e7769bbd1454898af0808e0a8159047a199c..11f179f7b94bf2c97dccd96a9c63fa8a937c1f18 100644 (file)
@@ -92,31 +92,15 @@ int UtcDaliPropertyMapMoveConstructor(void)
   Property::Map map2(std::move(map1));
   DALI_TEST_EQUALS(3u, map2.Count(), TEST_LOCATION);
 
-  // Calling any methods on map1 will debug assert
+  // Calling some methods on map1 will debug assert
   const char* exceptionMessage = "Cannot use an object previously used as an r-value";
-  DALI_TEST_ASSERTION(map1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Empty(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert((const char*)"key", Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert(std::string("key"), Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert(0, Property::Value()), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetValue(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKey(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKeyAt(1), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetPair(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKeyValue(0), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find((const char*)"key"), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(std::string("key")), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0, "key"), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find("key", Property::INTEGER), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0, Property::INTEGER), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Clear(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Merge(Property::Map()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1["key"], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)["key"], exceptionMessage);
-  DALI_TEST_ASSERTION(map1[0], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)[0], exceptionMessage);
-  DALI_TEST_ASSERTION(Property::Map temp; map1 = temp, exceptionMessage);
 
   END_TEST;
 }
@@ -136,31 +120,15 @@ int UtcDaliPropertyMapMoveAssignmentOperator(void)
   map2 = std::move(map1);
   DALI_TEST_EQUALS(3u, map2.Count(), TEST_LOCATION);
 
-  // Calling any methods on map1 will debug assert
+  // Calling some methods on map1 will debug assert
   const char* exceptionMessage = "Cannot use an object previously used as an r-value";
-  DALI_TEST_ASSERTION(map1.Count(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Empty(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert((const char*)"key", Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert(std::string("key"), Property::Value()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Insert(0, Property::Value()), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetValue(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKey(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKeyAt(1), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetPair(0), exceptionMessage);
   DALI_TEST_ASSERTION(map1.GetKeyValue(0), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find((const char*)"key"), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(std::string("key")), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0, "key"), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find("key", Property::INTEGER), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Find(0, Property::INTEGER), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Clear(), exceptionMessage);
-  DALI_TEST_ASSERTION(map1.Merge(Property::Map()), exceptionMessage);
-  DALI_TEST_ASSERTION(map1["key"], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)["key"], exceptionMessage);
-  DALI_TEST_ASSERTION(map1[0], exceptionMessage);
   DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)[0], exceptionMessage);
-  DALI_TEST_ASSERTION(Property::Map temp; map1 = temp, exceptionMessage);
 
   // Self std::move assignment make compile warning over gcc-13. Let we ignore the warning.
 #if(__GNUC__ >= 13)
@@ -177,6 +145,137 @@ int UtcDaliPropertyMapMoveAssignmentOperator(void)
   END_TEST;
 }
 
+int UtcDaliPropertyMapMovedMapP1(void)
+{
+  Property::Map map1;
+  map1["hello"] = 1;
+  map1["world"] = 2;
+  map1[10]      = "DALi";
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+
+  Property::Map map2;
+  map2[10] = "DALi again";
+  DALI_TEST_EQUALS(1u, map2.Count(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(3u, map2.Count(), TEST_LOCATION);
+
+  // Calling some methods on map1 will debug assert
+  const char* exceptionMessage = "Cannot use an object previously used as an r-value";
+  DALI_TEST_ASSERTION(map1.GetValue(0), exceptionMessage);
+  DALI_TEST_ASSERTION(map1.GetKey(0), exceptionMessage);
+  DALI_TEST_ASSERTION(map1.GetKeyAt(1), exceptionMessage);
+  DALI_TEST_ASSERTION(map1.GetPair(0), exceptionMessage);
+  DALI_TEST_ASSERTION(map1.GetKeyValue(0), exceptionMessage);
+  DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)["key"], exceptionMessage);
+  DALI_TEST_ASSERTION(const_cast<const Property::Map&>(map1)[0], exceptionMessage);
+
+  // Call some API to moved map
+  Property::Map emptyMap;
+  DALI_TEST_EQUALS(emptyMap.GetHash(), map1.GetHash(), TEST_LOCATION);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(true, map1.Empty(), TEST_LOCATION);
+  map1.Clear();
+
+  DALI_TEST_EQUALS(false, map1.Remove(10), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, map1.Remove("hello"), TEST_LOCATION);
+
+  Property::Value* nullValuePtr = nullptr;
+  DALI_TEST_EQUALS(nullValuePtr, map1.Find(10), TEST_LOCATION);
+  DALI_TEST_EQUALS(nullValuePtr, map1.Find("hello"), TEST_LOCATION);
+  DALI_TEST_EQUALS(nullValuePtr, map1.Find(10, "hello"), TEST_LOCATION);
+  DALI_TEST_EQUALS(nullValuePtr, map1.Find(10, Property::Type::FLOAT), TEST_LOCATION);
+  DALI_TEST_EQUALS(nullValuePtr, map1.Find("hello", Property::Type::FLOAT), TEST_LOCATION);
+
+  // Test Insert
+  map1["hello"] = 1;
+  map1.Insert("world", 2);
+  map1[10] = "DALi";
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS("DALi", map1.Find(10)->Get<std::string>(), TEST_LOCATION);
+  DALI_TEST_EQUALS(1, map1.Find("hello")->Get<int32_t>(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test Insert 2 (Index key first)
+  map1[10]      = "DALi";
+  map1["hello"] = 1;
+  map1.Insert("world", 2);
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS("DALi", map1.Find(10)->Get<std::string>(), TEST_LOCATION);
+  DALI_TEST_EQUALS(1, map1.Find("hello")->Get<int32_t>(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test Insert 3 (Insert key first)
+  map1.Insert(4, 2);
+  map1[10]      = "DALi";
+  map1["hello"] = 1;
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS("DALi", map1.Find(10)->Get<std::string>(), TEST_LOCATION);
+  DALI_TEST_EQUALS(1, map1.Find("hello")->Get<int32_t>(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test Insert 4 (Insert string first)
+  map1.Insert("world", 2);
+  map1[10]      = "DALi";
+  map1["hello"] = 1;
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS("DALi", map1.Find(10)->Get<std::string>(), TEST_LOCATION);
+  DALI_TEST_EQUALS(1, map1.Find("hello")->Get<int32_t>(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test Merge
+  map1.Merge(map2);
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test copy operator
+  DALI_TEST_EQUALS(3u, map2.Count(), TEST_LOCATION);
+
+  map1 = map2;
+
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+
+  map2 = std::move(map1);
+  DALI_TEST_EQUALS(0u, map1.Count(), TEST_LOCATION);
+
+  // Test copy moved map
+  Property::Map map3 = map1;
+  DALI_TEST_EQUALS(0u, map3.Count(), TEST_LOCATION);
+
+  Property::Map map4;
+  map4 = map1;
+  DALI_TEST_EQUALS(0u, map4.Count(), TEST_LOCATION);
+
+  // Test move operator
+  DALI_TEST_EQUALS(3u, map2.Count(), TEST_LOCATION);
+
+  map1 = std::move(map2);
+
+  DALI_TEST_EQUALS(3u, map1.Count(), TEST_LOCATION);
+
+  // Test move moved map
+  DALI_TEST_EQUALS(0u, map2.Count(), TEST_LOCATION);
+  Property::Map map5 = std::move(map2);
+
+  DALI_TEST_EQUALS(0u, map5.Count(), TEST_LOCATION);
+
+  map3 = std::move(map2);
+
+  DALI_TEST_EQUALS(0u, map3.Count(), TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliPropertyMapConstOperator(void)
 {
   Property::Map map;
@@ -724,6 +823,21 @@ int UtcDaliPropertyMapOstream02(void)
   END_TEST;
 }
 
+int UtcDaliPropertyMapOstream03(void)
+{
+  std::ostringstream oss;
+
+  Property::Map map;
+  map.Insert(100, 9);
+
+  Property::Map map2(std::move(map));
+
+  oss << map;
+  DALI_TEST_EQUALS(oss.str().compare("Map(0) = {}"), 0, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliPropertyKeyConstructorP(void)
 {
   Property::Key key1("aKey");
index f49c9b49d33710a1cab87c182aee8115d2de27bf..32817b5a68cb706e3608ef5109019774f2e2d14f 100644 (file)
@@ -560,7 +560,7 @@ int UtcDaliPropertyValueMoveConstructorArray(void)
   DALI_TEST_EQUALS(3u, array.Size(), TEST_LOCATION);
 
   Property::Value value(std::move(array));
-  DALI_TEST_ASSERTION(array.Size(), "Cannot use an object previously used as an r-value"); // Our local variable should become invalid
+  DALI_TEST_EQUALS(0u, array.Size(), TEST_LOCATION);
 
   Property::Array* arrayPtr = value.GetArray();
   DALI_TEST_CHECK(arrayPtr);
@@ -578,7 +578,7 @@ int UtcDaliPropertyValueMoveConstructorMap(void)
   DALI_TEST_EQUALS(3u, map.Count(), TEST_LOCATION);
 
   Property::Value value(std::move(map));
-  DALI_TEST_ASSERTION(map.Count(), "Cannot use an object previously used as an r-value"); // Our local variable should become invalid
+  DALI_TEST_EQUALS(0u, map.Count(), TEST_LOCATION);
 
   Property::Map* mapPtr = value.GetMap();
   DALI_TEST_CHECK(mapPtr);
index da66690eeb170529f30e20fba868ff035024f8b8..81639ec4ccb01adddfacaba8f6f00a7243938369 100644 (file)
 
 namespace Dali::Internal::HashUtils
 {
-enum
-{
-  INITIAL_HASH_VALUE = 5381
-};
+constexpr std::size_t INITIAL_HASH_VALUE = 5381;
 
 /*
  * djb2 (http://www.cse.yorku.ca/~oz/hash.html)
index 17f4a802bfcf13a910ac2abfca9cd5dbff566863..640500f4f8eb70c539142f7fa0080f7b63f65a3d 100644 (file)
@@ -82,7 +82,11 @@ Property::Array::Array(const std::initializer_list<Property::Value>& values)
 Property::Array::Array(const Property::Array& other)
 : mImpl(new Impl)
 {
-  mImpl->mArray = other.mImpl->mArray;
+  if(DALI_LIKELY(other.mImpl))
+  {
+    mImpl->mArray = other.mImpl->mArray;
+    // Keep mHash as NOT_HASHED.
+  }
 }
 
 Property::Array::Array(Property::Array&& other) noexcept
@@ -98,13 +102,16 @@ Property::Array::~Array()
 
 Property::Array::SizeType Property::Array::Count() const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->mArray.size();
+  return DALI_LIKELY(mImpl) ? mImpl->mArray.size() : 0;
 }
 
 void Property::Array::PushBack(const Value& value)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
+
   if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
   {
     // Use ordered hash operation.
@@ -115,20 +122,30 @@ void Property::Array::PushBack(const Value& value)
 
 void Property::Array::Clear()
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  mImpl->mArray.clear();
-  mImpl->mHash = NOT_HASHED;
+  if(DALI_LIKELY(mImpl))
+  {
+    mImpl->mArray.clear();
+    mImpl->mHash = NOT_HASHED;
+  }
 }
 
 void Property::Array::Reserve(SizeType size)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
+
   mImpl->mArray.reserve(size);
 }
 
 void Property::Array::Resize(SizeType size)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
+
   if(mImpl->mArray.size() != size)
   {
     mImpl->mArray.resize(size);
@@ -143,13 +160,12 @@ void Property::Array::Resize(SizeType size)
 
 Property::Array::SizeType Property::Array::Capacity()
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->mArray.capacity();
+  return DALI_LIKELY(mImpl) ? mImpl->mArray.capacity() : 0;
 }
 
 const Property::Value& Property::Array::operator[](SizeType index) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   // Note says no bounds checking is performed so we don't need to verify mImpl as Count() will return 0 anyway
   return mImpl->mArray[index];
@@ -157,7 +173,7 @@ const Property::Value& Property::Array::operator[](SizeType index) const
 
 Property::Value& Property::Array::operator[](SizeType index)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   // Mark as we should rehash always. (Since new value might be changed by application side anytime.)
   if(mImpl->mHash != ALWAYS_REHASH)
@@ -171,12 +187,21 @@ Property::Value& Property::Array::operator[](SizeType index)
 
 Property::Array& Property::Array::operator=(const Property::Array& other)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
   if(this != &other)
   {
-    mImpl->mArray = other.mImpl->mArray;
-    mImpl->mHash  = other.mImpl->mHash;
+    if(DALI_UNLIKELY(other.mImpl == nullptr))
+    {
+      Clear();
+    }
+    else
+    {
+      if(DALI_UNLIKELY(!mImpl))
+      {
+        mImpl = new Impl();
+      }
+      mImpl->mArray = other.mImpl->mArray;
+      mImpl->mHash  = other.mImpl->mHash;
+    }
   }
   return *this;
 }
@@ -194,35 +219,37 @@ Property::Array& Property::Array::operator=(Property::Array&& other) noexcept
 
 bool Property::Array::operator==(const Property::Array& rhs) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
   // TODO : Need to check epsilon for float comparison in future. For now, just compare hash value and count.
   return Count() == rhs.Count() && GetHash() == rhs.GetHash();
 }
 
 std::size_t Property::Array::GetHash() const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->GetHash();
+  return DALI_LIKELY(mImpl) ? mImpl->GetHash() : Dali::Internal::HashUtils::INITIAL_HASH_VALUE;
 }
 
 std::ostream& operator<<(std::ostream& stream, const Property::Array& array)
 {
   stream << "Array(" << array.Count() << ") = [";
-  for(Property::Array::SizeType i = 0; i < array.Count(); ++i)
+
+  if(DALI_LIKELY(array.mImpl))
   {
-    if(i > 0)
+    for(Property::Array::SizeType i = 0; i < array.Count(); ++i)
+    {
+      if(i > 0)
+      {
+        stream << ", ";
+      }
+      stream << array.GetElementAt(i);
+    }
+
+    if(array.mImpl->mHash != NOT_HASHED)
     {
-      stream << "";
+      stream << "(hash=" << array.mImpl->mHash << ")";
     }
-    stream << array.GetElementAt(i);
   }
-  stream << "]";
 
-  if(array.mImpl->mHash != NOT_HASHED)
-  {
-    stream << "(hash=" << array.mImpl->mHash << ")";
-  }
+  stream << "]";
 
   return stream;
 }
index e7a5f8ffe86fefea6574d2cbb3f02b0fd9752073..ebbf2a0c650567ddcab9629163cf13cb0ca45b60 100644 (file)
@@ -108,8 +108,12 @@ Property::Map::Map(const std::initializer_list<KeyValuePair>& values)
 Property::Map::Map(const Property::Map& other)
 : mImpl(new Impl)
 {
-  mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
-  mImpl->mIndexValueContainer  = other.mImpl->mIndexValueContainer;
+  if(DALI_LIKELY(other.mImpl))
+  {
+    mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
+    mImpl->mIndexValueContainer  = other.mImpl->mIndexValueContainer;
+    // Keep mHash as NOT_HASHED.
+  }
 }
 
 Property::Map::Map(Property::Map&& other) noexcept
@@ -125,19 +129,29 @@ Property::Map::~Map()
 
 Property::Map::SizeType Property::Map::Count() const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size();
+  if(DALI_LIKELY(mImpl))
+  {
+    return mImpl->mStringValueContainer.size() + mImpl->mIndexValueContainer.size();
+  }
+  return 0;
 }
 
 bool Property::Map::Empty() const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty();
+  if(DALI_LIKELY(mImpl))
+  {
+    return mImpl->mStringValueContainer.empty() && mImpl->mIndexValueContainer.empty();
+  }
+  return true;
 }
 
 void Property::Map::Insert(std::string key, Value value)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
+
   if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
   {
     // Use unordered hash operation.
@@ -149,7 +163,11 @@ void Property::Map::Insert(std::string key, Value value)
 
 void Property::Map::Insert(Property::Index key, Value value)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
+
   if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
   {
     // Use unordered hash operation.
@@ -161,7 +179,8 @@ void Property::Map::Insert(Property::Index key, Value value)
 
 Property::Value& Property::Map::GetValue(SizeType position) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
+
   SizeType numStringKeys = mImpl->mStringValueContainer.size();
   SizeType numIndexKeys  = mImpl->mIndexValueContainer.size();
   DALI_ASSERT_ALWAYS(position < (numStringKeys + numIndexKeys) && "position out-of-bounds");
@@ -180,7 +199,8 @@ const std::string& Property::Map::GetKey(SizeType position) const
 {
   DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetKey() is deprecated and will be removed from next release.\n");
 
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
+
   SizeType numStringKeys = mImpl->mStringValueContainer.size();
   DALI_ASSERT_ALWAYS(position < numStringKeys && "position out-of-bounds");
 
@@ -189,7 +209,7 @@ const std::string& Property::Map::GetKey(SizeType position) const
 
 Property::Key Property::Map::GetKeyAt(SizeType position) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   SizeType numStringKeys = mImpl->mStringValueContainer.size();
   SizeType numIndexKeys  = mImpl->mIndexValueContainer.size();
@@ -211,7 +231,7 @@ StringValuePair& Property::Map::GetPair(SizeType position) const
 {
   DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: GetPair() is deprecated and will be removed from next release.\n");
 
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   SizeType numStringKeys = mImpl->mStringValueContainer.size();
 
@@ -222,11 +242,10 @@ StringValuePair& Property::Map::GetPair(SizeType position) const
 
 KeyValuePair Property::Map::GetKeyValue(SizeType position) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   SizeType numStringKeys = mImpl->mStringValueContainer.size();
   SizeType numIndexKeys  = mImpl->mIndexValueContainer.size();
-
   DALI_ASSERT_ALWAYS(position < (numStringKeys + numIndexKeys) && "position out-of-bounds");
 
   if(position < numStringKeys)
@@ -243,19 +262,20 @@ KeyValuePair Property::Map::GetKeyValue(SizeType position) const
 
 Property::Value* Property::Map::Find(std::string_view key) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  for(auto&& iter : mImpl->mStringValueContainer)
+  if(DALI_LIKELY(mImpl))
   {
-    if(key == iter.first)
+    for(auto&& iter : mImpl->mStringValueContainer)
     {
-      if(mImpl->mHash != ALWAYS_REHASH)
+      if(key == iter.first)
       {
-        // Mark as we cannot assume that hash is valid anymore.
-        // Recalculate hash always after now.
-        mImpl->mHash = ALWAYS_REHASH;
+        if(mImpl->mHash != ALWAYS_REHASH)
+        {
+          // Mark as we cannot assume that hash is valid anymore.
+          // Recalculate hash always after now.
+          mImpl->mHash = ALWAYS_REHASH;
+        }
+        return &iter.second;
       }
-      return &iter.second;
     }
   }
   return nullptr; // Not found
@@ -263,19 +283,20 @@ Property::Value* Property::Map::Find(std::string_view key) const
 
 Property::Value* Property::Map::Find(Property::Index key) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  for(auto&& iter : mImpl->mIndexValueContainer)
+  if(DALI_LIKELY(mImpl))
   {
-    if(iter.first == key)
+    for(auto&& iter : mImpl->mIndexValueContainer)
     {
-      if(mImpl->mHash != ALWAYS_REHASH)
+      if(iter.first == key)
       {
-        // Mark as we cannot assume that hash is valid anymore.
-        // Recalculate hash always after now.
-        mImpl->mHash = ALWAYS_REHASH;
+        if(mImpl->mHash != ALWAYS_REHASH)
+        {
+          // Mark as we cannot assume that hash is valid anymore.
+          // Recalculate hash always after now.
+          mImpl->mHash = ALWAYS_REHASH;
+        }
+        return &iter.second;
       }
-      return &iter.second;
     }
   }
   return nullptr; // Not found
@@ -293,19 +314,20 @@ Property::Value* Property::Map::Find(Property::Index indexKey, std::string_view
 
 Property::Value* Property::Map::Find(std::string_view key, Property::Type type) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  for(auto&& iter : mImpl->mStringValueContainer)
+  if(DALI_LIKELY(mImpl))
   {
-    if((iter.second.GetType() == type) && (key == iter.first))
+    for(auto&& iter : mImpl->mStringValueContainer)
     {
-      if(mImpl->mHash != ALWAYS_REHASH)
+      if((iter.second.GetType() == type) && (key == iter.first))
       {
-        // Mark as we cannot assume that hash is valid anymore.
-        // Recalculate hash always after now.
-        mImpl->mHash = ALWAYS_REHASH;
+        if(mImpl->mHash != ALWAYS_REHASH)
+        {
+          // Mark as we cannot assume that hash is valid anymore.
+          // Recalculate hash always after now.
+          mImpl->mHash = ALWAYS_REHASH;
+        }
+        return &iter.second;
       }
-      return &iter.second;
     }
   }
   return nullptr; // Not found
@@ -313,19 +335,20 @@ Property::Value* Property::Map::Find(std::string_view key, Property::Type type)
 
 Property::Value* Property::Map::Find(Property::Index key, Property::Type type) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  for(auto&& iter : mImpl->mIndexValueContainer)
+  if(DALI_LIKELY(mImpl))
   {
-    if((iter.second.GetType() == type) && (iter.first == key))
+    for(auto&& iter : mImpl->mIndexValueContainer)
     {
-      if(mImpl->mHash != ALWAYS_REHASH)
+      if((iter.second.GetType() == type) && (iter.first == key))
       {
-        // Mark as we cannot assume that hash is valid anymore.
-        // Recalculate hash always after now.
-        mImpl->mHash = ALWAYS_REHASH;
+        if(mImpl->mHash != ALWAYS_REHASH)
+        {
+          // Mark as we cannot assume that hash is valid anymore.
+          // Recalculate hash always after now.
+          mImpl->mHash = ALWAYS_REHASH;
+        }
+        return &iter.second;
       }
-      return &iter.second;
     }
   }
   return nullptr; // Not found
@@ -333,54 +356,60 @@ Property::Value* Property::Map::Find(Property::Index key, Property::Type type) c
 
 void Property::Map::Clear()
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  mImpl->mStringValueContainer.clear();
-  mImpl->mIndexValueContainer.clear();
-  mImpl->mHash = NOT_HASHED;
+  if(DALI_LIKELY(mImpl))
+  {
+    mImpl->mStringValueContainer.clear();
+    mImpl->mIndexValueContainer.clear();
+    mImpl->mHash = NOT_HASHED;
+  }
 }
 
 bool Property::Map::Remove(Property::Index key)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  auto iter = std::find_if(mImpl->mIndexValueContainer.begin(), mImpl->mIndexValueContainer.end(), [key](const IndexValuePair& element) { return element.first == key; });
-  if(iter != mImpl->mIndexValueContainer.end())
+  if(DALI_LIKELY(mImpl))
   {
-    if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
+    auto iter = std::find_if(mImpl->mIndexValueContainer.begin(), mImpl->mIndexValueContainer.end(), [key](const IndexValuePair& element) { return element.first == key; });
+    if(iter != mImpl->mIndexValueContainer.end())
     {
-      // Use unordered hash operation.
-      auto valueHash = iter->second.GetHash();
-      mImpl->mHash -= Dali::Internal::HashUtils::HashRawValue(key, valueHash);
+      if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
+      {
+        // Use unordered hash operation.
+        auto valueHash = iter->second.GetHash();
+        mImpl->mHash -= Dali::Internal::HashUtils::HashRawValue(key, valueHash);
+      }
+      mImpl->mIndexValueContainer.erase(iter);
+      return true;
     }
-    mImpl->mIndexValueContainer.erase(iter);
-    return true;
   }
   return false;
 }
 
 bool Property::Map::Remove(std::string_view key)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
-  auto iter = std::find_if(mImpl->mStringValueContainer.begin(), mImpl->mStringValueContainer.end(), [key](const StringValuePair& element) { return element.first == key; });
-  if(iter != mImpl->mStringValueContainer.end())
+  if(DALI_LIKELY(mImpl))
   {
-    if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
+    auto iter = std::find_if(mImpl->mStringValueContainer.begin(), mImpl->mStringValueContainer.end(), [key](const StringValuePair& element) { return element.first == key; });
+    if(iter != mImpl->mStringValueContainer.end())
     {
-      // Use unordered hash operation.
-      auto valueHash = iter->second.GetHash();
-      mImpl->mHash -= Dali::Internal::HashUtils::HashStringView(key, valueHash);
+      if(mImpl->mHash != ALWAYS_REHASH && mImpl->mHash != NOT_HASHED)
+      {
+        // Use unordered hash operation.
+        auto valueHash = iter->second.GetHash();
+        mImpl->mHash -= Dali::Internal::HashUtils::HashStringView(key, valueHash);
+      }
+      mImpl->mStringValueContainer.erase(iter);
+      return true;
     }
-    mImpl->mStringValueContainer.erase(iter);
-    return true;
   }
   return false;
 }
 
 void Property::Map::Merge(const Property::Map& from)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
 
   // Ensure we're not attempting to merge with ourself
   if(this != &from)
@@ -413,7 +442,7 @@ void Property::Map::Merge(const Property::Map& from)
 
 const Property::Value& Property::Map::operator[](std::string_view key) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   for(auto&& iter : mImpl->mStringValueContainer)
   {
@@ -428,7 +457,10 @@ const Property::Value& Property::Map::operator[](std::string_view key) const
 
 Property::Value& Property::Map::operator[](std::string_view key)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
 
   if(mImpl->mHash != ALWAYS_REHASH)
   {
@@ -452,7 +484,7 @@ Property::Value& Property::Map::operator[](std::string_view key)
 
 const Property::Value& Property::Map::operator[](Property::Index key) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  DALI_ASSERT_ALWAYS(mImpl && "Cannot use an object previously used as an r-value");
 
   for(auto&& iter : mImpl->mIndexValueContainer)
   {
@@ -467,7 +499,10 @@ const Property::Value& Property::Map::operator[](Property::Index key) const
 
 Property::Value& Property::Map::operator[](Property::Index key)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
+  if(DALI_UNLIKELY(!mImpl))
+  {
+    mImpl = new Impl();
+  }
 
   if(mImpl->mHash != ALWAYS_REHASH)
   {
@@ -491,13 +526,22 @@ Property::Value& Property::Map::operator[](Property::Index key)
 
 Property::Map& Property::Map::operator=(const Property::Map& other)
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
   if(this != &other)
   {
-    mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
-    mImpl->mIndexValueContainer  = other.mImpl->mIndexValueContainer;
-    mImpl->mHash                 = other.mImpl->mHash;
+    if(DALI_UNLIKELY(other.mImpl == nullptr))
+    {
+      Clear();
+    }
+    else
+    {
+      if(DALI_UNLIKELY(!mImpl))
+      {
+        mImpl = new Impl();
+      }
+      mImpl->mStringValueContainer = other.mImpl->mStringValueContainer;
+      mImpl->mIndexValueContainer  = other.mImpl->mIndexValueContainer;
+      mImpl->mHash                 = other.mImpl->mHash;
+    }
   }
   return *this;
 }
@@ -515,23 +559,20 @@ Property::Map& Property::Map::operator=(Property::Map&& other) noexcept
 
 bool Property::Map::operator==(const Property::Map& rhs) const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-
   // TODO : Need to check epsilon for float comparison in future. For now, just compare hash value and count.
   return Count() == rhs.Count() && GetHash() == rhs.GetHash();
 }
 
 std::size_t Property::Map::GetHash() const
 {
-  DALI_ASSERT_DEBUG(mImpl && "Cannot use an object previously used as an r-value");
-  return mImpl->GetHash();
+  return DALI_LIKELY(mImpl) ? mImpl->GetHash() : Dali::Internal::HashUtils::INITIAL_HASH_VALUE;
 }
 
 std::ostream& operator<<(std::ostream& stream, const Property::Map& map)
 {
   stream << "Map(" << map.Count() << ") = {";
 
-  if(map.mImpl)
+  if(DALI_LIKELY(map.mImpl))
   {
     int32_t count = 0;
     // Output the String-Value pairs
@@ -553,15 +594,15 @@ std::ostream& operator<<(std::ostream& stream, const Property::Map& map)
       }
       stream << iter.first << ":" << iter.second;
     }
+
+    if(map.mImpl->mHash != NOT_HASHED)
+    {
+      stream << "(hash=" << map.mImpl->mHash << ")";
+    }
   }
 
   stream << "}";
 
-  if(map.mImpl->mHash != NOT_HASHED)
-  {
-    stream << "(hash=" << map.mImpl->mHash << ")";
-  }
-
   return stream;
 }