[dali_1.9.32] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / public-api / object / property-value.cpp
index 695956d..09bb5c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <ostream>
 
 // INTERNAL INCLUDES
-#include <dali/public-api/object/any.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/extents.h>
 #include <dali/public-api/math/angle-axis.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/matrix3.h>
+#include <dali/public-api/math/quaternion.h>
 #include <dali/public-api/math/radian.h>
+#include <dali/public-api/math/rect.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
-#include <dali/public-api/math/matrix3.h>
-#include <dali/public-api/math/matrix.h>
-#include <dali/public-api/math/rect.h>
-#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/object/property-array.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/property-types.h>
-#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
 
 struct Property::Value::Impl
 {
+  ~Impl()
+  {
+    // Destroy the current object stored in Data union memory.
+    Destroy();
+  }
+
+  Impl(const Impl&) = delete;
+
+  Impl(Impl&&) = delete;
+
+  Impl& operator=(Impl&&) = delete;
+
   Impl()
-  : mType( Property::NONE )
   {
+    static_assert(sizeof(Impl) == 16);
+    static_assert(alignof(Impl) == alignof(Impl*));
+
+    SetType(Property::NONE);
   }
 
-  Impl(bool boolValue)
-  : mType( PropertyTypes::Get<bool>() ),
-    mValue( boolValue )
+  Impl(bool booleanValue)
   {
+    SetType(Property::BOOLEAN);
+    mData.mBool.member = booleanValue;
   }
 
   Impl(float floatValue)
-  : mType( PropertyTypes::Get<float>() ),
-    mValue( floatValue )
   {
+    SetType(Property::FLOAT);
+    mData.mFloat.member = floatValue;
+  }
+
+  Impl(int32_t integerValue)
+  {
+    SetType(Property::INTEGER);
+    mData.mInt.member = integerValue;
+  }
+
+  Impl(Vector2 vectorValue)
+  {
+    SetType(Property::VECTOR2);
+    ConstructInplace(mData.mVector2.member, std::move(vectorValue));
+  }
+
+  Impl(Vector3 vectorValue)
+  {
+    SetType(Property::VECTOR3);
+    ConstructInplace(mData.mVector3.member, std::move(vectorValue));
+  }
+
+  Impl(Extents extentsValue)
+  {
+    SetType(Property::EXTENTS);
+    ConstructInplace(mData.mExtents.member, std::move(extentsValue));
+  }
+
+  Impl(Property::Map mapValue)
+  {
+    SetType(Property::MAP);
+    ConstructInplace(mData.mMap.member, std::move(mapValue));
+  }
+
+  Impl(Property::Array arrayValue)
+  {
+    SetType(Property::ARRAY);
+    ConstructInplace(mData.mArray.member, std::move(arrayValue));
+  }
+
+  Impl(std::string stringValue)
+  {
+    SetType(Property::STRING);
+    mData.mString.member = new std::string(std::move(stringValue));
+  }
+
+  Impl(Rect<int32_t> rectValue)
+  {
+    SetType(Property::RECTANGLE);
+    mData.mRect.member = new Rect<int32_t>(std::move(rectValue));
+  }
+
+  Impl(Vector4 vectorValue)
+  {
+    SetType(Property::VECTOR4);
+    mData.mVector4.member = new Vector4(std::move(vectorValue));
+  }
+
+  Impl(Matrix3 matrixValue)
+  {
+    SetType(Property::MATRIX3);
+    mData.mMatrix3.member = new Matrix3(std::move(matrixValue));
+  }
+
+  Impl(Matrix matrixValue)
+  {
+    SetType(Property::MATRIX);
+    mData.mMatrix.member = new Matrix(std::move(matrixValue));
+  }
+
+  Impl(AngleAxis angleAxisValue)
+  {
+    SetType(Property::ROTATION);
+    mData.mAngleAxis.member = new AngleAxis(std::move(angleAxisValue));
+  }
+
+  Type GetType() const
+  {
+    return mData.mType.type;
+  }
+
+  bool GetBool() const
+  {
+    return mData.mBool.member;
+  }
+
+  int32_t GetInt() const
+  {
+    return mData.mInt.member;
+  }
+
+  float GetFloat() const
+  {
+    return mData.mFloat.member;
+  }
+
+  const Extents& GetExtents() const
+  {
+    return mData.mExtents.member;
+  }
+
+  const Vector2& GetVector2() const
+  {
+    return mData.mVector2.member;
+  }
+
+  const Vector3& GetVector3() const
+  {
+    return mData.mVector3.member;
+  }
+
+  const Property::Map& GetMap() const
+  {
+    return mData.mMap.member;
   }
 
-  Impl(int integerValue)
-  : mType( PropertyTypes::Get<int>() ),
-    mValue( integerValue )
+  const Property::Array& GetArray() const
   {
+    return mData.mArray.member;
   }
 
-  Impl(unsigned int unsignedIntegerValue)
-  : mType( PropertyTypes::Get<unsigned int>() ),
-    mValue( unsignedIntegerValue )
+  const Vector4& GetVector4() const
   {
+    return *(mData.mVector4.member);
   }
 
-  Impl(const Vector2& vectorValue)
-  : mType( PropertyTypes::Get<Vector2>() ),
-    mValue( vectorValue )
+  const Matrix3& GetMatrix3() const
   {
+    return *(mData.mMatrix3.member);
   }
 
-  Impl(const Vector3& vectorValue)
-  : mType( PropertyTypes::Get<Vector3>() ),
-    mValue( vectorValue )
+  const Matrix& GetMatrix() const
   {
+    return *(mData.mMatrix.member);
   }
 
-  Impl(const Vector4& vectorValue)
-  : mType( PropertyTypes::Get<Vector4>() ),
-    mValue( vectorValue )
+  const AngleAxis& GetAngleAxis() const
   {
+    return *(mData.mAngleAxis.member);
   }
 
-  Impl(const Matrix3& matrixValue)
-  : mType(PropertyTypes::Get<Matrix3>()),
-    mValue(matrixValue)
+  const std::string& GetString() const
   {
+    return *(mData.mString.member);
   }
 
-  Impl(const Matrix& matrixValue)
-  : mType(PropertyTypes::Get<Matrix>()),
-    mValue(matrixValue)
+  const Rect<int32_t>& GetRect() const
   {
+    return *(mData.mRect.member);
   }
 
-  Impl(const AngleAxis& angleAxisValue)
-  : mType( PropertyTypes::Get<AngleAxis>() ),
-    mValue( angleAxisValue )
+  Property::Map* GetMapPtr()
   {
+    return &(mData.mMap.member);
   }
 
-  Impl(const Quaternion& quaternionValue)
-  : mType( PropertyTypes::Get<Quaternion>() ),
-    mValue( quaternionValue )
+  Property::Array* GetArrayPtr()
   {
+    return &(mData.mArray.member);
   }
 
-  Impl(const std::string& stringValue)
-    : mType( PropertyTypes::Get<std::string>() ),
-      mValue( stringValue )
+  Impl& operator=(const Impl& other)
   {
+    const bool isSameType = GetType() == other.GetType();
+
+    if(!isSameType)
+    {
+      Destroy();
+      SetType(other.GetType());
+    }
+
+    switch(GetType())
+    {
+      case Property::NONE:
+      {
+        break;
+      }
+      case Property::BOOLEAN:
+      {
+        mData.mBool.member = other.GetBool();
+        break;
+      }
+      case Property::FLOAT:
+      {
+        mData.mFloat.member = other.GetFloat();
+        break;
+      }
+      case Property::INTEGER:
+      {
+        mData.mInt.member = other.GetInt();
+        break;
+      }
+      case Property::EXTENTS:
+      {
+        auto obj = other.GetExtents();
+        ConstructInplace(mData.mExtents.member, std::move(obj));
+        break;
+      }
+      case Property::VECTOR2:
+      {
+        auto obj = other.GetVector2();
+        ConstructInplace(mData.mVector2.member, std::move(obj));
+        break;
+      }
+      case Property::VECTOR3:
+      {
+        auto obj = other.GetVector3();
+        ConstructInplace(mData.mVector3.member, std::move(obj));
+        break;
+      }
+      case Property::ARRAY:
+      {
+        auto obj = other.GetArray();
+        ConstructInplace(mData.mArray.member, std::move(obj));
+        break;
+      }
+      case Property::MAP:
+      {
+        auto obj = other.GetMap();
+        ConstructInplace(mData.mMap.member, std::move(obj));
+        break;
+      }
+      case Property::VECTOR4:
+      {
+        if(isSameType)
+        {
+          *mData.mVector4.member = other.GetVector4();
+        }
+        else
+        {
+          mData.mVector4.member = new Vector4(other.GetVector4());
+        }
+        break;
+      }
+      case Property::MATRIX3:
+      {
+        if(isSameType)
+        {
+          *mData.mMatrix3.member = other.GetMatrix3();
+        }
+        else
+        {
+          mData.mMatrix3.member = new Matrix3(other.GetMatrix3());
+        }
+        break;
+      }
+      case Property::MATRIX:
+      {
+        if(isSameType)
+        {
+          *mData.mMatrix.member = other.GetMatrix();
+        }
+        else
+        {
+          mData.mMatrix.member = new Matrix(other.GetMatrix());
+        }
+        break;
+      }
+      case Property::RECTANGLE:
+      {
+        if(isSameType)
+        {
+          *mData.mRect.member = other.GetRect();
+        }
+        else
+        {
+          mData.mRect.member = new Rect<int32_t>(other.GetRect());
+        }
+        break;
+      }
+      case Property::ROTATION:
+      {
+        if(isSameType)
+        {
+          *mData.mAngleAxis.member = other.GetAngleAxis();
+        }
+        else
+        {
+          mData.mAngleAxis.member = new AngleAxis(other.GetAngleAxis());
+        }
+        break;
+      }
+      case Property::STRING:
+      {
+        if(isSameType)
+        {
+          *mData.mString.member = other.GetString();
+        }
+        else
+        {
+          mData.mString.member = new std::string(other.GetString());
+        }
+        break;
+      }
+    }
+    return *this;
   }
 
-  Impl(const Rect<int>& rect)
-    : mType( PropertyTypes::Get<Rect<int> >() ),
-      mValue( rect )
+private:
+  void SetType(Type typeValue)
   {
+    mData.mType.type = typeValue;
   }
 
-  Impl(Property::Map container)
-    : mType( PropertyTypes::Get<Property::Map >() ),
-      mValue( container )
+  /**
+   * This helper function takes a typed(Tp) memory location( member)
+   * and a object of same type( val ) and move constructs a new object of
+   * same type(Tp) in the memory location( member) using placement new.
+   * after this function call member location will have a object of type Tp.
+   */
+  template<typename Tp>
+  void ConstructInplace(Tp& member, Tp&& val)
   {
+    new(&member) Tp(std::forward<Tp>(val));
   }
 
-  Impl(Property::Array container)
-    : mType( PropertyTypes::Get<Property::Array >() ),
-      mValue( container )
+  /**
+  * Destroy the object created in the Data union memory by probing the
+  * type and calling the appropriate destructor.
+  * and also reset the type and memory location to reflect that .
+  */
+  void Destroy()
   {
+    switch(GetType())
+    {
+      case Property::NONE:
+      case Property::BOOLEAN:
+      case Property::FLOAT:
+      case Property::INTEGER:
+      {
+        break; // nothing to do
+      }
+      case Property::EXTENTS:
+      {
+        mData.mExtents.member.~Extents();
+        break;
+      }
+      case Property::VECTOR2:
+      {
+        mData.mVector2.member.~Vector2();
+        break;
+      }
+      case Property::VECTOR3:
+      {
+        mData.mVector3.member.~Vector3();
+        break;
+      }
+      case Property::ARRAY:
+      {
+        using array = Property::Array;
+        mData.mArray.member.~array();
+        break;
+      }
+      case Property::MAP:
+      {
+        using map = Property::Map;
+        mData.mMap.member.~map();
+        break;
+      }
+      case Property::VECTOR4:
+      {
+        delete mData.mVector4.member;
+        break;
+      }
+      case Property::MATRIX3:
+      {
+        delete mData.mMatrix3.member;
+        break;
+      }
+      case Property::MATRIX:
+      {
+        delete mData.mMatrix.member;
+        break;
+      }
+      case Property::RECTANGLE:
+      {
+        delete mData.mRect.member;
+        break;
+      }
+      case Property::ROTATION:
+      {
+        delete mData.mAngleAxis.member;
+        break;
+      }
+      case Property::STRING:
+      {
+        delete mData.mString.member;
+        break;
+      }
+    }
   }
 
-  Type mType;
+  /*
+   * This wrapper struct is used for
+   * storing Type in every union member
+   * and can acess it from non active member
+   * of the uninon without invoking UB. this is
+   * possible because of CIS(common initial sequence)
+   * http://eel.is/c++draft/class.mem#general-25
+   */
+  template<typename T>
+  struct UnionMember
+  {
+    Type type;
+    T    member;
+  };
+
+  /**
+   * Tagged union implementation.
+   *
+   * This Data union contains non trivial data
+   * types Map and Array, the default constructor
+   * and destructors are deleted by the compiler
+   * so we provided empty constructor and destructor
+   * just to pacify the compiler.
+   * The only job of this union to give a typed memory buffer to the
+   * Impl class which can construct the appropriate object
+   * using placement new.
+   * As Impl class explicitly construct the object and keeps track of the
+   * object it creates and then destroys them in the ~Impl() this will not leak
+   * any memory.
+   */
+  union Data
+  {
+    Data()
+    {
+    }
+    ~Data()
+    {
+    }
+
+    UnionMember<bool>            mBool;
+    UnionMember<int32_t>         mInt;
+    UnionMember<float>           mFloat;
+    UnionMember<Extents>         mExtents;
+    UnionMember<Vector2>         mVector2;
+    UnionMember<Vector3>         mVector3;
+    UnionMember<Property::Map>   mMap;
+    UnionMember<Property::Array> mArray;
+    UnionMember<Vector4*>        mVector4;
+    UnionMember<Matrix3*>        mMatrix3;
+    UnionMember<Matrix*>         mMatrix;
+    UnionMember<AngleAxis*>      mAngleAxis;
+    UnionMember<std::string*>    mString;
+    UnionMember<Rect<int32_t>*>  mRect;
+    struct
+    {
+      Type type;
+    } mType;
+  };
 
-  typedef Any AnyValue;
-  AnyValue mValue;
+  Data mData;
 };
 
 Property::Value::Value()
