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