ROOT logo
// @(#)root/reflex:$Id: Object.h 36314 2010-10-12 12:40:57Z axel $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, 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_Object
#define Reflex_Object

// Include files
#include "Reflex/Type.h"
#include <string>
#include <vector>

namespace Reflex {
// forward declarations

/**
 * @class Object Object.h Reflex/Object.h
 * @author Stefan Roiser
 * @date 24/06/2004
 * @ingroup Ref
 */
class RFLX_API Object {
public:
   /** constructor */
   Object(const Type& type = Type(),
          void* mem = 0);


   /** constructor */
   Object(const Object &);


   /** destructor */
   ~Object() {}


   template <typename T>
   static Object
   Create(T& v) {
      return Object(Type::ByTypeInfo(typeid(T)), &v);
   }


   /**
    * operator assigment
    */
   Object operator =(const Object& obj);


   /**
    * operator ==
    */
   bool operator ==(const Object& obj);


   /**
    * inequal operator
    */
   bool operator !=(const Object& obj);


   /**
    * operator bool
    */
   operator bool() const;


   /**
    * Address will return the memory address of the object
    * @return memory address of object
    */
   void* Address() const;


   /**
    * CastObject an object from this class type to another one
    * @param  to is the class type to cast into
    * @param  obj the memory address of the object to be casted
    */
   Object CastObject(const Type& to) const;


   /**
    * Destruct will call the destructor of a type and remove its memory
    * allocation if desired
    */
   void Destruct() const;


   /**
    * DynamicType is used to discover the dynamic type (useful in
    * case of polymorphism)
    * @return the actual class of the object
    */
   Type DynamicType() const;


   /**
    * Get the data member value
    * @param dm name of the data member to get
    * @return member value as object
    */
   Object Get(const std::string& dm) const;


   /**
    * Invoke a member function of the object
    * @param fm name of the member function
    * @param ret Object to put the return value into (can be 0 for function returning void)
    * @param args a vector of memory addresses to parameter values
    * @return the return value of the function as object
    */
   void Invoke(const std::string& fm,
               Object* ret = 0,
               const std::vector<void*>& args = std::vector<void*>()) const;


   /**
    * Invoke a member function of the object
    * @param fm name of the member function
    * @param ret Object to put the return value into (can be 0 for function returning void)
    * @param args a vector of memory addresses to parameter values
    * @return the return value of the function as object
    */
   template <typename T>
   void
   Invoke(const std::string& fm,
          T& ret,
          const std::vector<void*>& args = std::vector<void*>()) const {
      Object retO(Type::ByTypeInfo(typeid(T)), &ret);
      Invoke(fm, &retO, args);
   }


   /**
    * Invoke a member function of the object
    * @param fm name of the member function
    * @param sign the signature of the member function (for overloads)
    * @param ret Object to put the return value into (can be 0 for function returning void)
    * @param args a vector of memory addresses to parameter values
    * @return the return value of the function as object
    */
   void Invoke(const std::string& fm,
               const Type& sign,
               Object* ret = 0,
               const std::vector<void*>& args = std::vector<void*>()) const;


   /**
    * Invoke a member function of the object
    * @param fm name of the member function
    * @param sign the signature of the member function (for overloads)
    * @param ret Object to put the return value into (can be 0 for function returning void)
    * @param args a vector of memory addresses to parameter values
    * @return the return value of the function as object
    */
   template <typename T>
   void
   Invoke(const std::string& fm,
          const Type& sign,
          T& ret,
          const std::vector<void*>& args = std::vector<void*>()) const {
      Object retO(Type::ByTypeInfo(typeid(T)), &ret);
      Invoke(fm, sign, &retO, args);
   }


   /**
    * Set will set a data member value of this object
    * @param dm the name of the data member
    * @param value the memory address of the value to set
    */
   void Set(const std::string& dm,
            const void* value) const;


   /**
    * Set will set a data member value of this object
    * @param dm the name of the data member
    * @param value the memory address of the value to set
    */
   template <class T>
   void Set(const std::string& dm,
            const T& value) const;


   /**
    * TypeOf will return the type of the object
    * @return type of the object
    */
   Type TypeOf() const;

private:
   friend class ValueObject;

   /** */
   void Set2(const std::string& dm,
             const void* value) const;

   /**
    * the type of the object
    * @link aggregation
    * @clientCardinality 1
    * @supplierCardinality 1
    * @label object type
    **/
   Type fType;


   /**
    * the address of the object
    */
   mutable
   void* fAddress;

};    // class Object


/**
 * Object_Cast can be used to cast an object into a given type
 * (no additional checks are performed for the time being)
 * @param o the object to be casted
 * @return the address of the object casted into type T
 */
template <class T> T Object_Cast(const Object& o);


} // namespace Reflex

#include "Reflex/Tools.h"

//-------------------------------------------------------------------------------
template <class T>
inline T
Reflex::Object_Cast(const Object& o) {
//-------------------------------------------------------------------------------
   return *(T*) o.Address();
}


