00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2012 Torus Knot Software Ltd 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a copy 00010 of this software and associated documentation files (the "Software"), to deal 00011 in the Software without restriction, including without limitation the rights 00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 copies of the Software, and to permit persons to whom the Software is 00014 furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 THE SOFTWARE. 00026 ----------------------------------------------------------------------------- 00027 */ 00028 // -- Based on boost::any, original copyright information follows -- 00029 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00030 // 00031 // Distributed under the Boost Software License, Version 1.0. (See 00032 // accompAnying file LICENSE_1_0.txt or copy at 00033 // http://www.boost.org/LICENSE_1_0.txt) 00034 // -- End original copyright -- 00035 00036 #ifndef __OGRE_ANY_H__ 00037 #define __OGRE_ANY_H__ 00038 00039 #include "OgrePrerequisites.h" 00040 #include "OgreException.h" 00041 #include "OgreString.h" 00042 #include <algorithm> 00043 #include <typeinfo> 00044 00045 00046 namespace Ogre 00047 { 00056 class Any 00057 { 00058 public: // constructors 00059 00060 Any() 00061 : mContent(0) 00062 { 00063 } 00064 00065 template<typename ValueType> 00066 explicit Any(const ValueType & value) 00067 : mContent(OGRE_NEW_T(holder<ValueType>, MEMCATEGORY_GENERAL)(value)) 00068 { 00069 } 00070 00071 Any(const Any & other) 00072 : mContent(other.mContent ? other.mContent->clone() : 0) 00073 { 00074 } 00075 00076 virtual ~Any() 00077 { 00078 destroy(); 00079 } 00080 00081 public: // modifiers 00082 00083 Any& swap(Any & rhs) 00084 { 00085 std::swap(mContent, rhs.mContent); 00086 return *this; 00087 } 00088 00089 template<typename ValueType> 00090 Any& operator=(const ValueType & rhs) 00091 { 00092 Any(rhs).swap(*this); 00093 return *this; 00094 } 00095 00096 Any & operator=(const Any & rhs) 00097 { 00098 Any(rhs).swap(*this); 00099 return *this; 00100 } 00101 00102 public: // queries 00103 00104 bool isEmpty() const 00105 { 00106 return !mContent; 00107 } 00108 00109 const std::type_info& getType() const 00110 { 00111 return mContent ? mContent->getType() : typeid(void); 00112 } 00113 00114 inline friend std::ostream& operator << 00115 ( std::ostream& o, const Any& v ) 00116 { 00117 if (v.mContent) 00118 v.mContent->writeToStream(o); 00119 return o; 00120 } 00121 00122 void destroy() 00123 { 00124 OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL); 00125 mContent = NULL; 00126 } 00127 00128 protected: // types 00129 00130 class placeholder 00131 { 00132 public: // structors 00133 00134 virtual ~placeholder() 00135 { 00136 } 00137 00138 public: // queries 00139 00140 virtual const std::type_info& getType() const = 0; 00141 00142 virtual placeholder * clone() const = 0; 00143 00144 virtual void writeToStream(std::ostream& o) = 0; 00145 00146 }; 00147 00148 template<typename ValueType> 00149 class holder : public placeholder 00150 { 00151 public: // structors 00152 00153 holder(const ValueType & value) 00154 : held(value) 00155 { 00156 } 00157 00158 public: // queries 00159 00160 virtual const std::type_info & getType() const 00161 { 00162 return typeid(ValueType); 00163 } 00164 00165 virtual placeholder * clone() const 00166 { 00167 return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held); 00168 } 00169 00170 virtual void writeToStream(std::ostream& o) 00171 { 00172 o << held; 00173 } 00174 00175 00176 public: // representation 00177 00178 ValueType held; 00179 00180 }; 00181 00182 00183 00184 protected: // representation 00185 placeholder * mContent; 00186 00187 template<typename ValueType> 00188 friend ValueType * any_cast(Any *); 00189 00190 00191 public: 00192 00193 template<typename ValueType> 00194 ValueType operator()() const 00195 { 00196 if (!mContent) 00197 { 00198 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00199 "Bad cast from uninitialised Any", 00200 "Any::operator()"); 00201 } 00202 else if(getType() == typeid(ValueType)) 00203 { 00204 return static_cast<Any::holder<ValueType> *>(mContent)->held; 00205 } 00206 else 00207 { 00208 StringUtil::StrStreamType str; 00209 str << "Bad cast from type '" << getType().name() << "' " 00210 << "to '" << typeid(ValueType).name() << "'"; 00211 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00212 str.str(), 00213 "Any::operator()"); 00214 } 00215 } 00216 00217 template <typename ValueType> 00218 ValueType get(void) const 00219 { 00220 if (!mContent) 00221 { 00222 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00223 "Bad cast from uninitialised Any", 00224 "Any::operator()"); 00225 } 00226 else if(getType() == typeid(ValueType)) 00227 { 00228 return static_cast<Any::holder<ValueType> *>(mContent)->held; 00229 } 00230 else 00231 { 00232 StringUtil::StrStreamType str; 00233 str << "Bad cast from type '" << getType().name() << "' " 00234 << "to '" << typeid(ValueType).name() << "'"; 00235 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00236 str.str(), 00237 "Any::operator()"); 00238 } 00239 } 00240 00241 }; 00242 00243 00247 class AnyNumeric : public Any 00248 { 00249 public: 00250 AnyNumeric() 00251 : Any() 00252 { 00253 } 00254 00255 template<typename ValueType> 00256 AnyNumeric(const ValueType & value) 00257 00258 { 00259 mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value); 00260 } 00261 00262 AnyNumeric(const AnyNumeric & other) 00263 : Any() 00264 { 00265 mContent = other.mContent ? other.mContent->clone() : 0; 00266 } 00267 00268 protected: 00269 class numplaceholder : public Any::placeholder 00270 { 00271 public: // structors 00272 00273 ~numplaceholder() 00274 { 00275 } 00276 virtual placeholder* add(placeholder* rhs) = 0; 00277 virtual placeholder* subtract(placeholder* rhs) = 0; 00278 virtual placeholder* multiply(placeholder* rhs) = 0; 00279 virtual placeholder* multiply(Real factor) = 0; 00280 virtual placeholder* divide(placeholder* rhs) = 0; 00281 }; 00282 00283 template<typename ValueType> 00284 class numholder : public numplaceholder 00285 { 00286 public: // structors 00287 00288 numholder(const ValueType & value) 00289 : held(value) 00290 { 00291 } 00292 00293 public: // queries 00294 00295 virtual const std::type_info & getType() const 00296 { 00297 return typeid(ValueType); 00298 } 00299 00300 virtual placeholder * clone() const 00301 { 00302 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held); 00303 } 00304 00305 virtual placeholder* add(placeholder* rhs) 00306 { 00307 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held); 00308 } 00309 virtual placeholder* subtract(placeholder* rhs) 00310 { 00311 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held); 00312 } 00313 virtual placeholder* multiply(placeholder* rhs) 00314 { 00315 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held); 00316 } 00317 virtual placeholder* multiply(Real factor) 00318 { 00319 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor); 00320 } 00321 virtual placeholder* divide(placeholder* rhs) 00322 { 00323 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held); 00324 } 00325 virtual void writeToStream(std::ostream& o) 00326 { 00327 o << held; 00328 } 00329 00330 public: // representation 00331 00332 ValueType held; 00333 00334 }; 00335 00337 AnyNumeric(placeholder* pholder) 00338 { 00339 mContent = pholder; 00340 } 00341 00342 public: 00343 AnyNumeric & operator=(const AnyNumeric & rhs) 00344 { 00345 AnyNumeric(rhs).swap(*this); 00346 return *this; 00347 } 00348 AnyNumeric operator+(const AnyNumeric& rhs) const 00349 { 00350 return AnyNumeric( 00351 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00352 } 00353 AnyNumeric operator-(const AnyNumeric& rhs) const 00354 { 00355 return AnyNumeric( 00356 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00357 } 00358 AnyNumeric operator*(const AnyNumeric& rhs) const 00359 { 00360 return AnyNumeric( 00361 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00362 } 00363 AnyNumeric operator*(Real factor) const 00364 { 00365 return AnyNumeric( 00366 static_cast<numplaceholder*>(mContent)->multiply(factor)); 00367 } 00368 AnyNumeric operator/(const AnyNumeric& rhs) const 00369 { 00370 return AnyNumeric( 00371 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00372 } 00373 AnyNumeric& operator+=(const AnyNumeric& rhs) 00374 { 00375 *this = AnyNumeric( 00376 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00377 return *this; 00378 } 00379 AnyNumeric& operator-=(const AnyNumeric& rhs) 00380 { 00381 *this = AnyNumeric( 00382 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00383 return *this; 00384 } 00385 AnyNumeric& operator*=(const AnyNumeric& rhs) 00386 { 00387 *this = AnyNumeric( 00388 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00389 return *this; 00390 } 00391 AnyNumeric& operator/=(const AnyNumeric& rhs) 00392 { 00393 *this = AnyNumeric( 00394 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00395 return *this; 00396 } 00397 00398 00399 00400 00401 }; 00402 00403 00404 template<typename ValueType> 00405 ValueType * any_cast(Any * operand) 00406 { 00407 return operand && (std::strcmp(operand->getType().name(), typeid(ValueType).name()) == 0) 00408 ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held 00409 : 0; 00410 } 00411 00412 template<typename ValueType> 00413 const ValueType * any_cast(const Any * operand) 00414 { 00415 return any_cast<ValueType>(const_cast<Any *>(operand)); 00416 } 00417 00418 template<typename ValueType> 00419 ValueType any_cast(const Any & operand) 00420 { 00421 const ValueType * result = any_cast<ValueType>(&operand); 00422 if(!result) 00423 { 00424 StringUtil::StrStreamType str; 00425 str << "Bad cast from type '" << operand.getType().name() << "' " 00426 << "to '" << typeid(ValueType).name() << "'"; 00427 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00428 str.str(), 00429 "Ogre::any_cast"); 00430 } 00431 return *result; 00432 } 00437 } 00438 00439 #endif 00440
Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:20