00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OpenSpace3D 00004 For the latest info, see http://www.openspace3d.com 00005 00006 Copyright (c) 2010 I-maginer 00007 00008 This program is free software; you can redistribute it and/or modify it under 00009 the terms of the GNU Lesser General Public License as published by the Free Software 00010 Foundation; either version 2 of the License, or (at your option) any later 00011 version. 00012 00013 This program is distributed in the hope that it will be useful, but WITHOUT 00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License along with 00018 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00019 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00020 http://www.gnu.org/copyleft/lesser.txt 00021 00022 You may alternatively use this source under the terms of a specific version of 00023 the OpenSpace3D Unrestricted License provided you have obtained such a license from 00024 I-maginer. 00025 ----------------------------------------------------------------------------- 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 __SO3_ANY_H__ 00037 #define __SO3_ANY_H__ 00038 00039 #include "../SCOLBasic/SO3Prerequisites.h" 00040 #include "../SCOLBasic/SO3Std.h" 00041 #include "OgreException.h" 00042 #include <algorithm> 00043 #include <typeinfo> 00044 00045 namespace SO3 00046 { 00047 00051 class SAny 00052 { 00053 public: 00056 class placeholder 00057 { 00058 public: 00059 protected: 00060 private: 00061 00062 public: 00065 virtual ~placeholder() 00066 { 00067 } 00068 00071 virtual const std::type_info& GetType() const = 0; 00072 00075 virtual placeholder* Clone() const = 0; 00076 00079 virtual void WriteToStream(std::ostream& o) = 0; 00080 protected: 00081 private: 00082 }; 00083 00086 template<typename ValueType> class holder : public placeholder 00087 { 00088 public: 00089 ValueType held; 00090 protected: 00091 private: 00092 00093 public: 00096 holder(const ValueType& value) : held(value) 00097 { 00098 } 00099 00102 virtual const std::type_info& GetType() const 00103 { 00104 return typeid(ValueType); 00105 } 00106 00109 virtual placeholder* Clone() const 00110 { 00111 return new holder(held); 00112 } 00113 00116 virtual void WriteToStream(std::ostream& o) 00117 { 00118 o << held; 00119 } 00120 }; 00121 00122 protected: 00123 placeholder* mContent; 00124 template<typename ValueType> friend ValueType* any_cast(SAny *); 00125 private: 00126 00127 public: 00130 SAny() : mContent(0) 00131 { 00132 } 00133 00136 template<typename ValueType> explicit SAny(const ValueType& value) : mContent(new holder<ValueType>(value)) 00137 { 00138 } 00139 00142 SAny(const SAny& other) : mContent(other.mContent ? other.mContent->Clone() : 0) 00143 { 00144 } 00145 00148 virtual ~SAny() 00149 { 00150 Destroy(); 00151 } 00152 00155 SAny& Swap(SAny& rhs) 00156 { 00157 std::swap(mContent, rhs.mContent); 00158 return *this; 00159 } 00160 00163 template<typename ValueType> SAny& operator=(const ValueType& rhs) 00164 { 00165 SAny(rhs).Swap(*this); 00166 return *this; 00167 } 00168 00171 SAny& operator=(const SAny& rhs) 00172 { 00173 SAny(rhs).Swap(*this); 00174 return *this; 00175 } 00176 00179 bool IsEmpty() const 00180 { 00181 return !mContent; 00182 } 00183 00186 const std::type_info& GetType() const 00187 { 00188 return mContent ? mContent->GetType() : typeid(void); 00189 } 00190 00193 inline friend std::ostream& operator <<(std::ostream& o, const SAny& v) 00194 { 00195 if (v.mContent) 00196 v.mContent->WriteToStream(o); 00197 return o; 00198 } 00199 00202 void Destroy() 00203 { 00204 SAFE_DELETE(mContent); 00205 } 00206 00209 template<typename ValueType> ValueType operator()() const 00210 { 00211 if(!mContent) 00212 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Bad cast from uninitialised SAny", "SAny::operator()"); 00213 else if(GetType() == typeid(ValueType)) 00214 return static_cast<SAny::holder<ValueType>*>(mContent)->held; 00215 else 00216 { 00217 std::ostringstream str; 00218 str << "Bad cast from type '" << GetType().name() << "' " << "to '" << typeid(ValueType).name() << "'"; 00219 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, str.str(), "SAny::operator()"); 00220 } 00221 } 00222 }; 00223 00228 class SAnyNumeric : public SAny 00229 { 00230 public: 00231 protected: 00234 class numplaceholder : public SAny::placeholder 00235 { 00236 public: 00237 protected: 00238 private: 00239 00240 public: 00243 ~numplaceholder() 00244 { 00245 } 00246 00249 virtual placeholder* Add(placeholder* rhs) = 0; 00250 00253 virtual placeholder* Subtract(placeholder* rhs) = 0; 00254 00257 virtual placeholder* Multiply(placeholder* rhs) = 0; 00258 00261 virtual placeholder* Multiply(float factor) = 0; 00262 00265 virtual placeholder* Divide(placeholder* rhs) = 0; 00266 protected: 00267 private: 00268 }; 00269 00272 template<typename ValueType> class numholder : public numplaceholder 00273 { 00274 public: 00275 ValueType held; 00276 protected: 00277 private: 00278 00279 public: 00282 numholder(const ValueType& value) : held(value) 00283 { 00284 } 00285 00288 virtual const std::type_info& GetType() const 00289 { 00290 return typeid(ValueType); 00291 } 00292 00295 virtual placeholder* Clone() const 00296 { 00297 return new numholder(held); 00298 } 00299 00302 virtual placeholder* Add(placeholder* rhs) 00303 { 00304 return new numholder(held + static_cast<numholder*>(rhs)->held); 00305 } 00306 00309 virtual placeholder* Subtract(placeholder* rhs) 00310 { 00311 return new numholder(held - static_cast<numholder*>(rhs)->held); 00312 } 00313 00316 virtual placeholder* Multiply(placeholder* rhs) 00317 { 00318 return new numholder(held * static_cast<numholder*>(rhs)->held); 00319 } 00320 00323 virtual placeholder* Multiply(float factor) 00324 { 00325 return new numholder(held * factor); 00326 } 00327 00330 virtual placeholder* Divide(placeholder* rhs) 00331 { 00332 return new numholder(held / static_cast<numholder*>(rhs)->held); 00333 } 00334 00337 virtual void WriteToStream(std::ostream& o) 00338 { 00339 o << held; 00340 } 00341 protected: 00342 private: 00343 }; 00344 private: 00345 00346 public: 00349 SAnyNumeric() : SAny() 00350 { 00351 } 00352 00355 template<typename ValueType> SAnyNumeric(const ValueType& value) 00356 { 00357 mContent = new numholder<ValueType>(value); 00358 } 00359 00362 SAnyNumeric(const SAnyNumeric& other) : SAny() 00363 { 00364 mContent = other.mContent ? other.mContent->Clone() : 0; 00365 } 00366 00369 SAnyNumeric(placeholder* pholder) 00370 { 00371 mContent = pholder; 00372 } 00373 00376 SAnyNumeric& operator=(const SAnyNumeric& rhs) 00377 { 00378 SAnyNumeric(rhs).Swap(*this); 00379 return *this; 00380 } 00381 00384 SAnyNumeric operator+(const SAnyNumeric& rhs) const 00385 { 00386 return SAnyNumeric(static_cast<numplaceholder*>(mContent)->Add(rhs.mContent)); 00387 } 00388 00391 SAnyNumeric operator-(const SAnyNumeric& rhs) const 00392 { 00393 return SAnyNumeric(static_cast<numplaceholder*>(mContent)->Subtract(rhs.mContent)); 00394 } 00395 00398 SAnyNumeric operator*(const SAnyNumeric& rhs) const 00399 { 00400 return SAnyNumeric(static_cast<numplaceholder*>(mContent)->Multiply(rhs.mContent)); 00401 } 00402 00405 SAnyNumeric operator*(float factor) const 00406 { 00407 return SAnyNumeric(static_cast<numplaceholder*>(mContent)->Multiply(factor)); 00408 } 00409 00412 SAnyNumeric operator/(const SAnyNumeric& rhs) const 00413 { 00414 return SAnyNumeric(static_cast<numplaceholder*>(mContent)->Divide(rhs.mContent)); 00415 } 00416 00419 SAnyNumeric& operator+=(const SAnyNumeric& rhs) 00420 { 00421 *this = SAnyNumeric(static_cast<numplaceholder*>(mContent)->Add(rhs.mContent)); 00422 return *this; 00423 } 00424 00427 SAnyNumeric& operator-=(const SAnyNumeric& rhs) 00428 { 00429 *this = SAnyNumeric(static_cast<numplaceholder*>(mContent)->Subtract(rhs.mContent)); 00430 return *this; 00431 } 00432 00435 SAnyNumeric& operator*=(const SAnyNumeric& rhs) 00436 { 00437 *this = SAnyNumeric(static_cast<numplaceholder*>(mContent)->Multiply(rhs.mContent)); 00438 return *this; 00439 } 00440 00443 SAnyNumeric& operator/=(const SAnyNumeric& rhs) 00444 { 00445 *this = SAnyNumeric(static_cast<numplaceholder*>(mContent)->Divide(rhs.mContent)); 00446 return *this; 00447 } 00448 protected: 00449 private: 00450 }; 00451 00454 template<typename ValueType> ValueType* any_cast(SAny* operand) 00455 { 00456 if(operand && operand->GetType() == typeid(ValueType)) 00457 return &static_cast<SAny::holder<ValueType>*>(operand->mContent)->held; 00458 else 00459 return 0; 00460 } 00461 00464 template<typename ValueType> const ValueType* any_cast(const SAny* operand) 00465 { 00466 return any_cast<ValueType>(const_cast<SAny*>(operand)); 00467 } 00468 00471 template<typename ValueType> ValueType any_cast(const SAny& operand) 00472 { 00473 const ValueType* result = any_cast<ValueType>(&operand); 00474 if(!result) 00475 { 00476 std::ostringstream str; 00477 str << "Bad cast from type '" << operand.GetType().name() << "' " << "to '" << typeid(ValueType).name() << "'"; 00478 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, str.str(), "any_cast"); 00479 } 00480 return *result; 00481 } 00482 00483 } 00484 00485 #endif
1.6.3