Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | 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-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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun May 6 10:54:20 2007