MyGUI
3.0.1
|
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__