//-------------------------------------------------------------------------------
inline Reflex::Object::Object(const Type& type,
                              void* mem)
//-------------------------------------------------------------------------------
   : fType(type),
   fAddress(mem) {
}


//-------------------------------------------------------------------------------
inline Reflex::Object::Object(const Object& obj)
//-------------------------------------------------------------------------------
   : fType(obj.fType),
   fAddress(obj.fAddress) {
}


//-------------------------------------------------------------------------------
inline Reflex::Object
Reflex::Object::operator =(const Object& obj) {
//-------------------------------------------------------------------------------
   fType = obj.fType;
   fAddress = obj.fAddress;
   return *this;
}


//-------------------------------------------------------------------------------
inline bool
Reflex::Object::operator ==(const Object& obj) {
//-------------------------------------------------------------------------------
   return fType == obj.fType && fAddress == obj.fAddress;
}


//-------------------------------------------------------------------------------
inline bool
Reflex::Object::operator !=(const Object& obj) {
//-------------------------------------------------------------------------------
   return fType != obj.fType || fAddress != obj.fAddress;
}


//-------------------------------------------------------------------------------
inline
Reflex::Object::operator bool() const {
//-------------------------------------------------------------------------------
   if (fType && fAddress) {
      return true;
   }
   return false;
}


//-------------------------------------------------------------------------------
inline void*
Reflex::Object::Address() const {
//-------------------------------------------------------------------------------
   return fAddress;
}


//-------------------------------------------------------------------------------
inline Reflex::Object
Reflex::Object::CastObject(const Type& to) const {
//-------------------------------------------------------------------------------
   if (*this) {
      return fType.CastObject(to, *this);
   }
   return Object();
}


//-------------------------------------------------------------------------------
inline void
Reflex::Object::Destruct() const {
//-------------------------------------------------------------------------------
   if (*this) {
      fType.Destruct(fAddress);
      fAddress = 0;
   }
}


//-------------------------------------------------------------------------------
inline Reflex::Type
Reflex::Object::DynamicType() const {
//-------------------------------------------------------------------------------
   return fType.DynamicType(*this);
}


//-------------------------------------------------------------------------------
inline void
Reflex::Object::Set(const std::string& dm,
                    const void* value) const {
//-------------------------------------------------------------------------------
   Set2(dm, value);
}


//-------------------------------------------------------------------------------
template <class T>
inline void
Reflex::Object::Set(const std::string& dm,
                    const T& value) const {
//-------------------------------------------------------------------------------
   Set2(dm, &value);
}


//-------------------------------------------------------------------------------
inline Reflex::Type
Reflex::Object::TypeOf() const {
//-------------------------------------------------------------------------------
   return fType;
}