-: mImpl( NULL )
+: mImpl(nullptr)
 {
-  mImpl = new Impl();
 }
 
-Property::Value::Value(bool boolValue)
-: mImpl( NULL )
+Property::Value::Value(bool booleanValue)
+: mImpl(new Impl(booleanValue))
 {
-  mImpl = new Impl( boolValue );
 }
 
 Property::Value::Value(float floatValue)
-: mImpl( NULL )
+: mImpl(new Impl(floatValue))
 {
-  mImpl = new Impl( floatValue );
 }
 
-Property::Value::Value(int integerValue)
-: mImpl( NULL )
+Property::Value::Value(int32_t integerValue)
+: mImpl(new Impl(integerValue))
 {
-  mImpl = new Impl( integerValue );
-}
-
-Property::Value::Value(unsigned int unsignedIntegerValue)
-: mImpl( NULL )
-{
-  mImpl = new Impl( unsignedIntegerValue );
 }
 
 Property::Value::Value(const Vector2& vectorValue)
-: mImpl( NULL )
+: mImpl(new Impl(vectorValue))
 {
-  mImpl = new Impl( vectorValue );
 }
 
 Property::Value::Value(const Vector3& vectorValue)
-: mImpl( NULL )
+: mImpl(new Impl(vectorValue))
 {
-  mImpl = new Impl( vectorValue );
 }
 
 Property::Value::Value(const Vector4& vectorValue)
