/*! @file
@ id $ Id $
taken from boost . org boost : : Any
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// See http://www.boost.org/libs/any for Documentation.
# ifndef XML_CXX_ANY_INCLUDED
# define XML_CXX_ANY_INCLUDED
# include <algorithm>
# include <typeinfo>
# include <stdexcept>
namespace xml {
class Serialize ;
//! @cond INTERNAL
//! @addtogroup serialization
//@{
/*! @defgroup xmlAny (internal) Any Object with limited Polymorfism
@ internal The implementation of xml : : Any is an adaption of @ c
boost : : any ( see http : //www.boost.org), but instead of
holding any element , but without polymorfism , the
implementation of xml : : Any only holds basic C + + types
( @ c int , @ c long , @ c float , . . . ) , plus @ c std : : string
and xml : : Serialize . All other non - standard - C + + types
are stored as xml : : Serialize * . This way , we can get a
polymorfic any type , but only for children of
xml : : Serialize , but in fact , that ' s all we
need . Another limitation is , that xml : : Any only stores
pointer types . Simply because we don ' t need more . */
//@{
//! @internal Number of supported types that can be stored as XML.
const int MAX_NUM ( 14 ) ;
template < int NUM > struct ToType { typedef Serialize Type ; } ;
template < > struct ToType < 1 > { typedef Serialize Type ; } ;
template < > struct ToType < 2 > { typedef std : : string Type ; } ;
template < > struct ToType < 3 > { typedef bool Type ; } ;
template < > struct ToType < 4 > { typedef unsigned char Type ; } ;
template < > struct ToType < 5 > { typedef signed char Type ; } ;
template < > struct ToType < 6 > { typedef char Type ; } ;
template < > struct ToType < 7 > { typedef unsigned short Type ; } ;
template < > struct ToType < 8 > { typedef signed short Type ; } ;
template < > struct ToType < 9 > { typedef unsigned int Type ; } ;
template < > struct ToType < 10 > { typedef signed int Type ; } ;
template < > struct ToType < 11 > { typedef unsigned long Type ; } ;
template < > struct ToType < 12 > { typedef signed long Type ; } ;
template < > struct ToType < 13 > { typedef float Type ; } ;
template < > struct ToType < 14 > { typedef double Type ; } ;
template < typename T > struct ToNum { static const int NUM = 1 ; } ;
template < > struct ToNum < Serialize > { static const int NUM = 1 ; } ;
template < > struct ToNum < std : : string > { static const int NUM = 2 ; } ;
template < > struct ToNum < bool > { static const int NUM = 3 ; } ;
template < > struct ToNum < unsigned char > { static const int NUM = 4 ; } ;
template < > struct ToNum < signed char > { static const int NUM = 5 ; } ;
template < > struct ToNum < char > { static const int NUM = 6 ; } ;
template < > struct ToNum < unsigned short > { static const int NUM = 7 ; } ;
template < > struct ToNum < signed short > { static const int NUM = 8 ; } ;
template < > struct ToNum < unsigned int > { static const int NUM = 9 ; } ;
template < > struct ToNum < signed int > { static const int NUM = 10 ; } ;
template < > struct ToNum < unsigned long > { static const int NUM = 11 ; } ;
template < > struct ToNum < signed long > { static const int NUM = 12 ; } ;
template < > struct ToNum < float > { static const int NUM = 13 ; } ;
template < > struct ToNum < double > { static const int NUM = 14 ; } ;
template < typename T > bool isSerialize ( ) {
return ToNum < T > : : NUM = = 1 ;
}
template < typename T , bool GOOD = ( ToNum < T > : : NUM = = 1 ) > struct Mapper {
static Serialize * toSerialize ( T & obj ) {
return 0 ;
}
} ;
template < typename T > struct Mapper < T , true > {
static Serialize * toSerialize ( T & obj ) {
return dynamic_cast < Serialize * > ( & obj ) ;
}
} ;
class Any {
public :
Any ( ) : _content ( 0 ) { }
template < typename TYPE > Any ( TYPE * value ) :
_content ( new Holder < TYPE > ( value ) ) {
}
Any ( const Any & other ) :
_content ( other . _content ? other . _content - > clone ( ) : 0 ) {
}
~ Any ( ) {
delete _content ;
}
Any & swap ( Any & rhs ) {
std : : swap ( _content , rhs . _content ) ;
return * this ;
}
template < typename TYPE > Any & operator = ( TYPE * rhs ) {
Any ( rhs ) . swap ( * this ) ;
return * this ;
}
Any & operator = ( const Any & rhs ) {
Any ( rhs ) . swap ( * this ) ;
return * this ;
}
bool empty ( ) const {
return ! _content ;
}
const std : : type_info & type ( ) const {
return _content ? _content - > type ( ) : typeid ( void ) ;
}
class Placeholder {
public :
virtual ~ Placeholder ( ) { }
virtual const std : : type_info & type ( ) const = 0 ;
virtual Placeholder * clone ( ) const = 0 ;
} ;
template < typename TYPE > class Holder : public Placeholder {
public :
Holder ( typename ToType < ToNum < TYPE > : : NUM > : : Type * value ) :
_held ( value ) {
}
virtual const std : : type_info & type ( ) const {
return typeid ( typename ToType < ToNum < TYPE > : : NUM > : : Type ) ;
}
virtual Placeholder * clone ( ) const {
return new Holder ( _held ) ;
}
typename ToType < ToNum < TYPE > : : NUM > : : Type * _held ;
} ;
private :
template < typename TYPE > friend TYPE * any_cast ( Any * ) ;
template < typename TYPE > friend TYPE * any_cast ( Any & ) ;
Placeholder * _content ;
} ;
template < typename TYPE > TYPE * any_cast ( Any * operand ) {
return operand & & operand - > type ( ) = = typeid ( TYPE )
? static_cast < Any : : Holder < TYPE > * > ( operand - > _content ) - > _held
: 0 ;
}
template < typename TYPE > const TYPE * any_cast ( const Any * operand ) {
return any_cast < TYPE > ( const_cast < Any * > ( operand ) ) ;
}
template < typename TYPE > TYPE * any_cast ( Any & operand ) {
if ( operand . type ( ) = = typeid ( TYPE ) )
return static_cast < Any : : Holder < TYPE > * > ( operand . _content ) - > _held ;
throw std : : bad_cast ( ) ;
}
template < typename TYPE > const TYPE * any_cast ( const Any & operand ) {
return any_cast < TYPE > ( const_cast < Any & > ( operand ) ) ;
}
//@}
//@}
//! @endcond INTERNAL
}
// Note for this file only (this file is in large parts taken from boost):
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0. (See
// http://www.boost.org/LICENSE_1_0.txt)
// Boost Software License - Version 1.0 - August 17th, 2003
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
# endif