ROOT logo
// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2004

// See http://www.boost.org/libs/any for Documentation.

// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef Reflex_Any
#define Reflex_Any

// What:  variant At boost::any
// who:   contributed by Kevlin Henney,
//        with features contributed and bugs found by
//        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
// when:  July 2001
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95

#include "Reflex/Kernel.h"
#include <algorithm>
#include <typeinfo>
#include <iostream>

namespace Reflex {
/**
 * @class Any Any.h Reflex/Any.h
 * @author K. Henney
 */
class RFLX_API Any {
   friend RFLX_API std::ostream& operator <<(std::ostream&,
                                             const Any&);

public:
   /** Constructor */
   Any():
      fContent(0) {}

   /** Constructor */
   template <typename ValueType> Any(const ValueType &value):
      fContent(new Holder<ValueType>(value)) {}

   /** Copy Constructor */
   Any(const Any &other):
      fContent(other.fContent ? other.fContent->Clone() : 0) {}

   /** Dtor */
   ~Any() {
      delete fContent;
   }

   /** Clear the content */
   void
   Clear() {
      if (!Empty()) {
         delete fContent;
         fContent = 0;
      }
   }


   /** bool operator */
   operator bool() {
      return !Empty();
   }

   /** Modifier */
   Any&
   Swap(Any& rhs) {
      std::swap(fContent, rhs.fContent);
      return *this;
   }


   /** Modifier */
   template <typename ValueType> Any&
   operator =(const ValueType& rhs) {
      Any(rhs).Swap(*this);
      return *this;
   }


   /** Modifier */
   Any&
   operator =(const Any& rhs) {
      Any(rhs).Swap(*this);
      return *this;
   }


   /** Query */
   bool
   Empty() const {
      return !fContent;
   }


   /** Query */
   const std::type_info&
   TypeInfo() const {
      return fContent ? fContent->TypeInfo() : typeid(void);
   }


   /** Adress */
   void*
   Address() const {
      return fContent ? fContent->Address() : 0;
   }


private:
   // or public: ?
   /**
    * @class Placeholder BoostAny.h Reflex/BoostAny.h
    * @author K. Henney
    */
   class Placeholder {
   public:
      /** Constructor */
      Placeholder() {}

      /** Destructor */
      virtual ~Placeholder() {}

      /** Query */
      virtual const std::type_info& TypeInfo() const = 0;

      /** Query */
      virtual Placeholder* Clone() const = 0;

      /** Query */
      virtual void* Address() const = 0;

   };

   /**
    * @class Holder BoostAny.h Reflex/BoostAny.h
    * @author K. Henney
    */
   template <typename ValueType> class Holder: public Placeholder {
   public:
      /** Constructor */
      Holder(const ValueType& value):
         fHeld(value) {}

      /** Query */
      virtual const std::type_info&
      TypeInfo() const {
         return typeid(ValueType);
      }


      /** Clone */
      virtual Placeholder*
      Clone() const {
         return new Holder(fHeld);
      }


      /** Address */
      virtual void*
      Address() const {
         return (void*) (&fHeld);
      }


      /** representation */
      ValueType fHeld;

   };


   /** representation */
   template <typename ValueType> friend ValueType* any_cast(Any*);

   // or  public:

   /** representation */
   Placeholder* fContent;

};


/**
 * @class BadAnyCast Any.h Reflex/Any.h
 * @author K. Henney
 */
class BadAnyCast: public std::bad_cast {
public:
   /** Constructor */
   BadAnyCast() {}

   /** Query */
   virtual const char*
   what() const throw() {
      return "BadAnyCast: failed conversion using any_cast";
   }


};

/** throw */
template <class E> void
throw_exception(const E& e) {
   throw e;
}


/** value */
template <typename ValueType> ValueType*
any_cast(Any* operand) {
   return operand && operand->TypeInfo() == typeid(ValueType)
          ? &static_cast<Any::Holder<ValueType>*>(operand->fContent)->fHeld : 0;
}


/** value */
template <typename ValueType> const ValueType*
any_cast(const Any* operand) {
   return any_cast<ValueType>(const_cast<Any*>(operand));
}


/** value */
template <typename ValueType> ValueType
any_cast(const Any& operand) {
   const ValueType* result = any_cast<ValueType>(&operand);

   if (!result) {
      throw_exception(BadAnyCast());
   }
   return *result;
}


/** stream operator */
RFLX_API std::ostream& operator <<(std::ostream&,
                                   const Any&);

} // namespace Reflex