-: mImpl( NULL )
+: mImpl(new Impl(vectorValue))
 {
-  mImpl = new Impl( vectorValue );
 }
 
 Property::Value::Value(const Matrix3& matrixValue)
-: mImpl( NULL )
+: mImpl(new Impl(matrixValue))
 {
-  mImpl = new Impl( matrixValue );
 }
 
 Property::Value::Value(const Matrix& matrixValue)
-: mImpl( NULL )
+: mImpl(new Impl(matrixValue))
+{
+}
+
+Property::Value::Value(const Rect<int32_t>& rectValue)
+: mImpl(new Impl(rectValue))
 {
-  mImpl = new Impl( matrixValue );
 }
 
-Property::Value::Value(const Rect<int>& rect)
-: mImpl( NULL )
+Property::Value::Value(const Rect<float>& rectValue)
+: mImpl(new Impl(Vector4(rectValue.x, rectValue.y, rectValue.width, rectValue.height)))
 {
-  mImpl = new Impl( rect );
 }
 
 Property::Value::Value(const AngleAxis& angleAxisValue)
-: mImpl( NULL )
+: mImpl(new Impl(angleAxisValue))
 {
-  mImpl = new Impl( angleAxisValue );
 }
 
 Property::Value::Value(const Quaternion& quaternionValue)
 {
-  mImpl = new Impl( quaternionValue );
+  AngleAxis angleAxisValue;
+  quaternionValue.ToAxisAngle(angleAxisValue.axis, angleAxisValue.angle);
+  mImpl = new Impl(std::move(angleAxisValue));
 }
 
-Property::Value::Value(const std::string& stringValue)
+Property::Value::Value(std::string stringValue)
+: mImpl(new Impl(std::move(stringValue)))
 {
-  mImpl = new Impl( stringValue );
 }
 
