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-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) Any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 Any WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 // -- Based on boost::any, original copyright information follows -- 00030 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00031 // 00032 // Distributed under the Boost Software License, Version 1.0. (See 00033 // accompAnying file LICENSE_1_0.txt or copy at 00034 // http://www.boost.org/LICENSE_1_0.txt) 00035 // -- End original copyright -- 00036 00037 #ifndef __OGRE_ANY_H__ 00038 #define __OGRE_ANY_H__ 00039 00040 #include "OgrePrerequisites.h" 00041 #include "OgreException.h" 00042 #include "OgreString.h" 00043 #include <algorithm> 00044 #include <typeinfo> 00045 00046 00047 namespace Ogre 00048 { 00051 class Any 00052 { 00053 public: // constructors 00054 00055 Any() 00056 : mContent(0) 00057 { 00058 } 00059 00060 template<typename ValueType> 00061 explicit Any(const ValueType & value) 00062 : mContent(OGRE_NEW_T(holder<ValueType>, MEMCATEGORY_GENERAL)(value)) 00063 { 00064 } 00065 00066 Any(const Any & other) 00067 : mContent(other.mContent ? other.mContent->clone() : 0) 00068 { 00069 } 00070 00071 virtual ~Any() 00072 { 00073 OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL); 00074 } 00075 00076 public: // modifiers 00077 00078 Any& swap(Any & rhs) 00079 { 00080 std::swap(mContent, rhs.mContent); 00081 return *this; 00082 } 00083 00084 template<typename ValueType> 00085 Any& operator=(const ValueType & rhs) 00086 { 00087 Any(rhs).swap(*this); 00088 return *this; 00089 } 00090 00091 Any & operator=(const Any & rhs) 00092 { 00093 Any(rhs).swap(*this); 00094 return *this; 00095 } 00096 00097 public: // queries 00098 00099 bool isEmpty() const 00100 { 00101 return !mContent; 00102 } 00103 00104 const std::type_info& getType() const 00105 { 00106 return mContent ? mContent->getType() : typeid(void); 00107 } 00108 00109 inline friend std::ostream& operator << 00110 ( std::ostream& o, const Any& v ) 00111 { 00112 if (v.mContent) 00113 v.mContent->writeToStream(o); 00114 return o; 00115 } 00116 00117 00118 protected: // types 00119 00120 class placeholder 00121 { 00122 public: // structors 00123 00124 virtual ~placeholder() 00125 { 00126 } 00127 00128 public: // queries 00129 00130 virtual const std::type_info& getType() const = 0; 00131 00132 virtual placeholder * clone() const = 0; 00133 00134 virtual void writeToStream(std::ostream& o) = 0; 00135 00136 }; 00137 00138 template<typename ValueType> 00139 class holder : public placeholder 00140 { 00141 public: // structors 00142 00143 holder(const ValueType & value) 00144 : held(value) 00145 { 00146 } 00147 00148 public: // queries 00149 00150 virtual const std::type_info & getType() const 00151 { 00152 return typeid(ValueType); 00153 } 00154 00155 virtual placeholder * clone() const 00156 { 00157 return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held); 00158 } 00159 00160 virtual void writeToStream(std::ostream& o) 00161 { 00162 o << held; 00163 } 00164 00165 00166 public: // representation 00167 00168 ValueType held; 00169 00170 }; 00171 00172 00173 00174 protected: // representation 00175 placeholder * mContent; 00176 00177 template<typename ValueType> 00178 friend ValueType * any_cast(Any *); 00179 00180 00181 public: 00182 00183 template<typename ValueType> 00184 ValueType operator()() const 00185 { 00186 if (!mContent) 00187 { 00188 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00189 "Bad cast from uninitialised Any", 00190 "Any::operator()"); 00191 } 00192 else if(getType() == typeid(ValueType)) 00193 { 00194 return static_cast<Any::holder<ValueType> *>(mContent)->held; 00195 } 00196 else 00197 { 00198 StringUtil::StrStreamType str; 00199 str << "Bad cast from type '" << getType().name() << "' " 00200 << "to '" << typeid(ValueType).name() << "'"; 00201 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00202 str.str(), 00203 "Any::operator()"); 00204 } 00205 } 00206 00207 00208 00209 }; 00210 00211 00215 class AnyNumeric : public Any 00216 { 00217 public: 00218 AnyNumeric() 00219 : Any() 00220 { 00221 } 00222 00223 template<typename ValueType> 00224 AnyNumeric(const ValueType & value) 00225 00226 { 00227 mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value); 00228 } 00229 00230 AnyNumeric(const AnyNumeric & other) 00231 : Any() 00232 { 00233 mContent = other.mContent ? other.mContent->clone() : 0; 00234 } 00235 00236 protected: 00237 class numplaceholder : public Any::placeholder 00238 { 00239 public: // structors 00240 00241 ~numplaceholder() 00242 { 00243 } 00244 virtual placeholder* add(placeholder* rhs) = 0; 00245 virtual placeholder* subtract(placeholder* rhs) = 0; 00246 virtual placeholder* multiply(placeholder* rhs) = 0; 00247 virtual placeholder* multiply(Real factor) = 0; 00248 virtual placeholder* divide(placeholder* rhs) = 0; 00249 }; 00250 00251 template<typename ValueType> 00252 class numholder : public numplaceholder 00253 { 00254 public: // structors 00255 00256 numholder(const ValueType & value) 00257 : held(value) 00258 { 00259 } 00260 00261 public: // queries 00262 00263 virtual const std::type_info & getType() const 00264 { 00265 return typeid(ValueType); 00266 } 00267 00268 virtual placeholder * clone() const 00269 { 00270 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held); 00271 } 00272 00273 virtual placeholder* add(placeholder* rhs) 00274 { 00275 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held); 00276 } 00277 virtual placeholder* subtract(placeholder* rhs) 00278 { 00279 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held); 00280 } 00281 virtual placeholder* multiply(placeholder* rhs) 00282 { 00283 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held); 00284 } 00285 virtual placeholder* multiply(Real factor) 00286 { 00287 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor); 00288 } 00289 virtual placeholder* divide(placeholder* rhs) 00290 { 00291 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held); 00292 } 00293 virtual void writeToStream(std::ostream& o) 00294 { 00295 o << held; 00296 } 00297 00298 public: // representation 00299 00300 ValueType held; 00301 00302 }; 00303 00305 AnyNumeric(placeholder* pholder) 00306 { 00307 mContent = pholder; 00308 } 00309 00310 public: 00311 AnyNumeric & operator=(const AnyNumeric & rhs) 00312 { 00313 AnyNumeric(rhs).swap(*this); 00314 return *this; 00315 } 00316 AnyNumeric operator+(const AnyNumeric& rhs) const 00317 { 00318 return AnyNumeric( 00319 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00320 } 00321 AnyNumeric operator-(const AnyNumeric& rhs) const 00322 { 00323 return AnyNumeric( 00324 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00325 } 00326 AnyNumeric operator*(const AnyNumeric& rhs) const 00327 { 00328 return AnyNumeric( 00329 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00330 } 00331 AnyNumeric operator*(Real factor) const 00332 { 00333 return AnyNumeric( 00334 static_cast<numplaceholder*>(mContent)->multiply(factor)); 00335 } 00336 AnyNumeric operator/(const AnyNumeric& rhs) const 00337 { 00338 return AnyNumeric( 00339 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00340 } 00341 AnyNumeric& operator+=(const AnyNumeric& rhs) 00342 { 00343 *this = AnyNumeric( 00344 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00345 return *this; 00346 } 00347 AnyNumeric& operator-=(const AnyNumeric& rhs) 00348 { 00349 *this = AnyNumeric( 00350 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00351 return *this; 00352 } 00353 AnyNumeric& operator*=(const AnyNumeric& rhs) 00354 { 00355 *this = AnyNumeric( 00356 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00357 return *this; 00358 } 00359 AnyNumeric& operator/=(const AnyNumeric& rhs) 00360 { 00361 *this = AnyNumeric( 00362 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00363 return *this; 00364 } 00365 00366 00367 00368 00369 }; 00370 00371 00372 template<typename ValueType> 00373 ValueType * any_cast(Any * operand) 00374 { 00375 return operand && operand->getType() == typeid(ValueType) 00376 ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held 00377 : 0; 00378 } 00379 00380 template<typename ValueType> 00381 const ValueType * any_cast(const Any * operand) 00382 { 00383 return any_cast<ValueType>(const_cast<Any *>(operand)); 00384 } 00385 00386 template<typename ValueType> 00387 ValueType any_cast(const Any & operand) 00388 { 00389 const ValueType * result = any_cast<ValueType>(&operand); 00390 if(!result) 00391 { 00392 StringUtil::StrStreamType str; 00393 str << "Bad cast from type '" << operand.getType().name() << "' " 00394 << "to '" << typeid(ValueType).name() << "'"; 00395 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00396 str.str(), 00397 "Ogre::any_cast"); 00398 } 00399 return *result; 00400 } 00401 00402 00403 } 00404 00405 #endif 00406
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:22 2009