Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:36 2006