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

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat May 10 16:24:56 2008