MyGUI  3.2.0
MyGUI_Any.h
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 
00023 // -- Based on boost::any, original copyright information follows --
00024 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00025 //
00026 // Distributed under the Boost Software License, Version 1.0.
00027 // (See at http://www.boost.org/LICENSE_1_0.txt)
00028 // -- End original copyright --
00029 
00030 #ifndef __MYGUI_ANY_H__
00031 #define __MYGUI_ANY_H__
00032 
00033 #include "MyGUI_Prerequest.h"
00034 #include "MyGUI_Diagnostic.h"
00035 #include <algorithm>
00036 
00037 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
00038 #include <typeinfo>
00039 #endif
00040 
00041 namespace MyGUI
00042 {
00043 
00081     class MYGUI_EXPORT Any
00082     {
00083     public:
00084         struct AnyEmpty { };
00085         static AnyEmpty Null;
00086 
00087         Any();
00088         Any(const Any::AnyEmpty& value);
00089         Any(const Any& other);
00090 
00091         template<typename ValueType>
00092         Any(const ValueType& value) :
00093             mContent(new Holder<ValueType>(value))
00094         {
00095         }
00096 
00097         ~Any();
00098 
00099         Any& swap(Any& rhs);
00100 
00101         template<typename ValueType>
00102         Any& operator = (const ValueType& rhs)
00103         {
00104             Any(rhs).swap(*this);
00105             return *this;
00106         }
00107 
00108         Any& operator = (const Any::AnyEmpty& rhs);
00109         Any& operator = (const Any& rhs);
00110 
00111         bool empty() const;
00112 
00113 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
00114         const std::type_info& getType() const;
00115 
00116         template<typename ValueType>
00117         ValueType* castType(bool _throw = true) const
00118         {
00119             if (this->getType() == typeid(ValueType))
00120                 return &static_cast<Any::Holder<ValueType> *>(this->mContent)->held;
00121             MYGUI_ASSERT(!_throw, "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'");
00122             return nullptr;
00123         }
00124 #else
00125         template<typename ValueType>
00126         ValueType* castType(bool _throw = true) const
00127         {
00128             Any::Holder<ValueType>* data = dynamic_cast<Any::Holder<ValueType> *>(this->mContent);
00129             if (data != nullptr)
00130                 return &data->held;
00131             MYGUI_ASSERT(!_throw, "Bad cast any");
00132             return nullptr;
00133         }
00134 #endif
00135 
00136         void* castUnsafe() const;
00137 
00138     private:
00139         class Placeholder
00140         {
00141         public:
00142             virtual ~Placeholder() { }
00143 
00144         public:
00145 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
00146             virtual const std::type_info& getType() const = 0;
00147 #endif
00148             virtual Placeholder* clone() const = 0;
00149         };
00150 
00151         template<typename ValueType>
00152         class Holder :
00153             public Placeholder
00154         {
00155         public:
00156             Holder(const ValueType& value) :
00157                 held(value)
00158             {
00159             }
00160 
00161         public:
00162 #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO
00163             virtual const std::type_info& getType() const
00164             {
00165                 return typeid(ValueType);
00166             }
00167 #endif
00168 
00169             virtual Placeholder* clone() const
00170             {
00171                 return new Holder(held);
00172             }
00173 
00174         public:
00175             ValueType held;
00176 
00177         private:
00178             Holder& operator=(const Holder&);
00179         };
00180 
00181     private:
00182         Placeholder* mContent;
00183     };
00184 
00185 } // namespace MyGUI
00186 
00187 #endif // __MYGUI_ANY_H__