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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:22 2009