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