// @(#)root/reflex:$Id: Object.h 26204 2008-11-14 15:38:38Z 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/Member.h"
#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

Last change: Fri Nov 14 16:51:42 2008
Last generated: 2008-11-14 16:51

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.