-Property::Value::Value(const char *stringValue)
+Property::Value::Value(const char* stringValue)
+: mImpl(nullptr)
 {
-  mImpl = new Impl( std::string(stringValue) );
+  if(stringValue) // string constructor is undefined with nullptr
+  {
+    mImpl = new Impl(std::string(stringValue));
+  }
+  else
+  {
+    mImpl = new Impl(std::string());
+  }
 }
 
-Property::Value::Value(Property::Array &arrayValue)
+Property::Value::Value(Property::Array arrayValue)
+: mImpl(new Impl(std::move(arrayValue)))
 {
-  mImpl = new Impl( arrayValue );
 }
 
-Property::Value::Value(Property::Map &mapValue)
+Property::Value::Value(Property::Map mapValue)
+: mImpl(new Impl(std::move(mapValue)))
 {
-  mImpl = new Impl( mapValue );
 }
 
+Property::Value::Value(const Extents& extentsValue)
+: mImpl(new Impl(extentsValue))
+{
+}
 
-Property::Value::~Value()
+Property::Value::Value(const std::initializer_list<KeyValuePair>& values)
+: mImpl(new Impl(Property::Map(values)))
 {
-  delete mImpl;
 }
 
-Property::Value::Value(const Value& value)
+Property::Value::Value(Type type)
+: mImpl(nullptr)
 {
-  switch (value.GetType())
+  switch(type)
   {
     case Property::BOOLEAN:
     {
-      mImpl = new Impl( value.Get<bool>() );
+      mImpl = new Impl(false);
       break;
     }
-
     case Property::FLOAT:
     {
-      mImpl = new Impl( value.Get<float>() );
+      mImpl = new Impl(0.f);
       break;
     }
-
     case Property::INTEGER:
     {
-      mImpl = new Impl( value.Get<int>() );
-      break;
-    }
-
-    case Property::UNSIGNED_INTEGER:
-    {
-      mImpl = new Impl( value.Get<unsigned int>() );
+      mImpl = new Impl(0);
       break;
     }
-
     case Property::VECTOR2:
     {
-      mImpl = new Impl( value.Get<Vector2>() );
+      mImpl = new Impl(Vector2::ZERO);
       break;
     }
-
     case Property::VECTOR3:
     {
-      mImpl = new Impl( value.Get<Vector3>() );
+      mImpl = new Impl(Vector3::ZERO);
       break;
     }
-
     case Property::VECTOR4:
     {
-      mImpl = new Impl( value.Get<Vector4>() );
+      mImpl = new Impl(Vector4::ZERO);
       break;
     }
-
     case Property::RECTANGLE:
     {
-      mImpl = new Impl( value.Get<Rect<int> >() );
+      mImpl = new Impl(Rect<int32_t>());
       break;
     }
-
     case Property::ROTATION:
     {
-      // Orientations have two representations
-      DALI_ASSERT_DEBUG( typeid(Quaternion) == value.mImpl->mValue.GetType() ||
-                         typeid(AngleAxis)  == value.mImpl->mValue.GetType() );
-
-      if ( typeid(Quaternion) == value.mImpl->mValue.GetType() )
-      {
-        mImpl = new Impl( value.Get<Quaternion>() );
-      }
-      else
-      {
-        mImpl = new Impl( value.Get<AngleAxis>() );
-      }
+      mImpl = new Impl(AngleAxis());
       break;
     }
-
-    case Property::MATRIX3:
+    case Property::STRING:
     {
-      mImpl = new Impl( value.Get<Matrix3>());
+      mImpl = new Impl(std::string());
       break;
     }
-
     case Property::MATRIX:
     {
-      mImpl = new Impl( value.Get<Matrix>());
+      mImpl = new Impl(Matrix());
       break;
     }
-
-    case Property::STRING:
+    case Property::MATRIX3:
     {
-      mImpl = new Impl( value.Get<std::string>() );
+      mImpl = new Impl(Matrix3());
+      break;
+    }
+    case Property::ARRAY:
+    {
+      mImpl = new Impl(Property::Array());
       break;
     }
-
     case Property::MAP:
     {
-      mImpl = new Impl( value.Get<Property::Map>() );
+      mImpl = new Impl(Property::Map());
       break;
     }
-
-    case Property::ARRAY:
+    case Property::EXTENTS:
     {
-      mImpl = new Impl( value.Get<Property::Array>() );
+      mImpl = new Impl(Extents());
       break;
     }
-
-    case Property::NONE: // fall
-    default:
+    case Property::NONE:
     {
-      mImpl = new Impl();
+      // No need to create an Impl
       break;
     }
   }
 }
 