#endif // Reflex_Any
 Any.h:1
 Any.h:2
 Any.h:3
 Any.h:4
 Any.h:5
 Any.h:6
 Any.h:7
 Any.h:8
 Any.h:9
 Any.h:10
 Any.h:11
 Any.h:12
 Any.h:13
 Any.h:14
 Any.h:15
 Any.h:16
 Any.h:17
 Any.h:18
 Any.h:19
 Any.h:20
 Any.h:21
 Any.h:22
 Any.h:23
 Any.h:24
 Any.h:25
 Any.h:26
 Any.h:27
 Any.h:28
 Any.h:29
 Any.h:30
 Any.h:31
 Any.h:32
 Any.h:33
 Any.h:34
 Any.h:35
 Any.h:36
 Any.h:37
 Any.h:38
 Any.h:39
 Any.h:40
 Any.h:41
 Any.h:42
 Any.h:43
 Any.h:44
 Any.h:45
 Any.h:46
 Any.h:47
 Any.h:48
 Any.h:49
 Any.h:50
 Any.h:51
 Any.h:52
 Any.h:53
 Any.h:54
 Any.h:55
 Any.h:56
 Any.h:57
 Any.h:58
 Any.h:59
 Any.h:60
 Any.h:61
 Any.h:62
 Any.h:63
 Any.h:64
 Any.h:65
 Any.h:66
 Any.h:67
 Any.h:68
 Any.h:69
 Any.h:70
 Any.h:71
 Any.h:72
 Any.h:73
 Any.h:74
 Any.h:75
 Any.h:76
 Any.h:77
 Any.h:78
 Any.h:79
 Any.h:80
 Any.h:81
 Any.h:82
 Any.h:83
 Any.h:84
 Any.h:85
 Any.h:86
 Any.h:87
 Any.h:88
 Any.h:89
 Any.h:90
 Any.h:91
 Any.h:92
 Any.h:93
 Any.h:94
 Any.h:95
 Any.h:96
 Any.h:97
 Any.h:98
 Any.h:99
 Any.h:100
 Any.h:101
 Any.h:102
 Any.h:103
 Any.h:104
 Any.h:105
 Any.h:106
 Any.h:107
 Any.h:108
 Any.h:109
 Any.h:110
 Any.h:111
 Any.h:112
 Any.h:113
 Any.h:114
 Any.h:115
 Any.h:116
 Any.h:117
 Any.h:118
 Any.h:119
 Any.h:120
 Any.h:121
 Any.h:122
 Any.h:123
 Any.h:124
 Any.h:125
 Any.h:126
 Any.h:127
 Any.h:128
 Any.h:129
 Any.h:130
 Any.h:131
 Any.h:132
 Any.h:133
 Any.h:134
 Any.h:135
 Any.h:136
 Any.h:137
 Any.h:138
 Any.h:139
 Any.h:140
 Any.h:141
 Any.h:142
 Any.h:143
 Any.h:144
 Any.h:145
 Any.h:146
 Any.h:147
 Any.h:148
 Any.h:149
 Any.h:150
 Any.h:151
 Any.h:152
 Any.h:153
 Any.h:154
 Any.h:155
 Any.h:156
 Any.h:157
 Any.h:158
 Any.h:159
 Any.h:160
 Any.h:161
 Any.h:162
 Any.h:163
 Any.h:164
 Any.h:165
 Any.h:166
 Any.h:167
 Any.h:168
 Any.h:169
 Any.h:170
 Any.h:171
 Any.h:172
 Any.h:173
 Any.h:174
 Any.h:175
 Any.h:176
 Any.h:177
 Any.h:178
 Any.h:179
 Any.h:180
 Any.h:181
 Any.h:182
 Any.h:183
 Any.h:184
 Any.h:185
 Any.h:186
 Any.h:187
 Any.h:188
 Any.h:189
 Any.h:190
 Any.h:191
 Any.h:192
 Any.h:193
 Any.h:194
 Any.h:195
 Any.h:196
 Any.h:197
 Any.h:198
 Any.h:199
 Any.h:200
 Any.h:201
 Any.h:202
 Any.h:203
 Any.h:204
 Any.h:205
 Any.h:206
 Any.h:207
 Any.h:208
 Any.h:209
 Any.h:210
 Any.h:211
 Any.h:212
 Any.h:213
 Any.h:214
 Any.h:215
 Any.h:216
 Any.h:217
 Any.h:218
 Any.h:219
 Any.h:220
 Any.h:221
 Any.h:222
 Any.h:223
 Any.h:224
 Any.h:225
 Any.h:226
 Any.h:227
 Any.h:228
 Any.h:229
 Any.h:230
 Any.h:231
 Any.h:232
 Any.h:233
 Any.h:234
 Any.h:235
 Any.h:236
 Any.h:237
 Any.h:238
 Any.h:239
 Any.h:240
 Any.h:241
 Any.h:242
 Any.h:243
 Any.h:244
 Any.h:245
 Any.h:246
 Any.h:247