Only include forward declaring iostream header in public API
[platform/core/uifw/dali-core.git] / dali / public-api / object / property-value.cpp
index a08b943..8bffbc3 100644 (file)
@@ -1,26 +1,28 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // CLASS HEADER
 #include <dali/public-api/object/property-value.h>
 
 // EXTERNAL INCLUDES
-#include <boost/any.hpp>
+#include <ostream>
 
 // INTERNAL INCLUDES
+#include <dali/public-api/object/any.h>
 #include <dali/public-api/math/angle-axis.h>
 #include <dali/public-api/math/radian.h>
 #include <dali/public-api/math/vector2.h>
@@ -30,6 +32,7 @@
 #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-map.h>
 #include <dali/public-api/object/property-types.h>
 #include <dali/integration-api/debug.h>
 
@@ -135,7 +138,7 @@ struct Property::Value::Impl
 
   Type mType;
 
-  typedef boost::any AnyValue;
+  typedef Any AnyValue;
   AnyValue mValue;
 };
 
@@ -550,83 +553,83 @@ Property::Type Property::Value::GetType() const
 
 void Property::Value::Get(bool& boolValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::BOOLEAN == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" );  // AnyCast does asserted type checking
 
-  boolValue = boost::any_cast<bool>(mImpl->mValue);
+  boolValue = AnyCast<bool>(mImpl->mValue);
 }
 
 void Property::Value::Get(float& floatValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::FLOAT == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
 
-  floatValue = boost::any_cast<float>(mImpl->mValue);
+  floatValue = AnyCast<float>(mImpl->mValue);
 }
 
 void Property::Value::Get(int& integerValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::INTEGER == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
 
-  integerValue = boost::any_cast<int>(mImpl->mValue);
+  integerValue = AnyCast<int>(mImpl->mValue);
 }
 
 void Property::Value::Get(unsigned int& unsignedIntegerValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
 
-  unsignedIntegerValue = boost::any_cast<unsigned int>(mImpl->mValue);
+  unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
 }
 
 void Property::Value::Get(Vector2& vectorValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::VECTOR2 == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
 
-  vectorValue = boost::any_cast<Vector2>(mImpl->mValue);
+  vectorValue = AnyCast<Vector2>(mImpl->mValue);
 }
 
 void Property::Value::Get(Vector3& vectorValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::VECTOR3 == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
 
-  vectorValue = boost::any_cast<Vector3>(mImpl->mValue);
+  vectorValue = AnyCast<Vector3>(mImpl->mValue);
 }
 
 void Property::Value::Get(Vector4& vectorValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::VECTOR4 == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
 
-  vectorValue = boost::any_cast<Vector4>(mImpl->mValue);
+  vectorValue = AnyCast<Vector4>(mImpl->mValue);
 }
 
 void Property::Value::Get(Matrix3& matrixValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::MATRIX3 == GetType() && "Property type invalid" );
-  matrixValue = boost::any_cast<Matrix3>(mImpl->mValue);
+  DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
+  matrixValue = AnyCast<Matrix3>(mImpl->mValue);
 }
 
 void Property::Value::Get(Matrix& matrixValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::MATRIX == GetType() && "Property type invalid" );
-  matrixValue = boost::any_cast<Matrix>(mImpl->mValue);
+  DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
+  matrixValue = AnyCast<Matrix>(mImpl->mValue);
 }
 
 void Property::Value::Get(Rect<int>& rect) const
 {
-  DALI_ASSERT_ALWAYS( Property::RECTANGLE == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
 
-  rect = boost::any_cast<Rect<int> >(mImpl->mValue);
+  rect = AnyCast<Rect<int> >(mImpl->mValue);
 }
 
 void Property::Value::Get(AngleAxis& angleAxisValue) const
 {
   DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
 
-  // Rotations have two representations
-  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.type() ||
-                     typeid(AngleAxis)  == mImpl->mValue.type() );
+  // Orientations have two representations
+  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
+                     typeid(AngleAxis)  == mImpl->mValue.GetType() );
 