-Property::Value::Value(Type type)
+Property::Value::Value(const Property::Value& value)
+: mImpl(nullptr)
 {
-  switch (type)
-  {
-    case Property::BOOLEAN:
-    {
-      mImpl = new Impl( false );
-      break;
-    }
+  // reuse assignment operator
+  operator=(value);
+}
 
-    case Property::FLOAT:
-    {
-      mImpl = new Impl( 0.f );
-      break;
-    }
+Property::Value::Value(Property::Value&& value) noexcept
+: mImpl(value.mImpl)
+{
+  value.mImpl = nullptr;
+}
 
-    case Property::INTEGER:
-    {
-      mImpl = new Impl( 0 );
-      break;
-    }
+Property::Value& Property::Value::operator=(const Property::Value& value)
+{
+  if(this == &value)
+  {
+    // skip self assignment
+    return *this;
+  }
 
-    case Property::UNSIGNED_INTEGER:
+  if(value.mImpl)
+  {
+    if(!mImpl)
     {
-      mImpl = new Impl( 0U );
-      break;
+      mImpl = new Impl();
     }
 
-    case Property::VECTOR2:
-    {
-      mImpl = new Impl( Vector2::ZERO );
-      break;
-    }
+    *mImpl = *(value.mImpl);
+  }
+  else
+  {
+    delete mImpl;
+    mImpl = nullptr;
+  }
 
-    case Property::VECTOR3:
-    {
-      mImpl = new Impl( Vector3::ZERO );
-      break;
-    }
-
-    case Property::VECTOR4:
-    {
-      mImpl = new Impl( Vector4::ZERO );
-      break;
-    }
-
-    case Property::RECTANGLE:
-    {
-      mImpl = new Impl( Rect<int>(0,0,0,0) );
-      break;
-    }
+  return *this;
+}
 
-    case Property::ROTATION:
-    {
-      mImpl = new Impl( Quaternion( Radian(0.f), Vector3::YAXIS) );
-      break;
-    }
+Property::Value& Property::Value::operator=(Property::Value&& value) noexcept
+{
+  if(this != &value)
+  {
+    delete mImpl;
+    mImpl       = value.mImpl;
+    value.mImpl = nullptr;
+  }
 
-    case Property::STRING:
-    {
-      mImpl = new Impl( std::string() );
-      break;
-    }
+  return *this;
+}
 
-    case Property::MAP:
-    {
-      mImpl = new Impl( Property::Map() );
-      break;
-    }
+Property::Value::~Value()
+{
+  delete mImpl;
+}
 
-    case Property::MATRIX:
-    {
-      mImpl = new Impl( Matrix() );
-      break;
-    }
+Property::Type Property::Value::GetType() const
+{
+  return mImpl ? mImpl->GetType() : Property::NONE;
+}
 
-    case Property::MATRIX3:
+bool Property::Value::Get(bool& booleanValue) const
+{
+  bool converted = false;
+  if(mImpl)
+  {
+    if(mImpl->GetType() == BOOLEAN)
     {
-      mImpl = new Impl( Matrix3() );
-      break;
+      booleanValue = mImpl->GetBool();
+      converted    = true;
     }
-
-    case Property::ARRAY:
+    else if(mImpl->GetType() == INTEGER)
     {
-      mImpl = new Impl( Property::Array() );
-      break;
-    }
-
-    case Property::NONE: // fall
-    default:
-    {
-      mImpl = new Impl();
-      break;
+      booleanValue = mImpl->GetInt();
+      converted    = true;
     }
   }
+  return converted;
 }
 
-Property::Value& Property::Value::operator=(const Property::Value& value)
+bool Property::Value::Get(float& floatValue) const
 {
-  if (this == &value)
+  bool converted = false;
+  if(mImpl)
   {
-    // skip self assignment
-    return *this;
-  }
-
-  mImpl->mType = value.GetType();
-
-  switch (mImpl->mType)
-  {
-    case Property::BOOLEAN:
+    if(mImpl->GetType() == FLOAT)
     {
-      mImpl->mValue = value.Get<bool>();
-      break;
+      floatValue = mImpl->GetFloat();
+      converted  = true;
     }
-
-    case Property::FLOAT:
+    else if(mImpl->GetType() == BOOLEAN)
     {
-      mImpl->mValue = value.Get<float>();
-      break;
+      floatValue = static_cast<float>(mImpl->GetBool());
+      converted  = true;
     }
-
-    case Property::INTEGER:
+    else if(mImpl->GetType() == INTEGER)
     {
-      mImpl->mValue = value.Get<int>();
-      break;
+      floatValue = static_cast<float>(mImpl->GetInt());
+      converted  = true;
     }
+  }
+  return converted;
+}
 
-    case Property::UNSIGNED_INTEGER:
+bool Property::Value::Get(int32_t& integerValue) const
+{
+  bool converted = false;
+  if(mImpl)
+  {
+    if(mImpl->GetType() == INTEGER)
     {
-      mImpl->mValue = value.Get<unsigned int>();
-      break;
+      integerValue = mImpl->GetInt();
+      converted    = true;
     }
-
-    case Property::VECTOR2:
+    else if(mImpl->GetType() == BOOLEAN)
     {
-      mImpl->mValue = value.Get<Vector2>();
-      break;
+      integerValue = mImpl->GetBool();
+      converted    = true;
     }
-
-    case Property::VECTOR3:
+    else if(mImpl->GetType() == FLOAT)
     {
-      mImpl->mValue = value.Get<Vector3>();
-      break;
+      integerValue = static_cast<int32_t>(mImpl->GetFloat());
+      converted    = true;
     }
+  }
+  return converted;
+}
 
-    case Property::VECTOR4:
+bool Property::Value::Get(Vector2& vectorValue) const
+{
+  bool converted = false;
+  if(mImpl)
+  {
+    if(mImpl->GetType() == VECTOR4)
     {
-      mImpl->mValue = value.Get<Vector4>();
-      break;
+      vectorValue = mImpl->GetVector4();
+      converted   = true;
     }
-
-    case Property::RECTANGLE:
+    else if(mImpl->GetType() == VECTOR2)
     {
-      mImpl->mValue = value.Get<Rect<int> >();
-      break;
+      vectorValue = mImpl->GetVector2();
+      converted   = true;
     }
-
-    case Property::ROTATION:
+    else if(mImpl->GetType() == VECTOR3)
     {
-      // Orientations have two representations
-      DALI_ASSERT_DEBUG( typeid(Quaternion) == value.mImpl->mValue.GetType() ||
-                         typeid(AngleAxis)  == value.mImpl->mValue.GetType() );
-
-      if ( typeid(Quaternion) == value.mImpl->mValue.GetType() )
-      {
-        mImpl = new Impl( value.Get<Quaternion>() );
-      }
-      else
-      {
-        mImpl = new Impl( value.Get<AngleAxis>() );
-      }
-      break;
+      vectorValue = mImpl->GetVector3();
+      converted   = true;
     }
+  }
+  return converted;
+}
 
-    case Property::STRING:
+bool Property::Value::Get(Vector3& vectorValue) const
+{
+  bool converted = false;
+  if(mImpl)
+  {
+    if(mImpl->GetType() == VECTOR4)
     {
-      mImpl->mValue = value.Get<std::string>();
-      break;
+      vectorValue = mImpl->GetVector4();
+      converted   = true;
     }
-
-    case Property::MATRIX:
+    else if(mImpl->GetType() == VECTOR2)
     {
-      mImpl->mValue = value.Get<Matrix>();
-      break;
+      vectorValue = mImpl->GetVector2();
+      converted   = true;
     }
-
-    case Property::MATRIX3:
+    else if(mImpl->GetType() == VECTOR3)
     {
-      mImpl->mValue = value.Get<Matrix3>();
-      break;
+      vectorValue = mImpl->GetVector3();
+      converted   = true;
     }
+  }
+  return converted;
+}
 
-    case Property::MAP:
+bool Property::Value::Get(Vector4& vectorValue) const
+{
+  bool converted = false;
+  if(mImpl)
+  {
+    if(mImpl->GetType() == VECTOR4)
     {
-      mImpl->mValue = value.Get<Property::Map>();
-      break;
+      vectorValue = mImpl->GetVector4();
+      converted   = true;
     }
-
-    case Property::ARRAY:
+    else if(mImpl->GetType() == VECTOR2)
     {
-      mImpl->mValue = value.Get<Property::Array>();
-      break;
+      vectorValue = mImpl->GetVector2();
+      converted   = true;
     }
-
-    case Property::NONE: // fall
-    default:
+    else if(mImpl->GetType() == VECTOR3)
     {
-      mImpl->mValue = Impl::AnyValue(0);
-      break;
+      vectorValue = mImpl->GetVector3();
+      converted   = true;
     }
   }
-
-  return *this;
-}
-
-Property::Type Property::Value::GetType() const
-{
-  return mImpl->mType;
+  return converted;
 }
 
-void Property::Value::Get(bool& boolValue) const
+bool Property::Value::Get(Matrix3& matrixValue) const
 {
-  DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" );  // AnyCast does asserted type checking
-
-  boolValue = AnyCast<bool>(mImpl->mValue);
-}
-
-void Property::Value::Get(float& floatValue) const
-{
-  DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
-
-  floatValue = AnyCast<float>(mImpl->mValue);
-}
-
-void Property::Value::Get(int& integerValue) const
-{
-  DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
-
-  integerValue = AnyCast<int>(mImpl->mValue);
-}
-
-void Property::Value::Get(unsigned int& unsignedIntegerValue) const
-{
-  DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
-
-  unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
-}
-
-void Property::Value::Get(Vector2& vectorValue) const
-{
-  DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
-
-  vectorValue = AnyCast<Vector2>(mImpl->mValue);
-}
-
-void Property::Value::Get(Vector3& vectorValue) const
-{
-  DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
-
-  vectorValue = AnyCast<Vector3>(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == MATRIX3))
+  {
+    matrixValue = mImpl->GetMatrix3();
+    converted   = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(Vector4& vectorValue) const
+bool Property::Value::Get(Matrix& matrixValue) const
 {
-  DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
-
-  vectorValue = AnyCast<Vector4>(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == MATRIX))
+  {
+    matrixValue = mImpl->GetMatrix();
+    converted   = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(Matrix3& matrixValue) const
+bool Property::Value::Get(Rect<int32_t>& rectValue) const
 {
-  DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
-  matrixValue = AnyCast<Matrix3>(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == RECTANGLE))
+  {
+    rectValue = mImpl->GetRect();
+    converted = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(Matrix& matrixValue) const
+bool Property::Value::Get(AngleAxis& angleAxisValue) const
 {
-  DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
-  matrixValue = AnyCast<Matrix>(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == ROTATION))
+  {
+    angleAxisValue = mImpl->GetAngleAxis();
+    converted      = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(Rect<int>& rect) const
+bool Property::Value::Get(Quaternion& quaternionValue) const
 {
-  DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
-
-  rect = AnyCast<Rect<int> >(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == ROTATION))
+  {
+    auto& obj       = mImpl->GetAngleAxis();
+    quaternionValue = Quaternion(obj.angle, obj.axis);
+    converted       = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(AngleAxis& angleAxisValue) const
+bool Property::Value::Get(std::string& stringValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
-
-  // Orientations have two representations
-  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
-                     typeid(AngleAxis)  == mImpl->mValue.GetType() );
-
-  if ( typeid(Quaternion) == mImpl->mValue.GetType() )
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == STRING))
   {
-    Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
-
-    quaternion.ToAxisAngle( angleAxisValue.axis, angleAxisValue.angle );
-  }
-  else
-  {
-    angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
+    stringValue.assign(mImpl->GetString());
+    converted = true;
   }
+  return converted;
 }
 
-void Property::Value::Get(Quaternion& quaternionValue) const
+bool Property::Value::Get(Property::Array& arrayValue) const
 {
-  DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
-
-  // Orientations have two representations
-  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
-               typeid(AngleAxis)  == mImpl->mValue.GetType() );
-
-  if ( typeid(Quaternion) == mImpl->mValue.GetType() )
-  {
-    quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
-  }
-  else
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == ARRAY))
   {
-    AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
-
-    quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
+    arrayValue = mImpl->GetArray();
+    converted  = true;
   }
+  return converted;
 }
 
