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-2012 Torus Knot Software Ltd
00008 
00009 Permission is hereby granted, free of charge, to any person obtaining a copy
00010 of this software and associated documentation files (the "Software"), to deal
00011 in the Software without restriction, including without limitation the rights
00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00013 copies of the Software, and to permit persons to whom the Software is
00014 furnished to do so, subject to the following conditions:
00015 
00016 The above copyright notice and this permission notice shall be included in
00017 all copies or substantial portions of the Software.
00018 
00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00025 THE SOFTWARE.
00026 -----------------------------------------------------------------------------
00027 */
00028 // -- Based on boost::any, original copyright information follows --
00029 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00030 //
00031 // Distributed under the Boost Software License, Version 1.0. (See
00032 // accompAnying file LICENSE_1_0.txt or copy at
00033 // http://www.boost.org/LICENSE_1_0.txt)
00034 // -- End original copyright --
00035 
00036 #ifndef __OGRE_ANY_H__
00037 #define __OGRE_ANY_H__
00038 
00039 #include "OgrePrerequisites.h"
00040 #include "OgreException.h"
00041 #include "OgreString.h"
00042 #include <algorithm>
00043 #include <typeinfo>
00044 
00045 
00046 namespace Ogre
00047 {
00056     class Any 
00057     {
00058     public: // constructors
00059 
00060         Any()
00061           : mContent(0)
00062         {
00063         }
00064 
00065         template<typename ValueType>
00066         explicit Any(const ValueType & value)
00067           : mContent(OGRE_NEW_T(holder<ValueType>, MEMCATEGORY_GENERAL)(value))
00068         {
00069         }
00070 
00071         Any(const Any & other)
00072           : mContent(other.mContent ? other.mContent->clone() : 0)
00073         {
00074         }
00075 
00076         virtual ~Any()
00077         {
00078             destroy();
00079         }
00080 
00081     public: // modifiers
00082 
00083         Any& swap(Any & rhs)
00084         {
00085             std::swap(mContent, rhs.mContent);
00086             return *this;
00087         }
00088 
00089         template<typename ValueType>
00090         Any& operator=(const ValueType & rhs)
00091         {
00092             Any(rhs).swap(*this);
00093             return *this;
00094         }
00095 
00096         Any & operator=(const Any & rhs)
00097         {
00098             Any(rhs).swap(*this);
00099             return *this;
00100         }
00101 
00102     public: // queries
00103 
00104         bool isEmpty() const
00105         {
00106             return !mContent;
00107         }
00108 
00109         const std::type_info& getType() const
00110         {
00111             return mContent ? mContent->getType() : typeid(void);
00112         }
00113 
00114         inline friend std::ostream& operator <<
00115             ( std::ostream& o, const Any& v )
00116         {
00117             if (v.mContent)
00118                 v.mContent->writeToStream(o);
00119             return o;
00120         }
00121 
00122         void destroy()
00123         {
00124             OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL);
00125             mContent = NULL;
00126         }
00127 
00128     protected: // types
00129 
00130         class placeholder 
00131         {
00132         public: // structors
00133     
00134             virtual ~placeholder()
00135             {
00136             }
00137 
00138         public: // queries
00139 
00140             virtual const std::type_info& getType() const = 0;
00141 
00142             virtual placeholder * clone() const = 0;
00143     
00144             virtual void writeToStream(std::ostream& o) = 0;
00145 
00146         };
00147 
00148         template<typename ValueType>
00149         class holder : public placeholder
00150         {
00151         public: // structors
00152 
00153             holder(const ValueType & value)
00154               : held(value)
00155             {
00156             }
00157 
00158         public: // queries
00159 
00160             virtual const std::type_info & getType() const
00161             {
00162                 return typeid(ValueType);
00163             }
00164 
00165             virtual placeholder * clone() const
00166             {
00167                 return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held);
00168             }
00169 
00170             virtual void writeToStream(std::ostream& o)
00171             {
00172                 o << held;
00173             }
00174 
00175 
00176         public: // representation
00177 
00178             ValueType held;
00179 
00180         };
00181 
00182 
00183 
00184     protected: // representation
00185         placeholder * mContent;
00186 
00187         template<typename ValueType>
00188         friend ValueType * any_cast(Any *);
00189 
00190 
00191     public: 
00192 
00193         template<typename ValueType>
00194         ValueType operator()() const
00195         {
00196             if (!mContent) 
00197             {
00198                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
00199                     "Bad cast from uninitialised Any", 
00200                     "Any::operator()");
00201             }
00202             else if(getType() == typeid(ValueType))
00203             {
00204                 return static_cast<Any::holder<ValueType> *>(mContent)->held;
00205             }
00206             else
00207             {
00208                 StringUtil::StrStreamType str;
00209                 str << "Bad cast from type '" << getType().name() << "' "
00210                     << "to '" << typeid(ValueType).name() << "'";
00211                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
00212                      str.str(), 
00213                     "Any::operator()");
00214             }
00215         }
00216 
00217         template <typename ValueType>
00218         ValueType get(void) const
00219         {
00220             if (!mContent) 
00221             {
00222                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
00223                     "Bad cast from uninitialised Any", 
00224                     "Any::operator()");
00225             }
00226             else if(getType() == typeid(ValueType))
00227             {
00228                 return static_cast<Any::holder<ValueType> *>(mContent)->held;
00229             }
00230             else
00231             {
00232                 StringUtil::StrStreamType str;
00233                 str << "Bad cast from type '" << getType().name() << "' "
00234                     << "to '" << typeid(ValueType).name() << "'";
00235                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
00236                      str.str(), 
00237                     "Any::operator()");
00238             }
00239         }
00240 
00241     };
00242 
00243 
00247     class AnyNumeric : public Any
00248     {
00249     public:
00250         AnyNumeric()
00251         : Any()
00252         {
00253         }
00254 
00255         template<typename ValueType>
00256         AnyNumeric(const ValueType & value)
00257             
00258         {
00259             mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value);
00260         }
00261 
00262         AnyNumeric(const AnyNumeric & other)
00263             : Any()
00264         {
00265             mContent = other.mContent ? other.mContent->clone() : 0; 
00266         }
00267 
00268     protected:
00269         class numplaceholder : public Any::placeholder
00270         {
00271         public: // structors
00272 
00273             ~numplaceholder()
00274             {
00275             }
00276             virtual placeholder* add(placeholder* rhs) = 0;
00277             virtual placeholder* subtract(placeholder* rhs) = 0;
00278             virtual placeholder* multiply(placeholder* rhs) = 0;
00279             virtual placeholder* multiply(Real factor) = 0;
00280             virtual placeholder* divide(placeholder* rhs) = 0;
00281         };
00282 
00283         template<typename ValueType>
00284         class numholder : public numplaceholder
00285         {
00286         public: // structors
00287 
00288             numholder(const ValueType & value)
00289                 : held(value)
00290             {
00291             }
00292 
00293         public: // queries
00294 
00295             virtual const std::type_info & getType() const
00296             {
00297                 return typeid(ValueType);
00298             }
00299 
00300             virtual placeholder * clone() const
00301             {
00302                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held);
00303             }
00304 
00305             virtual placeholder* add(placeholder* rhs)
00306             {
00307                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held);
00308             }
00309             virtual placeholder* subtract(placeholder* rhs)
00310             {
00311                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held);
00312             }
00313             virtual placeholder* multiply(placeholder* rhs)
00314             {
00315                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held);
00316             }
00317             virtual placeholder* multiply(Real factor)
00318             {
00319                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor);
00320             }
00321             virtual placeholder* divide(placeholder* rhs)
00322             {
00323                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held);
00324             }
00325             virtual void writeToStream(std::ostream& o)
00326             {
00327                 o << held;
00328             }
00329 
00330         public: // representation
00331 
00332             ValueType held;
00333 
00334         };
00335 
00337         AnyNumeric(placeholder* pholder)
00338         {
00339             mContent = pholder;
00340         }
00341 
00342     public:
00343         AnyNumeric & operator=(const AnyNumeric & rhs)
00344         {
00345             AnyNumeric(rhs).swap(*this);
00346             return *this;
00347         }
00348         AnyNumeric operator+(const AnyNumeric& rhs) const
00349         {
00350             return AnyNumeric(
00351                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
00352         }
00353         AnyNumeric operator-(const AnyNumeric& rhs) const
00354         {
00355             return AnyNumeric(
00356                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
00357         }
00358         AnyNumeric operator*(const AnyNumeric& rhs) const
00359         {
00360             return AnyNumeric(
00361                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
00362         }
00363         AnyNumeric operator*(Real factor) const
00364         {
00365             return AnyNumeric(
00366                 static_cast<numplaceholder*>(mContent)->multiply(factor));
00367         }
00368         AnyNumeric operator/(const AnyNumeric& rhs) const
00369         {
00370             return AnyNumeric(
00371                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
00372         }
00373         AnyNumeric& operator+=(const AnyNumeric& rhs)
00374         {
00375             *this = AnyNumeric(
00376                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
00377             return *this;
00378         }
00379         AnyNumeric& operator-=(const AnyNumeric& rhs)
00380         {
00381             *this = AnyNumeric(
00382                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
00383             return *this;
00384         }
00385         AnyNumeric& operator*=(const AnyNumeric& rhs)
00386         {
00387             *this = AnyNumeric(
00388                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
00389             return *this;
00390         }
00391         AnyNumeric& operator/=(const AnyNumeric& rhs)
00392         {
00393             *this = AnyNumeric(
00394                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
00395             return *this;
00396         }
00397 
00398 
00399 
00400 
00401     };
00402 
00403 
00404     template<typename ValueType>
00405     ValueType * any_cast(Any * operand)
00406     {
00407         return operand && (std::strcmp(operand->getType().name(), typeid(ValueType).name()) == 0)
00408                     ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held
00409                     : 0;
00410     }
00411 
00412     template<typename ValueType>
00413     const ValueType * any_cast(const Any * operand)
00414     {
00415         return any_cast<ValueType>(const_cast<Any *>(operand));
00416     }
00417 
00418     template<typename ValueType>
00419     ValueType any_cast(const Any & operand)
00420     {
00421         const ValueType * result = any_cast<ValueType>(&operand);
00422         if(!result)
00423         {
00424             StringUtil::StrStreamType str;
00425             str << "Bad cast from type '" << operand.getType().name() << "' "
00426                 << "to '" << typeid(ValueType).name() << "'";
00427             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
00428                 str.str(), 
00429                 "Ogre::any_cast");
00430         }
00431         return *result;
00432     }
00437 }
00438 
00439 #endif
00440 

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:20