// @(#)root/reflex:$Id$ // 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) { //------------------------------------------------------------------------------- if (&obj != this) { 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