Any.h

Go to the documentation of this file.
00001 // @(#)root/reflex:$Id: Any.h 29288 2009-07-01 13:03:35Z axel $
00002 // Author: Stefan Roiser 2004
00003 
00004 // See http://www.boost.org/libs/any for Documentation.
00005 
00006 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00007 //
00008 // Permission to use, copy, modify, and distribute this software for any
00009 // purpose is hereby granted without fee, provided that this copyright and
00010 // permissions notice appear in all copies and derivatives.
00011 //
00012 // This software is provided "as is" without express or implied warranty.
00013 
00014 #ifndef Reflex_Any
00015 #define Reflex_Any
00016 
00017 // What:  variant At boost::any
00018 // who:   contributed by Kevlin Henney,
00019 //        with features contributed and bugs found by
00020 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
00021 // when:  July 2001
00022 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
00023 
00024 #include "Reflex/Kernel.h"
00025 #include <algorithm>
00026 #include <typeinfo>
00027 #include <iostream>
00028 
00029 namespace Reflex {
00030 /**
00031  * @class Any Any.h Reflex/Any.h
00032  * @author K. Henney
00033  */
00034 class RFLX_API Any {
00035    friend RFLX_API std::ostream& operator <<(std::ostream&,
00036                                              const Any&);
00037 
00038 public:
00039    /** Constructor */
00040    Any():
00041       fContent(0) {}
00042 
00043    /** Constructor */
00044    template <typename ValueType> Any(const ValueType &value):
00045       fContent(new Holder<ValueType>(value)) {}
00046 
00047    /** Copy Constructor */
00048    Any(const Any &other):
00049       fContent(other.fContent ? other.fContent->Clone() : 0) {}
00050 
00051    /** Dtor */
00052    ~Any() {
00053       delete fContent;
00054    }
00055 
00056    /** Clear the content */
00057    void
00058    Clear() {
00059       if (!Empty()) {
00060          delete fContent;
00061          fContent = 0;
00062       }
00063    }
00064 
00065 
00066    /** bool operator */
00067    operator bool() {
00068       return !Empty();
00069    }
00070 
00071    /** Modifier */
00072    Any&
00073    Swap(Any& rhs) {
00074       std::swap(fContent, rhs.fContent);
00075       return *this;
00076    }
00077 
00078 
00079    /** Modifier */
00080    template <typename ValueType> Any&
00081    operator =(const ValueType& rhs) {
00082       Any(rhs).Swap(*this);
00083       return *this;
00084    }
00085 
00086 
00087    /** Modifier */
00088    Any&
00089    operator =(const Any& rhs) {
00090       Any(rhs).Swap(*this);
00091       return *this;
00092    }
00093 
00094 
00095    /** Query */
00096    bool
00097    Empty() const {
00098       return !fContent;
00099    }
00100 
00101 
00102    /** Query */
00103    const std::type_info&
00104    TypeInfo() const {
00105       return fContent ? fContent->TypeInfo() : typeid(void);
00106    }
00107 
00108 
00109    /** Adress */
00110    void*
00111    Address() const {
00112       return fContent ? fContent->Address() : 0;
00113    }
00114 
00115 
00116 private:
00117    // or public: ?
00118    /**
00119     * @class Placeholder BoostAny.h Reflex/BoostAny.h
00120     * @author K. Henney
00121     */
00122    class Placeholder {
00123    public:
00124       /** Constructor */
00125       Placeholder() {}
00126 
00127       /** Destructor */
00128       virtual ~Placeholder() {}
00129 
00130       /** Query */
00131       virtual const std::type_info& TypeInfo() const = 0;
00132 
00133       /** Query */
00134       virtual Placeholder* Clone() const = 0;
00135 
00136       /** Query */
00137       virtual void* Address() const = 0;
00138 
00139    };
00140 
00141    /**
00142     * @class Holder BoostAny.h Reflex/BoostAny.h
00143     * @author K. Henney
00144     */
00145    template <typename ValueType> class Holder: public Placeholder {
00146    public:
00147       /** Constructor */
00148       Holder(const ValueType& value):
00149          fHeld(value) {}
00150 
00151       /** Query */
00152       virtual const std::type_info&
00153       TypeInfo() const {
00154          return typeid(ValueType);
00155       }
00156 
00157 
00158       /** Clone */
00159       virtual Placeholder*
00160       Clone() const {
00161          return new Holder(fHeld);
00162       }
00163 
00164 
00165       /** Address */
00166       virtual void*
00167       Address() const {
00168          return (void*) (&fHeld);
00169       }
00170 
00171 
00172       /** representation */
00173       ValueType fHeld;
00174 
00175    };
00176 
00177 
00178    /** representation */
00179    template <typename ValueType> friend ValueType* any_cast(Any*);
00180 
00181    // or  public:
00182 
00183    /** representation */
00184    Placeholder* fContent;
00185 
00186 };
00187 
00188 
00189 /**
00190  * @class BadAnyCast Any.h Reflex/Any.h
00191  * @author K. Henney
00192  */
00193 class BadAnyCast: public std::bad_cast {
00194 public:
00195    /** Constructor */
00196    BadAnyCast() {}
00197 
00198    /** Query */
00199    virtual const char*
00200    what() const throw() {
00201       return "BadAnyCast: failed conversion using any_cast";
00202    }
00203 
00204 
00205 };
00206 
00207 /** throw */
00208 template <class E> void
00209 throw_exception(const E& e) {
00210    throw e;
00211 }
00212 
00213 
00214 /** value */
00215 template <typename ValueType> ValueType*
00216 any_cast(Any* operand) {
00217    return operand && operand->TypeInfo() == typeid(ValueType)
00218           ? &static_cast<Any::Holder<ValueType>*>(operand->fContent)->fHeld : 0;
00219 }
00220 
00221 
00222 /** value */
00223 template <typename ValueType> const ValueType*
00224 any_cast(const Any* operand) {
00225    return any_cast<ValueType>(const_cast<Any*>(operand));
00226 }
00227 
00228 
00229 /** value */
00230 template <typename ValueType> ValueType
00231 any_cast(const Any& operand) {
00232    const ValueType* result = any_cast<ValueType>(&operand);
00233 
00234    if (!result) {
00235       throw_exception(BadAnyCast());
00236    }
00237    return *result;
00238 }
00239 
00240 
00241 /** stream operator */
00242 RFLX_API std::ostream& operator <<(std::ostream&,
00243                                    const Any&);
00244 
00245 } // namespace Reflex
00246 
00247 #endif // Reflex_Any

Generated on Tue Jul 5 14:25:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1