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

Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat Apr 11 13:46:39 2009