-  if ( typeid(Quaternion) == mImpl->mValue.type() )
+  if ( typeid(Quaternion) == mImpl->mValue.GetType() )
   {
-    Quaternion quaternion = boost::any_cast<Quaternion>(mImpl->mValue);
+    Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
 
     Radian angleRadians(0.0f);
     quaternion.ToAxisAngle( angleAxisValue.axis, angleRadians );
@@ -634,25 +637,25 @@ void Property::Value::Get(AngleAxis& angleAxisValue) const
   }
   else
   {
-    angleAxisValue = boost::any_cast<AngleAxis>(mImpl->mValue);
+    angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
   }
 }
 
 void Property::Value::Get(Quaternion& quaternionValue) const
 {
-  DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
+  DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
 
-  // Rotations have two representations
-  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.type() ||
-               typeid(AngleAxis)  == mImpl->mValue.type() );
+  // Orientations have two representations
+  DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
+               typeid(AngleAxis)  == mImpl->mValue.GetType() );
 
-  if ( typeid(Quaternion) == mImpl->mValue.type() )
+  if ( typeid(Quaternion) == mImpl->mValue.GetType() )
   {
-    quaternionValue = boost::any_cast<Quaternion>(mImpl->mValue);
+    quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
   }
   else
   {
-    AngleAxis angleAxis = boost::any_cast<AngleAxis>(mImpl->mValue);
+    AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
 
     quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
   }