-void Property::Value::Get(std::string &out) const
+bool Property::Value::Get(Property::Map& mapValue) const
 {
-  DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
-
-  out = AnyCast<std::string>(mImpl->mValue);
+  bool converted = false;
+  if(mImpl && (mImpl->GetType() == MAP))
+  {
+    mapValue  = mImpl->GetMap();
+    converted = true;
+  }
+  return converted;
 }
 
-void Property::Value::Get(Property::Array &out) const
+Property::Array const* Property::Value::GetArray() const
 {
-  DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
-
-  out = AnyCast<Property::Array>(mImpl->mValue);
+  if(mImpl && (mImpl->GetType() == ARRAY))
+  {
+    return mImpl->GetArrayPtr();
+  }
+  return nullptr;
 }
 
-void Property::Value::Get(Property::Map &out) const
+Property::Array* Property::Value::GetArray()
 {
-  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
-
-  out = AnyCast<Property::Map>(mImpl->mValue);
+  Property::Array* array = nullptr;
+  if(mImpl && (mImpl->GetType() == ARRAY)) // type cannot change in mImpl so array is allocated
+  {
+    array = mImpl->GetArrayPtr();
+  }
+  return array;
 }
 
-Property::Value& Property::Value::GetValue(const std::string& key) const
+Property::Map const* Property::Value::GetMap() const
 {
-  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
-
-  Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-
-  DALI_ASSERT_DEBUG(container);
-
-  if(container)
+  Property::Map* map = nullptr;
+  if(mImpl && (mImpl->GetType() == MAP)) // type cannot change in mImpl so map is allocated
   {
-    Property::Value* value = container->Find( key );
-    if ( value )
-    {
-      return *value;
-    }
+    map = mImpl->GetMapPtr();
   }
-
-  DALI_LOG_WARNING("Cannot find property map key %s", key.c_str());
-  DALI_ASSERT_ALWAYS(!"Cannot find property map key");
+  return map;
 }
 
