# 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-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 Sep 17 15:39:07 2006