@@ -660,50 +663,44 @@ void Property::Value::Get(Quaternion& quaternionValue) const
 
 void Property::Value::Get(std::string &out) const
 {
-  DALI_ASSERT_ALWAYS(Property::STRING == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
 
-  out = boost::any_cast<std::string>(mImpl->mValue);
+  out = AnyCast<std::string>(mImpl->mValue);
 }
 
 void Property::Value::Get(Property::Array &out) const
 {
-  DALI_ASSERT_ALWAYS(Property::ARRAY == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
 
-  out = boost::any_cast<Property::Array>(mImpl->mValue);
+  out = AnyCast<Property::Array>(mImpl->mValue);
 }
 
 void Property::Value::Get(Property::Map &out) const
 {
-  DALI_ASSERT_ALWAYS(Property::MAP == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
 
-  out = boost::any_cast<Property::Map>(mImpl->mValue);
+  out = AnyCast<Property::Map>(mImpl->mValue);
 }
 
 Property::Value& Property::Value::GetValue(const std::string& key) const
 {
-  DALI_ASSERT_ALWAYS(Property::MAP == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
 
-  Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+  Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
 
   DALI_ASSERT_DEBUG(container);
 
   if(container)
   {
-    for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
+    Property::Value* value = container->Find( key );
+    if ( value )
     {
-      if(iter->first == key)
-      {
-        return iter->second;
-      }
+      return *value;
     }
   }
 
   DALI_LOG_WARNING("Cannot find property map key %s", key.c_str());
   DALI_ASSERT_ALWAYS(!"Cannot find property map key");
-
-  // should never return this
-  static Property::Value null;
-  return null;
 }
 
 bool Property::Value::HasKey(const std::string& key) const
@@ -712,18 +709,16 @@ bool Property::Value::HasKey(const std::string& key) const
 
   if( Property::MAP == GetType() )
   {
-    Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+    Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
 
     DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
 
     if(container)
     {
-      for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
+      Property::Value* value = container->Find( key );
+      if ( value )
       {
-        if(iter->first == key)
-        {
-          has = true;
-        }
+        has = true;
       }
     }
   }
@@ -738,20 +733,13 @@ const std::string& Property::Value::GetKey(const int index) const
   {
     case Property::MAP:
     {
-      int i = 0;
-      Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+      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->size()))
+        if(0 <= index && index < static_cast<int>(container->Count()))
         {
-          for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
-          {
-            if(i++ == index)
-            {
-              return iter->first;
-            }
-          }
+          return container->GetKey( index );
         }
       }
     }
@@ -785,24 +773,13 @@ const std::string& Property::Value::GetKey(const int index) const
 
 void Property::Value::SetValue(const std::string& key, const Property::Value &value)
 {
-  DALI_ASSERT_ALWAYS(Property::MAP == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
 
-  Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+  Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
 
   if(container)
   {
-    for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
-    {
-      if(iter->first == key)
-      {
-        iter->second = value;
-        return;
-      }
-    }
-
-    // if we get here its a new key
-    container->push_back(Property::StringValuePair(key, value));
-
+    (*container)[ key ] = value;
   }
 }
 
@@ -812,22 +789,15 @@ Property::Value& Property::Value::GetItem(const int index) const
   {
     case Property::MAP:
     {
-      int i = 0;
-      Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
 
       DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
       if(container)
       {
-        DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
+        DALI_ASSERT_ALWAYS(index < static_cast<int>(container->Count()) && "Property array index invalid");
         DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
 
-        for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
-        {
-          if(i++ == index)
-          {
-            return iter->second;
-          }
-        }
+        return container->GetValue( index );
       }
     }
     break;
@@ -835,7 +805,7 @@ Property::Value& Property::Value::GetItem(const int index) const
     case Property::ARRAY:
     {
       int i = 0;
-      Property::Array *container = boost::any_cast<Property::Array>(&(mImpl->mValue));
+      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
 
       DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
       if(container)
@@ -877,10 +847,22 @@ Property::Value& Property::Value::GetItem(const int index) const
 
 
   DALI_ASSERT_ALWAYS(!"Property value index not valid");
+}
 
-  // should never return this
-  static Property::Value null;
-  return null;
+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)
@@ -889,25 +871,18 @@ void Property::Value::SetItem(const int index, const Property::Value &value)
   {
     case Property::MAP:
     {
-      Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
-      if( container && index < static_cast<int>(container->size()) )
+      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
+      if( container && index < static_cast<int>(container->Count()) )
       {
-        int i = 0;
-        for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
-        {
-          if(i++ == index)
-          {
-            iter->second = value;
-            break;
-          }
-        }
+        Property::Value& indexValue = container->GetValue( index );
+        indexValue = value;
       }
     }
     break;
 
     case Property::ARRAY:
     {
-      Property::Array *container = boost::any_cast<Property::Array>(&(mImpl->mValue));
+      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
       if( container && index < static_cast<int>(container->size()) )
       {
         (*container)[index] = value;
@@ -938,9 +913,9 @@ void Property::Value::SetItem(const int index, const Property::Value &value)
 
 int Property::Value::AppendItem(const Property::Value &value)
 {
-  DALI_ASSERT_ALWAYS(Property::ARRAY == GetType() && "Property type invalid");
+  DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
 
-  Property::Array *container = boost::any_cast<Property::Array>(&(mImpl->mValue));
+  Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
 
   if(container)
   {
@@ -962,17 +937,17 @@ int Property::Value::GetSize() const
   {
     case Property::MAP:
     {
-      Property::Map *container = boost::any_cast<Property::Map>(&(mImpl->mValue));
+      Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
       if(container)
       {
-        ret = container->size();
+        ret = container->Count();
       }
     }
     break;
 
     case Property::ARRAY:
     {
-      Property::Array *container = boost::any_cast<Property::Array>(&(mImpl->mValue));
+      Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
       if(container)
       {
         ret = container->size();
@@ -1003,5 +978,108 @@ int Property::Value::GetSize() const
   return ret;
 }
 
+std::ostream& operator<< (std::ostream& stream, const Property::Value& value )
+{
+
+  const Property::Value::Impl& impl( *value.mImpl );
+
+  switch( impl.mType )
+  {
+    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;
+    }
+  }
+  return stream;
+}
+
 
 } // namespace Dali