1 #ifndef __DALI_ANY_TYPE_H__
2 #define __DALI_ANY_TYPE_H__
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 // Licensed under the Flora License, Version 1.0 (the License);
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://floralicense.org/license/
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an AS IS BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
21 * @addtogroup CAPI_DALI_OBJECT_MODULE
26 #include <typeinfo> // operator typeid
30 #include <dali/public-api/common/dali-common.h>
32 namespace Dali DALI_IMPORT_API
36 * Stores a value of any type.
38 * @note Assignments of values with different types are now allowed to replicate Any behaviour
42 * Any uintVariable = 5u;
43 * Any floatVariable( 4.5f );
44 * Any strVariable( std::string( "Hello world" ) );
46 * unsigned int variable = AnyCast< unsigned int >( uintVariable );
47 * if ( typeid( int ) == uintVariable.GetType() )
54 * Default constructor.
59 * Destructor. Free resources.
64 * @brief Pass Assert message
66 * @param assertMessage Assert message to report
68 static void AssertAlways( const char* assertMessage );
71 * @brief Constructs a Any type with the given value.
73 * @param[in] value The given value.
75 template<typename Type>
76 Any( const Type& value )
77 : mContainer( new AnyContainerImpl<Type>( value ) )
83 * @param [in] any Any to be copied.
87 // If container isn't empty then copy the container?
88 if ( NULL != any.mContainer )
90 mContainer = any.mContainer->mCloneFunc( *any.mContainer );
94 // Otherwise mark new container as empty
100 * @brief Assigns a given value to the Any type.
102 * @note If the types are different, then the current container will be re-created.
104 * @param[in] value The given value.
106 template<typename Type>
107 Any& operator=( const Type& value )
110 // If the container is empty then assign the new value
111 if ( NULL == mContainer )
113 mContainer = new AnyContainerImpl< Type >( value );
117 // Check to see if this type is compatible with current container?
118 if ( mContainer->GetType() == typeid( Type ) )
120 // Same type so just set the new value
121 static_cast< AnyContainerImpl< Type >* >( mContainer )->SetValue( value );
125 // Incompatible types, so delete old container and assign a new one with this type and value
126 mContainer->mDeleteFunc( mContainer );
127 mContainer = new AnyContainerImpl< Type >( value );
134 * @brief Assignment operator.
136 * @note Asserts if values of different types are assigned.
138 * @param [in] any Any to be assigned.
140 Any& operator=( const Any& any );
143 * @brief Get a value of type Type from container
145 * @param type destination of type Type to write to
147 template<typename Type>
148 void Get( Type& type )
154 * @brief Returns the type info of the stored value.
156 * @note Returns the info of the void type if there is no value stored.
158 const std::type_info& GetType() const;
161 * @brief Retrieves the stored value in the Any type.
163 * @return The stored value.
165 template<typename Type>
166 const Type& Get() const
169 if ( NULL == mContainer )
171 AssertAlways( "Any::Get(). mContainer is NULL" );
174 // Check if the value has the same value than the Any type.
175 if( mContainer->GetType() != typeid( Type ) )
177 AssertAlways( "Any::Get(). Trying to retrieve a value of a different type than the template one." );
179 return static_cast< AnyContainerImpl< Type >* >( mContainer )->GetValue();
183 * @brief Return pointer of Type to the value stored
185 * @return pointer to the value or NULL if no value is contained
187 template<typename Type>
190 if( NULL == mContainer )
194 // Check if the value has the same value than the Any type.
195 if( mContainer->GetType() != typeid( Type ) )
197 AssertAlways( "Any::GetPointer(). Trying to retrieve a pointer to a value of a different type than the template one." );
199 return static_cast< AnyContainerImpl< Type >* >( mContainer )->GetPointerToValue();
203 * @brief Returns whether container holds a value
205 * @return true or false
209 return ( NULL == mContainer ) ? true : false;
212 struct AnyContainerBase; // Forward declaration for typedef
213 typedef AnyContainerBase* (*CloneFunc)( const AnyContainerBase& base );
214 typedef void (*DeleteFunc)( const AnyContainerBase* base );
217 * Base container to hold type for match verification and instance cloning function
220 struct AnyContainerBase
223 * @brief Constructor of base container
225 * @param type typeid of container
226 * @param cloneFunc Cloning function to replicate this container type
227 * @param deleteFunc Deleting function to destroy this container type
229 AnyContainerBase( const std::type_info& type, CloneFunc cloneFunc, DeleteFunc deleteFunc )
231 mCloneFunc( cloneFunc ),
232 mDeleteFunc( deleteFunc )
236 * @brief Get the typeid of this container
240 const std::type_info& GetType() const
245 const::std::type_info& mType; // typeID
246 CloneFunc mCloneFunc; // cloning function for this container
247 DeleteFunc mDeleteFunc; // deleting function for this container
252 * @brief Templated Clone function from container base
254 * @param base reference to container
256 template<typename Type>
257 struct AnyContainerImplCloner
259 static AnyContainerBase* Clone( const AnyContainerBase& base )
261 return new AnyContainerImpl< Type >( static_cast< AnyContainerImpl< Type > >( base ) );
266 * @brief Templated Delete function from container base
268 * @param base pointer to container
270 template<typename Type>
271 struct AnyContainerImplDelete
273 static void Delete( const AnyContainerBase* base )
275 delete ( static_cast< const AnyContainerImpl< Type >* > ( base ) );
280 * @brief Templated class to hold value for type
283 template<typename Type>
284 class AnyContainerImpl : public AnyContainerBase
289 * @brief Constructor to create container holding value of type Type
291 * @param value Value of Type
293 AnyContainerImpl( const Type& value )
294 : AnyContainerBase( typeid( Type ),
295 static_cast< CloneFunc >( &AnyContainerImplCloner< Type >::Clone ),
296 static_cast< DeleteFunc >( &AnyContainerImplDelete< Type >::Delete ) ),
301 * @brief Constructor to create new container of type from and existing container (cloning)
303 * @param base reference to base container to copy from
305 AnyContainerImpl( const AnyContainerBase& base )
306 : AnyContainerBase( typeid( Type ),
307 static_cast< CloneFunc >( &AnyContainerImplCloner< Type >::Clone ),
308 static_cast< DeleteFunc >( &AnyContainerImplDelete< Type >::Delete ) )
310 mValue = static_cast< const AnyContainerImpl& >( base ).GetValue();
314 * @brief Get the container's stored value
316 * @return value of Type
318 const Type& GetValue() const
323 void SetValue( const Type& value )
329 * @brief Get a pointer to the value held
331 * @return pointer to the value of type Type
333 Type* GetPointerToValue()
335 return static_cast< Type* >( &mValue );
342 AnyContainerBase* mContainer;
347 * AnyCast helper functions ( replicates boost functionality, but without exception generation )
351 * @brief Extract a pointer to the held type of an Any object from a pointer to that Any object (NULL if empty )
353 * @param any Pointer to an Any object
355 * @return Pointer to the Type held
357 template<typename Type>inline Type* AnyCast( Any* any )
359 return any->GetPointer<Type>();
363 * @brief Extract a const pointer to the held type of an Any object from a pointer to that Any object (NULL if empty )
365 * @param any const Pointer to an Any object
367 * @return const Pointer to the Type held
369 template<typename Type>inline const Type* AnyCast( const Any* any )
371 return any->GetPointer<Type>();
375 * @brief Extract a held value of type Type from an Any object from a reference to that Any object
377 * @param any reference to an Any object
379 * @return Type value of type Type
381 template<typename Type>inline Type AnyCast( Any& any )
383 return any.Get<Type>();
387 * @brief Extract a held value of type Type from an Any object from a const reference to that Any object
389 * @param any reference to an Any object
391 * @return Type value of type Type
393 template<typename Type>inline Type AnyCast( const Any& any )
395 return any.Get<Type>();
403 #endif // __DALI_ANY_TYPE_H__