#endif // Reflex_Object
 Object.h:1
 Object.h:2
 Object.h:3
 Object.h:4
 Object.h:5
 Object.h:6
 Object.h:7
 Object.h:8
 Object.h:9
 Object.h:10
 Object.h:11
 Object.h:12
 Object.h:13
 Object.h:14
 Object.h:15
 Object.h:16
 Object.h:17
 Object.h:18
 Object.h:19
 Object.h:20
 Object.h:21
 Object.h:22
 Object.h:23
 Object.h:24
 Object.h:25
 Object.h:26
 Object.h:27
 Object.h:28
 Object.h:29
 Object.h:30
 Object.h:31
 Object.h:32
 Object.h:33
 Object.h:34
 Object.h:35
 Object.h:36
 Object.h:37
 Object.h:38
 Object.h:39
 Object.h:40
 Object.h:41
 Object.h:42
 Object.h:43
 Object.h:44
 Object.h:45
 Object.h:46
 Object.h:47
 Object.h:48
 Object.h:49
 Object.h:50
 Object.h:51
 Object.h:52
 Object.h:53
 Object.h:54
 Object.h:55
 Object.h:56
 Object.h:57
 Object.h:58
 Object.h:59
 Object.h:60
 Object.h:61
 Object.h:62
 Object.h:63
 Object.h:64
 Object.h:65
 Object.h:66
 Object.h:67
 Object.h:68
 Object.h:69
 Object.h:70
 Object.h:71
 Object.h:72
 Object.h:73
 Object.h:74
 Object.h:75
 Object.h:76
 Object.h:77
 Object.h:78
 Object.h:79
 Object.h:80
 Object.h:81
 Object.h:82
 Object.h:83
 Object.h:84
 Object.h:85
 Object.h:86
 Object.h:87
 Object.h:88
 Object.h:89
 Object.h:90
 Object.h:91
 Object.h:92
 Object.h:93
 Object.h:94
 Object.h:95
 Object.h:96
 Object.h:97
 Object.h:98
 Object.h:99
 Object.h:100
 Object.h:101
 Object.h:102
 Object.h:103
 Object.h:104
 Object.h:105
 Object.h:106
 Object.h:107
 Object.h:108
 Object.h:109
 Object.h:110
 Object.h:111
 Object.h:112
 Object.h:113
 Object.h:114
 Object.h:115
 Object.h:116
 Object.h:117
 Object.h:118
 Object.h:119
 Object.h:120
 Object.h:121
 Object.h:122
 Object.h:123
 Object.h:124
 Object.h:125
 Object.h:126
 Object.h:127
 Object.h:128
 Object.h:129
 Object.h:130
 Object.h:131
 Object.h:132
 Object.h:133
 Object.h:134
 Object.h:135
 Object.h:136
 Object.h:137
 Object.h:138
 Object.h:139
 Object.h:140
 Object.h:141
 Object.h:142
 Object.h:143
 Object.h:144
 Object.h:145
 Object.h:146
 Object.h:147
 Object.h:148
 Object.h:149
 Object.h:150
 Object.h:151
 Object.h:152
 Object.h:153
 Object.h:154
 Object.h:155
 Object.h:156
 Object.h:157
 Object.h:158
 Object.h:159
 Object.h:160
 Object.h:161
 Object.h:162
 Object.h:163
 Object.h:164
 Object.h:165
 Object.h:166
 Object.h:167
 Object.h:168
 Object.h:169
 Object.h:170
 Object.h:171
 Object.h:172
 Object.h:173
 Object.h:174
 Object.h:175
 Object.h:176
 Object.h:177
 Object.h:178
 Object.h:179
 Object.h:180
 Object.h:181
 Object.h:182
 Object.h:183
 Object.h:184
 Object.h:185
 Object.h:186
 Object.h:187
 Object.h:188
 Object.h:189
 Object.h:190
 Object.h:191
 Object.h:192
 Object.h:193
 Object.h:194
 Object.h:195
 Object.h:196
 Object.h:197
 Object.h:198
 Object.h:199
 Object.h:200
 Object.h:201
 Object.h:202
 Object.h:203
 Object.h:204
 Object.h:205
 Object.h:206
 Object.h:207
 Object.h:208
 Object.h:209
 Object.h:210
 Object.h:211
 Object.h:212
 Object.h:213
 Object.h:214
 Object.h:215
 Object.h:216
 Object.h:217
 Object.h:218
 Object.h:219
 Object.h:220
 Object.h:221
 Object.h:222
 Object.h:223
 Object.h:224
 Object.h:225
 Object.h:226
 Object.h:227
 Object.h:228
 Object.h:229
 Object.h:230
 Object.h:231
 Object.h:232
 Object.h:233
 Object.h:234
 Object.h:235
 Object.h:236
 Object.h:237
 Object.h:238
 Object.h:239
 Object.h:240
 Object.h:241
 Object.h:242
 Object.h:243
 Object.h:244
 Object.h:245
 Object.h:246
 Object.h:247
 Object.h:248
 Object.h:249
 Object.h:250
 Object.h:251
 Object.h:252
 Object.h:253
 Object.h:254
 Object.h:255
 Object.h:256
 Object.h:257
 Object.h:258
 Object.h:259
 Object.h:260
 Object.h:261
 Object.h:262
 Object.h:263
 Object.h:264
 Object.h:265
 Object.h:266
 Object.h:267
 Object.h:268
 Object.h:269
 Object.h:270
 Object.h:271
 Object.h:272
 Object.h:273
 Object.h:274
 Object.h:275
 Object.h:276
 Object.h:277
 Object.h:278
 Object.h:279
 Object.h:280
 Object.h:281
 Object.h:282
 Object.h:283
 Object.h:284
 Object.h:285
 Object.h:286
 Object.h:287
 Object.h:288
 Object.h:289
 Object.h:290
 Object.h:291
 Object.h:292
 Object.h:293
 Object.h:294
 Object.h:295
 Object.h:296
 Object.h:297
 Object.h:298
 Object.h:299
 Object.h:300
 Object.h:301
 Object.h:302
 Object.h:303
 Object.h:304
 Object.h:305
 Object.h:306
 Object.h:307
 Object.h:308
 Object.h:309
 Object.h:310
 Object.h:311
 Object.h:312
 Object.h:313
 Object.h:314
 Object.h:315
 Object.h:316
 Object.h:317
 Object.h:318
 Object.h:319
 Object.h:320
 Object.h:321
 Object.h:322
 Object.h:323
 Object.h:324
 Object.h:325
 Object.h:326
 Object.h:327
 Object.h:328
 Object.h:329
 Object.h:330
 Object.h:331
 Object.h:332
 Object.h:333
 Object.h:334
 Object.h:335
 Object.h:336
 Object.h:337
 Object.h:338
 Object.h:339
 Object.h:340
 Object.h:341
 Object.h:342
 Object.h:343
 Object.h:344
 Object.h:345
 Object.h:346
 Object.h:347
 Object.h:348
 Object.h:349
 Object.h:350
 Object.h:351
 Object.h:352
 Object.h:353
 Object.h:354
 Object.h:355
 Object.h:356
 Object.h:357
 Object.h:358
 Object.h:359
 Object.h:360
 Object.h:361
 Object.h:362
 Object.h:363
 Object.h:364
 Object.h:365
 Object.h:366
 Object.h:367