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-2005 The OGRE Team 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 */ 00025 // -- Based on boost::any, original copyright information follows -- 00026 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00027 // 00028 // Distributed under the Boost Software License, Version 1.0. (See 00029 // accompAnying file LICENSE_1_0.txt or copy at 00030 // http://www.boost.org/LICENSE_1_0.txt) 00031 // -- End original copyright -- 00032 00033 #ifndef __OGRE_ANY_H__ 00034 #define __OGRE_ANY_H__ 00035 00036 #include "OgrePrerequisites.h" 00037 #include "OgreException.h" 00038 #include "OgreString.h" 00039 #include <algorithm> 00040 #include <typeinfo> 00041 00042 00043 namespace Ogre 00044 { 00047 class Any 00048 { 00049 public: // constructors 00050 00051 Any() 00052 : mContent(0) 00053 { 00054 } 00055 00056 template<typename ValueType> 00057 explicit Any(const ValueType & value) 00058 : mContent(new holder<ValueType>(value)) 00059 { 00060 } 00061 00062 Any(const Any & other) 00063 : mContent(other.mContent ? other.mContent->clone() : 0) 00064 { 00065 } 00066 00067 virtual ~Any() 00068 { 00069 delete mContent; 00070 } 00071 00072 public: // modifiers 00073 00074 Any& swap(Any & rhs) 00075 { 00076 std::swap(mContent, rhs.mContent); 00077 return *this; 00078 } 00079 00080 template<typename ValueType> 00081 Any& operator=(const ValueType & rhs) 00082 { 00083 Any(rhs).swap(*this); 00084 return *this; 00085 } 00086 00087 Any & operator=(const Any & rhs) 00088 { 00089 Any(rhs).swap(*this); 00090 return *this; 00091 } 00092 00093 public: // queries 00094 00095 bool isEmpty() const 00096 { 00097 return !mContent; 00098 } 00099 00100 const std::type_info& getType() const 00101 { 00102 return mContent ? mContent->getType() : typeid(void); 00103 } 00104 00105 inline friend std::ostream& operator << 00106 ( std::ostream& o, const Any& v ) 00107 { 00108 if (v.mContent) 00109 v.mContent->writeToStream(o); 00110 return o; 00111 } 00112 00113 00114 protected: // types 00115 00116 class placeholder 00117 { 00118 public: // structors 00119 00120 virtual ~placeholder() 00121 { 00122 } 00123 00124 public: // queries 00125 00126 virtual const std::type_info& getType() const = 0; 00127 00128 virtual placeholder * clone() const = 0; 00129 00130 virtual void writeToStream(std::ostream& o) = 0; 00131 00132 }; 00133 00134 template<typename ValueType> 00135 class holder : public placeholder 00136 { 00137 public: // structors 00138 00139 holder(const ValueType & value) 00140 : held(value) 00141 { 00142 } 00143 00144 public: // queries 00145 00146 virtual const std::type_info & getType() const 00147 { 00148 return typeid(ValueType); 00149 } 00150 00151 virtual placeholder * clone() const 00152 { 00153 return new holder(held); 00154 } 00155 00156 virtual void writeToStream(std::ostream& o) 00157 { 00158 o << held; 00159 } 00160 00161 00162 public: // representation 00163 00164 ValueType held; 00165 00166 }; 00167 00168 00169 00170 protected: // representation 00171 placeholder * mContent; 00172 00173 template<typename ValueType> 00174 friend ValueType * any_cast(Any *); 00175 00176 00177 public: 00178 00179 template<typename ValueType> 00180 ValueType operator()() const 00181 { 00182 if (!mContent) 00183 { 00184 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00185 "Bad cast from uninitialised Any", 00186 "Any::operator()"); 00187 } 00188 else if(getType() == typeid(ValueType)) 00189 { 00190 return static_cast<Any::holder<ValueType> *>(mContent)->held; 00191 } 00192 else 00193 { 00194 StringUtil::StrStreamType str; 00195 str << "Bad cast from type '" << getType().name() << "' " 00196 << "to '" << typeid(ValueType).name() << "'"; 00197 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00198 str.str(), 00199 "Any::operator()"); 00200 } 00201 } 00202 00203 00204 00205 }; 00206 00207 00211 class AnyNumeric : public Any 00212 { 00213 public: 00214 AnyNumeric() 00215 : Any() 00216 { 00217 } 00218 00219 template<typename ValueType> 00220 AnyNumeric(const ValueType & value) 00221 00222 { 00223 mContent = new numholder<ValueType>(value); 00224 } 00225 00226 AnyNumeric(const AnyNumeric & other) 00227 : Any() 00228 { 00229 mContent = other.mContent ? other.mContent->clone() : 0; 00230 } 00231 protected: 00232 class numplaceholder : public Any::placeholder 00233 { 00234 public: // structors 00235 00236 ~numplaceholder() 00237 { 00238 } 00239 virtual placeholder* add(placeholder* rhs) = 0; 00240 virtual placeholder* subtract(placeholder* rhs) = 0; 00241 virtual placeholder* multiply(placeholder* rhs) = 0; 00242 virtual placeholder* multiply(Real factor) = 0; 00243 virtual placeholder* divide(placeholder* rhs) = 0; 00244 }; 00245 00246 template<typename ValueType> 00247 class numholder : public numplaceholder 00248 { 00249 public: // structors 00250 00251 numholder(const ValueType & value) 00252 : held(value) 00253 { 00254 } 00255 00256 public: // queries 00257 00258 virtual const std::type_info & getType() const 00259 { 00260 return typeid(ValueType); 00261 } 00262 00263 virtual placeholder * clone() const 00264 { 00265 return new numholder(held); 00266 } 00267 00268 virtual placeholder* add(placeholder* rhs) 00269 { 00270 return new numholder(held + static_cast<numholder*>(rhs)->held); 00271 } 00272 virtual placeholder* subtract(placeholder* rhs) 00273 { 00274 return new numholder(held - static_cast<numholder*>(rhs)->held); 00275 } 00276 virtual placeholder* multiply(placeholder* rhs) 00277 { 00278 return new numholder(held * static_cast<numholder*>(rhs)->held); 00279 } 00280 virtual placeholder* multiply(Real factor) 00281 { 00282 return new numholder(held * factor); 00283 } 00284 virtual placeholder* divide(placeholder* rhs) 00285 { 00286 return new numholder(held / static_cast<numholder*>(rhs)->held); 00287 } 00288 virtual void writeToStream(std::ostream& o) 00289 { 00290 o << held; 00291 } 00292 00293 public: // representation 00294 00295 ValueType held; 00296 00297 }; 00298 00300 AnyNumeric(placeholder* pholder) 00301 { 00302 mContent = pholder; 00303 } 00304 00305 public: 00306 AnyNumeric & operator=(const AnyNumeric & rhs) 00307 { 00308 AnyNumeric(rhs).swap(*this); 00309 return *this; 00310 } 00311 AnyNumeric operator+(const AnyNumeric& rhs) const 00312 { 00313 return AnyNumeric( 00314 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00315 } 00316 AnyNumeric operator-(const AnyNumeric& rhs) const 00317 { 00318 return AnyNumeric( 00319 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00320 } 00321 AnyNumeric operator*(const AnyNumeric& rhs) const 00322 { 00323 return AnyNumeric( 00324 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00325 } 00326 AnyNumeric operator*(Real factor) const 00327 { 00328 return AnyNumeric( 00329 static_cast<numplaceholder*>(mContent)->multiply(factor)); 00330 } 00331 AnyNumeric operator/(const AnyNumeric& rhs) const 00332 { 00333 return AnyNumeric( 00334 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00335 } 00336 AnyNumeric& operator+=(const AnyNumeric& rhs) 00337 { 00338 *this = AnyNumeric( 00339 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00340 return *this; 00341 } 00342 AnyNumeric& operator-=(const AnyNumeric& rhs) 00343 { 00344 *this = AnyNumeric( 00345 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00346 return *this; 00347 } 00348 AnyNumeric& operator*=(const AnyNumeric& rhs) 00349 { 00350 *this = AnyNumeric( 00351 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00352 return *this; 00353 } 00354 AnyNumeric& operator/=(const AnyNumeric& rhs) 00355 { 00356 *this = AnyNumeric( 00357 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00358 return *this; 00359 } 00360 00361 00362 00363 00364 }; 00365 00366 00367 template<typename ValueType> 00368 ValueType * any_cast(Any * operand) 00369 { 00370 return operand && operand->getType() == typeid(ValueType) 00371 ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held 00372 : 0; 00373 } 00374 00375 template<typename ValueType> 00376 const ValueType * any_cast(const Any * operand) 00377 { 00378 return any_cast<ValueType>(const_cast<Any *>(operand)); 00379 } 00380 00381 template<typename ValueType> 00382 ValueType any_cast(const Any & operand) 00383 { 00384 const ValueType * result = any_cast<ValueType>(&operand); 00385 if(!result) 00386 { 00387 StringUtil::StrStreamType str; 00388 str << "Bad cast from type '" << operand.getType().name() << "' " 00389 << "to '" << typeid(ValueType).name() << "'"; 00390 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00391 str.str(), 00392 "Ogre::any_cast"); 00393 } 00394 return *result; 00395 } 00396 00397 00398 } 00399 00400 #endif 00401
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:36 2006