OgreAny.h

Go to the documentation of this file.
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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 23:36:23 2012