Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreAny.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 9.2 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) Any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16Any WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29// -- Based on boost::any, original copyright information follows --
30// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
31//
32// Distributed under the Boost Software License, Version 1.0. (See
33// accompAnying file LICENSE_1_0.txt or copy at
34// http://www.boost.org/LICENSE_1_0.txt)
35// -- End original copyright --
36
37#ifndef __OGRE_ANY_H__
38#define __OGRE_ANY_H__
39
40#include "OgrePrerequisites.h"
41#include "OgreException.h"
42#include "OgreString.h"
43#include <algorithm>
44#include <typeinfo>
45
46
47namespace Ogre
48{
49        /** Variant type that can hold Any other type.
50        */
51    class Any
52    {
53    public: // constructors
54
55        Any()
56          : mContent(0)
57        {
58        }
59
60        template<typename ValueType>
61        explicit Any(const ValueType & value)
62          : mContent(new holder<ValueType>(value))
63        {
64        }
65
66        Any(const Any & other)
67          : mContent(other.mContent ? other.mContent->clone() : 0)
68        {
69        }
70
71        virtual ~Any()
72        {
73            delete mContent;
74        }
75
76    public: // modifiers
77
78        Any& swap(Any & rhs)
79        {
80            std::swap(mContent, rhs.mContent);
81            return *this;
82        }
83
84        template<typename ValueType>
85        Any& operator=(const ValueType & rhs)
86        {
87            Any(rhs).swap(*this);
88            return *this;
89        }
90
91        Any & operator=(const Any & rhs)
92        {
93            Any(rhs).swap(*this);
94            return *this;
95        }
96
97    public: // queries
98
99        bool isEmpty() const
100        {
101            return !mContent;
102        }
103
104        const std::type_info& getType() const
105        {
106            return mContent ? mContent->getType() : typeid(void);
107        }
108
109                inline friend std::ostream& operator <<
110                        ( std::ostream& o, const Any& v )
111                {
112                        if (v.mContent)
113                                v.mContent->writeToStream(o);
114                        return o;
115                }
116
117
118    protected: // types
119
120        class placeholder
121        {
122        public: // structors
123   
124            virtual ~placeholder()
125            {
126            }
127
128        public: // queries
129
130            virtual const std::type_info& getType() const = 0;
131
132            virtual placeholder * clone() const = 0;
133   
134                        virtual void writeToStream(std::ostream& o) = 0;
135
136        };
137
138        template<typename ValueType>
139        class holder : public placeholder
140        {
141        public: // structors
142
143            holder(const ValueType & value)
144              : held(value)
145            {
146            }
147
148        public: // queries
149
150            virtual const std::type_info & getType() const
151            {
152                return typeid(ValueType);
153            }
154
155            virtual placeholder * clone() const
156            {
157                return new holder(held);
158            }
159
160                        virtual void writeToStream(std::ostream& o)
161                        {
162                                o << held;
163                        }
164
165
166        public: // representation
167
168            ValueType held;
169
170        };
171
172
173
174    protected: // representation
175        placeholder * mContent;
176
177        template<typename ValueType>
178        friend ValueType * any_cast(Any *);
179
180
181    public: 
182
183            template<typename ValueType>
184        ValueType operator()() const
185        {
186                        if (!mContent) 
187                        {
188                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
189                                        "Bad cast from uninitialised Any", 
190                                        "Any::operator()");
191                        }
192                        else if(getType() == typeid(ValueType))
193                        {
194                return static_cast<Any::holder<ValueType> *>(mContent)->held;
195                        }
196                        else
197                        {
198                                StringUtil::StrStreamType str;
199                                str << "Bad cast from type '" << getType().name() << "' "
200                                        << "to '" << typeid(ValueType).name() << "'";
201                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
202                                         str.str(), 
203                                        "Any::operator()");
204                        }
205                }
206
207               
208
209    };
210
211
212        /** Specialised Any class which has built in arithmetic operators, but can
213                hold only types which support operator +,-,* and / .
214        */
215        class AnyNumeric : public Any
216        {
217        public:
218                AnyNumeric()
219                : Any()
220                {
221                }
222
223                template<typename ValueType>
224                AnyNumeric(const ValueType & value)
225                       
226                {
227                        mContent = new numholder<ValueType>(value);
228                }
229
230                AnyNumeric(const AnyNumeric & other)
231            : Any()
232                {
233                        mContent = other.mContent ? other.mContent->clone() : 0; 
234                }
235        protected:
236                class numplaceholder : public Any::placeholder
237                {
238                public: // structors
239
240                        ~numplaceholder()
241                        {
242                        }
243                        virtual placeholder* add(placeholder* rhs) = 0;
244                        virtual placeholder* subtract(placeholder* rhs) = 0;
245                        virtual placeholder* multiply(placeholder* rhs) = 0;
246                        virtual placeholder* multiply(Real factor) = 0;
247                        virtual placeholder* divide(placeholder* rhs) = 0;
248                };
249
250                template<typename ValueType>
251                class numholder : public numplaceholder
252                {
253                public: // structors
254
255                        numholder(const ValueType & value)
256                                : held(value)
257                        {
258                        }
259
260                public: // queries
261
262                        virtual const std::type_info & getType() const
263                        {
264                                return typeid(ValueType);
265                        }
266
267                        virtual placeholder * clone() const
268                        {
269                                return new numholder(held);
270                        }
271
272                        virtual placeholder* add(placeholder* rhs)
273                        {
274                                return new numholder(held + static_cast<numholder*>(rhs)->held);
275                        }
276                        virtual placeholder* subtract(placeholder* rhs)
277                        {
278                                return new numholder(held - static_cast<numholder*>(rhs)->held);
279                        }
280                        virtual placeholder* multiply(placeholder* rhs)
281                        {
282                                return new numholder(held * static_cast<numholder*>(rhs)->held);
283                        }
284                        virtual placeholder* multiply(Real factor)
285                        {
286                                return new numholder(held * factor);
287                        }
288                        virtual placeholder* divide(placeholder* rhs)
289                        {
290                                return new numholder(held / static_cast<numholder*>(rhs)->held);
291                        }
292                        virtual void writeToStream(std::ostream& o)
293                        {
294                                o << held;
295                        }
296
297                public: // representation
298
299                        ValueType held;
300
301                };
302
303                /// Construct from holder
304                AnyNumeric(placeholder* pholder)
305                {
306                        mContent = pholder;
307                }
308
309        public:
310                AnyNumeric & operator=(const AnyNumeric & rhs)
311                {
312                        AnyNumeric(rhs).swap(*this);
313                        return *this;
314                }
315                AnyNumeric operator+(const AnyNumeric& rhs) const
316                {
317                        return AnyNumeric(
318                                static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
319                }
320                AnyNumeric operator-(const AnyNumeric& rhs) const
321                {
322                        return AnyNumeric(
323                                static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
324                }
325                AnyNumeric operator*(const AnyNumeric& rhs) const
326                {
327                        return AnyNumeric(
328                                static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
329                }
330                AnyNumeric operator*(Real factor) const
331                {
332                        return AnyNumeric(
333                                static_cast<numplaceholder*>(mContent)->multiply(factor));
334                }
335                AnyNumeric operator/(const AnyNumeric& rhs) const
336                {
337                        return AnyNumeric(
338                                static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
339                }
340                AnyNumeric& operator+=(const AnyNumeric& rhs)
341                {
342                        *this = AnyNumeric(
343                                static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
344                        return *this;
345                }
346                AnyNumeric& operator-=(const AnyNumeric& rhs)
347                {
348                        *this = AnyNumeric(
349                                static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
350                        return *this;
351                }
352                AnyNumeric& operator*=(const AnyNumeric& rhs)
353                {
354                        *this = AnyNumeric(
355                                static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
356                        return *this;
357                }
358                AnyNumeric& operator/=(const AnyNumeric& rhs)
359                {
360                        *this = AnyNumeric(
361                                static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
362                        return *this;
363                }
364
365
366
367
368        };
369
370
371    template<typename ValueType>
372    ValueType * any_cast(Any * operand)
373    {
374        return operand && operand->getType() == typeid(ValueType)
375                    ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held
376                    : 0;
377    }
378
379    template<typename ValueType>
380    const ValueType * any_cast(const Any * operand)
381    {
382        return any_cast<ValueType>(const_cast<Any *>(operand));
383    }
384
385    template<typename ValueType>
386    ValueType any_cast(const Any & operand)
387    {
388        const ValueType * result = any_cast<ValueType>(&operand);
389        if(!result)
390                {
391                        StringUtil::StrStreamType str;
392                        str << "Bad cast from type '" << operand.getType().name() << "' "
393                                << "to '" << typeid(ValueType).name() << "'";
394                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
395                                str.str(), 
396                                "Ogre::any_cast");
397                }
398        return *result;
399    }
400
401
402}
403
404#endif
405
Note: See TracBrowser for help on using the repository browser.