-bool Property::Value::HasKey(const std::string& key) const
+Property::Map* Property::Value::GetMap()
 {
-  bool has = false;
-
-  if( Property::MAP == GetType() )
+  if(mImpl && (mImpl->GetType() == MAP))
   {
-    Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-
-    DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
-
-    if(container)
-    {
-      Property::Value* value = container->Find( key );
-      if ( value )
-      {
-        has = true;
-      }
-    }
+    return mImpl->GetMapPtr();
   }
-
-  return has;
+  return nullptr;
 }
 
-
-const std::string& Property::Value::GetKey(const int index) const
+bool Property::Value::Get(Extents& extentsValue) const
 {
-  switch( GetType() )
+  bool converted = false;
+  if(mImpl)
   {
-    case Property::MAP:
+    if(mImpl->GetType() == EXTENTS)
     {
-      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-      DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
-      if(container)
-      {
-        if(0 <= index && index < static_cast<int>(container->Count()))
-        {
-          return container->GetKey( index );
-        }
-      }
+      extentsValue = mImpl->GetExtents();
+      converted    = true;
     }
-    break;
-    case Property::NONE:
-    case Property::ARRAY:
-    case Property::BOOLEAN:
-    case Property::FLOAT:
-    case Property::UNSIGNED_INTEGER:
-    case Property::INTEGER:
-    case Property::VECTOR2:
-    case Property::VECTOR3:
-    case Property::VECTOR4:
-    case Property::MATRIX:
-    case Property::MATRIX3:
-    case Property::RECTANGLE:
-    case Property::ROTATION:
-    case Property::STRING:
-    case Property::TYPE_COUNT:
+    else if(mImpl->GetType() == VECTOR4)
     {
-      break;
+      auto& obj           = mImpl->GetVector4();
+      extentsValue.start  = static_cast<uint16_t>(obj.x);
+      extentsValue.end    = static_cast<uint16_t>(obj.y);
+      extentsValue.top    = static_cast<uint16_t>(obj.z);
+      extentsValue.bottom = static_cast<uint16_t>(obj.w);
+      converted           = true;
     }
   }
-
-
-  // should never return this
-  static std::string null;
-  return null;
+  return converted;
 }
 
-
-void Property::Value::SetValue(const std::string& key, const Property::Value &value)
+std::ostream& operator<<(std::ostream& stream, const Property::Value& value)
 {
-  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
-
-  Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-
-  if(container)
+  if(value.mImpl)
   {
-    (*container)[ key ] = value;
-  }
-}
+    auto obj = value.mImpl;
 
