/*! @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 #include #include 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 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 struct ToNum {static const int NUM = 1;}; template<> struct ToNum {static const int NUM = 1;}; template<> struct ToNum {static const int NUM = 2;}; template<> struct ToNum {static const int NUM = 3;}; template<> struct ToNum {static const int NUM = 4;}; template<> struct ToNum {static const int NUM = 5;}; template<> struct ToNum< char > {static const int NUM = 6;}; template<> struct ToNum {static const int NUM = 7;}; template<> struct ToNum {static const int NUM = 8;}; template<> struct ToNum {static const int NUM = 9;}; template<> struct ToNum {static const int NUM = 10;}; template<> struct ToNum {static const int NUM = 11;}; template<> struct ToNum {static const int NUM = 12;}; template<> struct ToNum {static const int NUM = 13;}; template<> struct ToNum {static const int NUM = 14;}; template bool isSerialize() { return ToNum::NUM == 1; } template ::NUM==1)> struct Mapper { static Serialize* toSerialize(T& obj) { return 0; } }; template struct Mapper { static Serialize* toSerialize(T& obj) { return dynamic_cast(&obj); } }; class Any { public: Any(): _content(0) {} template Any(TYPE* value): _content(new Holder(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 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 class Holder: public Placeholder { public: Holder(typename ToType::NUM>::Type* value): _held(value) { } virtual const std::type_info& type() const { return typeid(typename ToType::NUM>::Type); } virtual Placeholder* clone() const { return new Holder(_held); } typename ToType::NUM>::Type* _held; }; private: template friend TYPE* any_cast(Any*); template friend TYPE* any_cast(Any&); Placeholder* _content; }; template TYPE* any_cast(Any* operand) { return operand && operand->type() == typeid(TYPE) ? static_cast*>(operand->_content)->_held : 0; } template const TYPE* any_cast(const Any* operand) { return any_cast(const_cast(operand)); } template TYPE* any_cast(Any& operand) { if (operand.type()==typeid(TYPE)) return static_cast*>(operand._content)->_held; throw std::bad_cast(); } template const TYPE* any_cast(const Any& operand) { return any_cast(const_cast(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