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(new holder<ValueType>(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 delete mContent; 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 new holder(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 = new numholder<ValueType>(value); 00228 } 00229 00230 AnyNumeric(const AnyNumeric & other) 00231 : Any() 00232 { 00233 mContent = other.mContent ? other.mContent->clone() : 0; 00234 } 00235 protected: 00236 class numplaceholder : public Any::placeholder 00237 { 00238 public: // structors 00239 00240 ~numplaceholder() 00241 { 00242 } 00243 virtual placeholder* add(placeholder* rhs) = 0; 00244 virtual placeholder* subtract(placeholder* rhs) = 0; 00245 virtual placeholder* multiply(placeholder* rhs) = 0; 00246 virtual placeholder* multiply(Real factor) = 0; 00247 virtual placeholder* divide(placeholder* rhs) = 0; 00248 }; 00249 00250 template<typename ValueType> 00251 class numholder : public numplaceholder 00252 { 00253 public: // structors 00254 00255 numholder(const ValueType & value) 00256 : held(value) 00257 { 00258 } 00259 00260 public: // queries 00261 00262 virtual const std::type_info & getType() const 00263 { 00264 return typeid(ValueType); 00265 } 00266 00267 virtual placeholder * clone() const 00268 { 00269 return new numholder(held); 00270 } 00271 00272 virtual placeholder* add(placeholder* rhs) 00273 { 00274 return new numholder(held + static_cast<numholder*>(rhs)->held); 00275 } 00276 virtual placeholder* subtract(placeholder* rhs) 00277 { 00278 return new numholder(held - static_cast<numholder*>(rhs)->held); 00279 } 00280 virtual placeholder* multiply(placeholder* rhs) 00281 { 00282 return new numholder(held * static_cast<numholder*>(rhs)->held); 00283 } 00284 virtual placeholder* multiply(Real factor) 00285 { 00286 return new numholder(held * factor); 00287 } 00288 virtual placeholder* divide(placeholder* rhs) 00289 { 00290 return new numholder(held / static_cast<numholder*>(rhs)->held); 00291 } 00292 virtual void writeToStream(std::ostream& o) 00293 { 00294 o << held; 00295 } 00296 00297 public: // representation 00298 00299 ValueType held; 00300 00301 }; 00302 00304 AnyNumeric(placeholder* pholder) 00305 { 00306 mContent = pholder; 00307 } 00308 00309 public: 00310 AnyNumeric & operator=(const AnyNumeric & rhs) 00311 { 00312 AnyNumeric(rhs).swap(*this); 00313 return *this; 00314 } 00315 AnyNumeric operator+(const AnyNumeric& rhs) const 00316 { 00317 return AnyNumeric( 00318 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00319 } 00320 AnyNumeric operator-(const AnyNumeric& rhs) const 00321 { 00322 return AnyNumeric( 00323 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00324 } 00325 AnyNumeric operator*(const AnyNumeric& rhs) const 00326 { 00327 return AnyNumeric( 00328 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00329 } 00330 AnyNumeric operator*(Real factor) const 00331 { 00332 return AnyNumeric( 00333 static_cast<numplaceholder*>(mContent)->multiply(factor)); 00334 } 00335 AnyNumeric operator/(const AnyNumeric& rhs) const 00336 { 00337 return AnyNumeric( 00338 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00339 } 00340 AnyNumeric& operator+=(const AnyNumeric& rhs) 00341 { 00342 *this = AnyNumeric( 00343 static_cast<numplaceholder*>(mContent)->add(rhs.mContent)); 00344 return *this; 00345 } 00346 AnyNumeric& operator-=(const AnyNumeric& rhs) 00347 { 00348 *this = AnyNumeric( 00349 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent)); 00350 return *this; 00351 } 00352 AnyNumeric& operator*=(const AnyNumeric& rhs) 00353 { 00354 *this = AnyNumeric( 00355 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent)); 00356 return *this; 00357 } 00358 AnyNumeric& operator/=(const AnyNumeric& rhs) 00359 { 00360 *this = AnyNumeric( 00361 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent)); 00362 return *this; 00363 } 00364 00365 00366 00367 00368 }; 00369 00370 00371 template<typename ValueType> 00372 ValueType * any_cast(Any * operand) 00373 { 00374 return operand && operand->getType() == typeid(ValueType) 00375 ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held 00376 : 0; 00377 } 00378 00379 template<typename ValueType> 00380 const ValueType * any_cast(const Any * operand) 00381 { 00382 return any_cast<ValueType>(const_cast<Any *>(operand)); 00383 } 00384 00385 template<typename ValueType> 00386 ValueType any_cast(const Any & operand) 00387 { 00388 const ValueType * result = any_cast<ValueType>(&operand); 00389 if(!result) 00390 { 00391 StringUtil::StrStreamType str; 00392 str << "Bad cast from type '" << operand.getType().name() << "' " 00393 << "to '" << typeid(ValueType).name() << "'"; 00394 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 00395 str.str(), 00396 "Ogre::any_cast"); 00397 } 00398 return *result; 00399 } 00400 00401 00402 } 00403 00404 #endif 00405
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Mon Aug 20 13:50:45 2007