-Property::Value& Property::Value::GetItem(const int index) const
-{
-  switch( GetType() )
-  {
-    case Property::MAP:
+    switch(obj->GetType())
     {
-      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-
-      DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
-      if(container)
+      case Dali::Property::BOOLEAN:
       {
-        DALI_ASSERT_ALWAYS(index < static_cast<int>(container->Count()) && "Property array index invalid");
-        DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
-
-        return container->GetValue( index );
+        stream << obj->GetBool();
+        break;
       }
-    }
-    break;
-
-    case Property::ARRAY:
-    {
-      int i = 0;
-      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
-
-      DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
-      if(container)
+      case Dali::Property::FLOAT:
       {
-        DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
-        DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
-
-        for(Property::Array::iterator iter = container->begin(); iter != container->end(); ++iter)
-        {
-          if(i++ == index)
-          {
-            return *iter;
-          }
-        }
+        stream << obj->GetFloat();
+        break;
       }
-    }
-    break;
-
-    case Property::NONE:
-    case Property::BOOLEAN:
-    case Property::FLOAT:
-    case Property::INTEGER:
-    case Property::UNSIGNED_INTEGER:
-    case Property::VECTOR2:
-    case Property::VECTOR3:
-    case Property::VECTOR4:
-    case Property::MATRIX3:
-    case Property::MATRIX:
-    case Property::RECTANGLE:
-    case Property::ROTATION:
-    case Property::STRING:
-    case Property::TYPE_COUNT:
-    {
-      DALI_ASSERT_ALWAYS(!"Cannot GetItem on property Type; not a container");
-      break;
-    }
-
-  } // switch GetType()
-
-
-  DALI_ASSERT_ALWAYS(!"Property value index not valid");
-}
-
-Property::Value& Property::Value::GetItem(const int index, std::string& key) const
-{
-  Property::Value& ret( GetItem(index) );
-
-  if( Property::MAP == GetType() )
-  {
-    Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-    if( index < static_cast<int>(container->Count()) )
-    {
-      key = container->GetKey( index );
-    }
-  }
-
-  return ret;
-}
-
-void Property::Value::SetItem(const int index, const Property::Value &value)
-{
-  switch( GetType() )
-  {
-    case Property::MAP:
-    {
-      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-      if( container && index < static_cast<int>(container->Count()) )
+      case Dali::Property::INTEGER:
       {
-        Property::Value& indexValue = container->GetValue( index );
-        indexValue = value;
+        stream << obj->GetInt();
+        break;
       }
-    }
-    break;
-
-    case Property::ARRAY:
-    {
-      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
-      if( container && index < static_cast<int>(container->size()) )
+      case Dali::Property::VECTOR2:
       {
-        (*container)[index] = value;
+        stream << obj->GetVector2();
+        break;
       }
-    }
-    break;
-
-    case Property::NONE:
-    case Property::BOOLEAN:
-    case Property::FLOAT:
-    case Property::INTEGER:
-    case Property::UNSIGNED_INTEGER:
-    case Property::VECTOR2:
-    case Property::VECTOR3:
-    case Property::VECTOR4:
-    case Property::MATRIX3:
-    case Property::MATRIX:
-    case Property::RECTANGLE:
-    case Property::ROTATION:
-    case Property::STRING:
-    case Property::TYPE_COUNT:
-    {
-      DALI_ASSERT_ALWAYS(!"Cannot SetItem on property Type; not a container");
-      break;
-    }
-  }
-}
-
-int Property::Value::AppendItem(const Property::Value &value)
-{
-  DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
-
-  Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
-
-  if(container)
-  {
-    container->push_back(value);
-    return container->size() - 1;
-  }
-  else
-  {
-    return -1;
-  }
-
-}
-
-int Property::Value::GetSize() const
-{
-  int ret = 0;
-
-  switch(GetType())
-  {
-    case Property::MAP:
-    {
-      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
-      if(container)
+      case Dali::Property::VECTOR3:
       {
-        ret = container->Count();
+        stream << obj->GetVector3();
+        break;
       }
-    }
-    break;
-
-    case Property::ARRAY:
-    {
-      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
-      if(container)
+      case Dali::Property::VECTOR4:
       {
-        ret = container->size();
+        stream << obj->GetVector4();
+        break;
+      }
+      case Dali::Property::MATRIX3:
+      {
+        stream << obj->GetMatrix3();
+        break;
+      }
+      case Dali::Property::MATRIX:
+      {
+        stream << obj->GetMatrix();
+        break;
+      }
+      case Dali::Property::RECTANGLE:
+      {
+        stream << obj->GetRect();
+        break;
+      }
+      case Dali::Property::ROTATION:
+      {
+        stream << obj->GetAngleAxis();
+        break;
+      }
+      case Dali::Property::STRING:
+      {
+        stream << obj->GetString();
+        break;
+      }
+      case Dali::Property::ARRAY:
+      {
+        stream << obj->GetArray();
+        break;
+      }
+      case Dali::Property::MAP:
+      {
+        stream << obj->GetMap();
+        break;
+      }
+      case Dali::Property::EXTENTS:
+      {
+        stream << obj->GetExtents();
+        break;
+      }
+      case Dali::Property::NONE:
+      { // mImpl will be a nullptr, there's no way to get to this case
       }
     }
-    break;
-
-    case Property::NONE:
-    case Property::BOOLEAN:
-    case Property::FLOAT:
-    case Property::INTEGER:
-    case Property::UNSIGNED_INTEGER:
-    case Property::VECTOR2:
-    case Property::VECTOR3:
-    case Property::VECTOR4:
-    case Property::MATRIX3:
-    case Property::MATRIX:
-    case Property::RECTANGLE:
-    case Property::ROTATION:
-    case Property::STRING:
-    case Property::TYPE_COUNT:
-    {
-      break;
-    }
-
   }
-
-  return ret;
-}
-
-std::ostream& operator<< (std::ostream& stream, const Property::Value& value )
-{
-
-  const Property::Value::Impl& impl( *value.mImpl );
-
-  switch( impl.mType )
+  else
   {
-    case Dali::Property::STRING:
-    {
-      stream <<  AnyCast<std::string>(impl.mValue).c_str();
-      break;
-    }
-    case Dali::Property::VECTOR2:
-    {
-      stream << AnyCast<Vector2>(impl.mValue);
-      break;
-    }
-    case Dali::Property::VECTOR3:
-    {
-      stream << AnyCast<Vector3>(impl.mValue);
-      break;
-    }
-    case Dali::Property::VECTOR4:
-    {
-      stream << AnyCast<Vector4>(impl.mValue);
-      break;
-    }
-    case Dali::Property::MATRIX:
-    {
-      stream << AnyCast<Matrix>(impl.mValue);
-      break;
-    }
-    case Dali::Property::BOOLEAN:
-    {
-      stream << AnyCast<bool>(impl.mValue);
-      break;
-    }
-    case Dali::Property::FLOAT:
-    {
-      stream << AnyCast<float>(impl.mValue);
-      break;
-    }
-    case Dali::Property::INTEGER:
-    {
-       stream << AnyCast<int>(impl.mValue);
-       break;
-    }
-    case Dali::Property::UNSIGNED_INTEGER:
-    {
-      stream << AnyCast<unsigned int>(impl.mValue);
-      break;
-    }
-    case Dali::Property::RECTANGLE:
-    {
-      Dali::Rect<int> rect; // Propery Value rectangles are currently integer based
-      value.Get( rect );
-      stream << rect;
-      break;
-    }
-    case Dali::Property::MATRIX3:
-    {
-      stream << AnyCast<Matrix3>(impl.mValue);
-      break;
-    }
-    case Dali::Property::ROTATION:
-    {
-      // @todo this may change to Quaternion
-      Dali::Quaternion q;
-      value.Get( q );
-      Dali::Vector4 v4 = q.EulerAngles();
-      stream << v4;
-      break;
-    }
-
-    case Dali::Property::ARRAY:
-    {
-      // @todo Need to think about the best way to support array
-      // E.g Do we want to create a JSON style array like:
-      // [ {"property-name-0":"property-value-0", "property-name-1":"property-value-1"} ]
-      stream << "ARRAY unsupported";
-      break;
-    }
-    case Dali::Property::MAP:
-    {
-      Dali::Property::Map map;
-      value.Get( map );
-      stream << "Map containing " << map.Count() << " elements";
-      break;
-    }
-    case Dali::Property::TYPE_COUNT:
-    {
-      stream << "unsupported TYPE_COUNT";
-      break;
-    }
-    default:
-    {
-      stream << "unsupported type = " << value.GetType();
-      break;
-    }
+    stream << "undefined type";
   }
   return stream;
 }
 
-
 } // namespace Dali