//*-- Author : Valeriy Onuchin 11/09/2000 
//
//
////////////////////////////////////////////////////////////////////////////////
//
// rooClass corresponds to d_Class class
//
// A class descriptor provides information about a class in the schema, called
// its described class. The described class is actually a particular shape of a
// particular version of a particular class. Because rooClass inherits from 
// rooScope, a class descriptor can look up or iterate through properties 
// defined in the scope of the described class, obtaining descriptors for the 
// properties in the class's scope.
//______________________________________________________________________________
//       Obtaining a Class Descriptor.
//
//   You should never instantiate this class directly. Instead, you can obtain 
// a class descriptor either from the module descriptor for the top-level 
// module or from the module descriptor for the module in which the class is 
// defined:
//
//    Call the resolve_class member function of the module descriptor to look
//    up the class by name. Alternatively, you can call the module descriptor's
//    resolve_type or resolve member function and cast the result to a class
//    descriptor.
//
//    Call the defines_types_begin member function of the module descriptor to
//    get an iterator for all types in the module's scope. You can obtain type
//    descriptors from the iterator. Call the is_class member function of a 
//    type descriptor to see whether it describes a class; if so, you can 
//    safely cast it to a class descriptor.
//
//______________________________________________________________________________
//       Specifying a Version.
//
// By default, when you call the rooModule::resolve_class(), 
//  rooModule::resolve_type, or rooModule::resolve member function of a module
// descriptor, you get a class descriptor for the most recent version of the 
// specified class. However, an optional parameter to these member functions 
// allows you to specify the desired version number. When you use that 
// parameter, you obtain a class descriptor for the specified version of the
// specified class.
//
//______________________________________________________________________________
//       Specifying a Shape.
//
// When you call the resolve_class, resolve_type, or resolve member
// function of a module descriptor, you obtain a class descriptor for the most 
// recent shape of the specified class and version. If the class has evolved, 
// you can look up the previous shape by calling the class descriptor's 
// previous_shape member function. If you have a descriptor for an older shape,
// you can call its next_shape() member function to get the descriptor for the
// next shape.
//
////////////////////////////////////////////////////////////////////////////////
//
// d_Class is part of the ODMG standard.  It describes a stand-alone
// database type composed of attributes and relationships.  The ODMG
// class hierarchy implies that d_Relationship and d_Attribute are
// disjunct, but because of Objectivity's architecture, d_Attribute
// has been made an immediate base class of d_Relationship.
//
// Classes can be looked up via hash tables in a schema module by name or
// Objectivity type number.  The members of a class may be iterated, or a
// named member looked up in the class scope.  Relationships, base
// classes, and sub-classes (derived classes) of a class may be iterated.
//

#include "rooObjy.h"
#include <ooas.h>
#include <oo.h>

ClassImp(rooClass)

////////////////////////////////////////////////////////////////////////////////
//______________________________________________________________________________
 rooClass::rooClass()
{
   // default ctor., internal use only 

   fImp = 0;
}

//______________________________________________________________________________
 rooClass::~rooClass()
{
   // dtor.  internal use only 
   
   fImp = 0;
}

//______________________________________________________________________________
 rooInheritanceItr rooClass::sub_class_list_begin()
{
   // Gets an iterator for the inheritance connections between the described 
   // class and its child classes.
   //
   // Returns:
   //    An inheritance iterator that finds all inheritance connections in which 
   //    the described class is the parent (base class).
   //
   // The returned iterator gets an inheritance descriptor for each inheritance
   // connection from the described class to an immediate derived class. To get 
   // the derived class from one of these inheritance descriptors, call its 
   // inherits_to() member function.
   //
   // See also: base_class_list_begin(), sub_class_list_end() 

   rooInheritanceItr itr;
   if(!fImp) return itr;
   *((inheritance_iterator*)itr.getImp()) = ((d_Class*)fImp)->sub_class_list_begin();
   return itr;
}

//______________________________________________________________________________
 rooInheritanceItr rooClass::sub_class_list_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the inheritance connections between the described class and its 
   // child classes.
   //
   // Returns: 
   //    An inheritance iterator that is positioned after the last inheritance 
   //    connection between the described class and a subclass.
   //
   // You can compare the iterator returned by sub_class_list_begin with the one
   // returned by this member function to test whether iteration has finished. 

   rooInheritanceItr itr;
   if(!fImp) return itr;
   *((inheritance_iterator*)itr.getImp()) = ((d_Class*)fImp)->sub_class_list_end();
   return itr;
}

//______________________________________________________________________________
 rooInheritanceItr rooClass::base_class_list_begin()
{
   // Gets an iterator for the inheritance connections between the described 
   // class and its parent classes.
   //
   // Returns: 
   //    An inheritance iterator that finds all inheritance connections in which 
   //    the described class is the child (derived) class.
   //
   // The returned iterator gets an inheritance descriptor for each inheritance
   // connection from an immediate base class to the described class. To get 
   // the base class from one of these inheritance descriptors, call its 
   // derives_from() member function.
   //
   // See also: base_class_list_end()

   rooInheritanceItr itr;
   if(!fImp) return itr;
   *((inheritance_iterator*)itr.getImp()) = 
                                 (((d_Class*)fImp)->base_class_list_begin());

   return itr;
}

//______________________________________________________________________________
 rooInheritanceItr rooClass::base_class_list_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the inheritance connections between the described class and its 
   // parent classes.
   //
   // Returns: 
   //    An inheritance iterator that is positioned after the last inheritance
   //    connection between the described class and a base class.
   //
   // You can compare the iterator returned by base_class_list_begin with the 
   // one returned by this member function to test whether iteration has finished.

   rooInheritanceItr itr;
   if(!fImp) return itr;
   *((inheritance_iterator*)itr.getImp()) = 
                                    ((d_Class*)fImp)->base_class_list_end();
   return itr;
}

//______________________________________________________________________________
 rooAttributeItr rooClass::defines_attribute_begin()
{
   // Gets an iterator for the attributes defined in the described class.
   //
   // Returns: 
   //    An attribute iterator that finds all immediate base classes, attributes, 
   //    and relationships in the described class.
   //
   // The returned iterator finds the same descriptors as the iterator returned 
   // by defines_begin, but it gets them typed as attribute descriptors instead 
   // of generic descriptors.
   //
   // See also: attributes_plus_inherited_begin

   rooAttributeItr itr;
   if(!fImp) return itr;
   *((attribute_iterator*)itr.getImp()) = 
                                 ((d_Class*)fImp)->defines_attribute_begin();
   return itr;
}

//______________________________________________________________________________
 rooAttributeItr rooClass::defines_attribute_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the attributes defined in the described class.
   //
   // Returns: 
   //    An attribute iterator that is positioned after the last attribute 
   //    defined in the described class.
   //
   // You can compare the iterator returned by defines_attribute_begin with the
   // one returned by this member function to test whether iteration has
   // finished.

   rooAttributeItr itr;
   if(!fImp) return itr;
   *((attribute_iterator*)itr.getImp()) = 
                                    ((d_Class*)fImp)->defines_attribute_end();
   return itr;
}

//______________________________________________________________________________
 rooRelationshipItr rooClass::defines_relationship_begin()
{
   // Gets an iterator for the relationships defined in the described class.
   //
   // Returns: 
   //    A relationship iterator that finds all relationships defined in the 
   //    described class.
   //
   // See also: defines_relationship_end

   rooRelationshipItr itr;
   if(!fImp) return itr;
   *((relationship_iterator*)itr.getImp()) = 
                                 ((d_Class*)fImp)->defines_relationship_begin(); 
   return itr;
}

//______________________________________________________________________________
 rooRelationshipItr rooClass::defines_relationship_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the relationships defined in the described class.
   //
   // Returns: 
   //    A relationship iterator that is positioned after the last 
   //    relationship defined in the described class.
   //
   // You can compare the iterator returned by defines_relationship_begin with
   // the one returned by this member function to test whether iteration has 
   // finished.

   rooRelationshipItr itr;
   if(!fImp) return itr;
   *((relationship_iterator*)itr.getImp()) = 
                                 ((d_Class*)fImp)->defines_relationship_end();
   return itr;
}

//______________________________________________________________________________
const rooAttribute & rooClass::resolve_attribute(const TString& nameToMatch)
{
   // Looks up an attribute defined by the described class.
   //
   // Parameters: 
   //    nameToMatch - the name of the attribute to be looked up.
   //
   // Returns:
   //    The attribute descriptor for the described class's attribute with the 
   //    specified name, or the null descriptor if nameToMatchis not the name 
   //    of an immediate base class of the described class or the name of an 
   //    attribute or a relationship defined by the described class.

   if(!fImp) return 0;
   d_Attribute& attr = ((d_Class*)fImp)->resolve_attribute(nameToMatch.Data());
   if(!attr) return 0;

   if(!fAttribute) fAttribute = new rooAttribute((void*)&attr);
   else fAttribute->setImp((void*)&attr);
   return *fAttribute;
}

//______________________________________________________________________________
const rooRelationship & rooClass::resolve_relationship(const TString& nameToMatch)
{
   // Looks up a relationship defined by the described class.
   //
   // Parameters: 
   //    nameToMatch - the name of the relationship (association) to be looked up.
   //
   // Returns: 
   //    The relationship descriptor for the described class's relationship with 
   //    the specified name, or the null descriptor if the described class does
   //    not define a relationship named nameToMatch.

   if(!fImp) return 0;
   d_Relationship& rl = ((d_Class*)fImp)->resolve_relationship(nameToMatch.Data());
   if(!rl) return 0;

   if(!fRelationship) fRelationship = new rooRelationship((void*)&rl);
   else fRelationship->setImp((void*)&rl);
   return *fRelationship;
}

//______________________________________________________________________________
 Bool_t rooClass::persistent_capable() const
{
   // Tests whether the described class is persistence-capable.

   return fImp ? ((d_Class*)fImp)->persistent_capable() : 0;
}

//______________________________________________________________________________
 Bool_t rooClass::has_extent() const
{
   // Tests whether the described class has a nonzero physical size.
   //
   // Returns:
   //    kTRUE if the described class has a nonzero physical size; 
   //    otherwise, kFALSE. 

   return fImp ? ((d_Class*)fImp)->has_extent() : 0;
}

//______________________________________________________________________________
rooClass::operator size_t() const
{
   //

   return fImp ? (size_t)(*((d_Class*)fImp)) : 0;
}

//______________________________________________________________________________
 UInt_t rooClass::id() const
{
   // Gets the unique ID that identifies the described class.
   //
   // Returns:
   //    The ID for the described class.
   //
   // The ID for a class (or any type) is the same as its type number.

   return fImp ? ((d_Class*)fImp)->id() : 0;
}

//______________________________________________________________________________
 Int_t rooClass::type_number() const
{
   // Gets the unique type number for the described class and version.
   //
   // Returns: 
   //    The unique type number for the described class and version.
   //
   // See also: shape_number()
   
   return fImp ? ((d_Class*)fImp)->type_number() : 0;
}

//______________________________________________________________________________
const rooMetaObject & rooClass::resolve(const TString& str,Int_t ver)
{ 
   // Looks up a property defined by the described class.
   //
   // Parameters: 
   //    str - the name of the property to be looked up.
   //    ver - the desired version of the entity named str. 
   //          This parameter should be omitted because it is only relevant for 
   //          looking up classes, not properties.
   //
   // Returns:
   //    The descriptor for the described class's property with the specified 
   //    name, or the null descriptor if nis not the name of an immediate base 
   //    class of the described class or the name of an attribute or a relationship 
   //    defined by the described class.
   //
   // The returned generic descriptor can be cast to the appropriate descriptor 
   // class (rooAttribute or rooRelationship). Analternative to calling
   // this member function is to call more specific functions that look up
   // properties of a particular kind.
   //
   // See also. resolve_attribute()

   if(!fImp) return 0;
   d_Meta_Object& mo = ((d_Class*)fImp)->resolve(str.Data(),ver);
   if(!mo) return 0;   

   if(!fMetaObject) fMetaObject = new rooMetaObject((void*)&mo);
   fMetaObject->setImp((void*)&mo);
   return *fMetaObject;
}

//______________________________________________________________________________
 rooMetaObjectItr rooClass::defines_begin()
{
   // Gets an iterator for the properties defined in the described class.
   //
   // Returns: 
   //    A descriptor iterator that finds all immediate base classes, attributes, 
   //    and relationships defined in the described class.
   //
   // The returned iterator gets generic descriptors for each property defined 
   // in the described class. An alternative to calling this member function is 
   // to call more specific functions that find properties of some particular 
   // kind.
   //
   // See also: defines_end()

   rooMetaObjectItr itr;
   if(!fImp) return itr;
   *((meta_object_iterator*)itr.getImp()) = ((d_Class*)fImp)->defines_begin();
   return itr;
}

//______________________________________________________________________________
 rooMetaObjectItr rooClass::defines_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the properties defined in the described class.
   //
   // Returns: 
   //    A descriptor iterator that is positioned after the last property 
   //    defined in the described class.
   //
   // You can compare the iterator returned by defines_begin with the one 
   // returned by this member function to test whether iteration has finished.

   rooMetaObjectItr itr;
   if(!fImp) return itr;
   *((meta_object_iterator*)itr.getImp()) = ((d_Class*)fImp)->defines_end();
   return itr;
}

//______________________________________________________________________________
 rooAttributePlusInheritedItr rooClass::attributes_plus_inherited_begin()
{
    //  Base classes are treated similarly to embedded class attributes.
    // They occupy a single "position," rather than a position for every
    // inherited attribute.  Consider:
    //
    //    class base : public ooObj {
    //        int32 x; };
    //
    //    class der : public base {
    //        int32 y; };
    //
    // An iteration over "der" using defines_attribute_begin() will hit two
    // attributes, "base" and "y," rather than three, "ooObj," "x." and "y."
    //
    // To iterate with base classes flattened into inherited attributes,
    // use attributes_plus_inherited_begin().  When obtaining attribute
    // positions in that context, using rooClass::position_in_class() is more
    // intuitive than using rooAttribute::position().  A rooAttribute only
    // knows its position relative to its defining class; it can't guess what
    // position you care about if you're using its class somewhere in
    // an inheritance hierarchy.
    //
    // For example, iterating "der" with attributes_plus_inherited_begin()
    // will visit "ooObj," "x," and "y," but not that if you call
    // if you call rooAttribute::position() on either "x" or "y," 1 will
    // be returned--an apparent conflict.  That's because rooAttribute
    // doesn't know anything about its inheritance context.  Specify that
    // context by calling rooClass::position_in_class("y"), and the return
    // value will be unique in the derived class context. 
    //

   rooAttributePlusInheritedItr itr;
   if(!fImp) return itr;
   *((attribute_plus_inherited_iterator*)itr.getImp()) = 
            ((d_Class*)fImp)->attributes_plus_inherited_begin();
   return itr;
}

//______________________________________________________________________________
 rooAttributePlusInheritedItr rooClass::attributes_plus_inherited_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the attributes of the described class. 
   //
   // You can compare the iterator returned by attributes_plus_inherited_begin
   // with the one returned by this member function to test whether iteration 
   // has finished.

   rooAttributePlusInheritedItr itr;
   if(!fImp) return itr;
   *((attribute_plus_inherited_iterator*)itr.getImp()) = 
            ((d_Class*)fImp)->attributes_plus_inherited_end();
   return itr;
}

//______________________________________________________________________________
 rooBaseClassPlusInheritedItr rooClass::base_classes_plus_inherited_begin()
{
   // Gets an iterator for the ancestor classes of the described class.
   //
   // Returns:
   //       A base-class iterator that finds all ancestor classes of the 
   //       described class.

   rooBaseClassPlusInheritedItr itr;
   if(!fImp) return itr;
   *((base_class_plus_inherited_iterator*)itr.getImp()) = 
                     ((d_Class*)fImp)->base_classes_plus_inherited_begin(); 

   return itr;
}

//______________________________________________________________________________
 rooBaseClassPlusInheritedItr rooClass::base_classes_plus_inherited_end()
{
   // Gets an iterator representing the termination condition for iteration 
   // through the ancestor classes of the described class.
   //
   // Returns: 
   //       A base-class iterator that is positioned after the last ancestor 
   //       class of the described class.
   //
   // You can compare the iterator returned by base_classes_plus_inherited_begin 
   // with the one returned by this member function to test whether iteration has 
   // finished.

   rooBaseClassPlusInheritedItr itr;
   if(!fImp) return itr;
   *((base_class_plus_inherited_iterator*)itr.getImp()) = 
                     ((d_Class*)fImp)->base_classes_plus_inherited_end(); 

   return itr; 
}

//______________________________________________________________________________
const rooAttribute & rooClass::attribute_at_position(const rooClassPosition & rpos)
{
   // Gets the attribute at the specified position in the described class.
   //
   // Returns:
   //    An attribute descriptor for the attribute at the specified position.
   //
   // This variant can get a descriptor for any attribute defined in or 
   // inherited by the described class. 
   // This member function throws an AttributeOutOfRange exception if pos or 
   // an attribute position within rpos is not a valid position in the containing 
   // class. It throws an AttributeTypeError exception if rpos indicates a position 
   // within an attribute that is not an embedded base class.
   
   if(!fImp) return 0;
   Class_Position* pos = (Class_Position*)rpos.getImp();
   d_Attribute& attr = ((d_Class*)fImp)->attribute_at_position(*pos);
   if(!attr) return 0;

   if(!fAttribute) fAttribute = new rooAttribute();
   fAttribute->setImp((void*)&attr);
   return *fAttribute;
}

//______________________________________________________________________________
const rooAttribute & rooClass::attribute_at_position(Int_t pos)
{
   // Gets the attribute at the specified position in the described class.
   //
   // Returns:
   //    An attribute descriptor for the attribute at the specified position.
   //
   // This variant can get a descriptor for any attribute defined in the described 
   // class. This member function throws an AttributeOutOfRange exception if pos or 
   // an attribute position within pos is not a valid position in the containing 
   // class. It throws an AttributeTypeError exception if pos indicates a position 
   // within an attribute that is not an embedded base class.
      
   if(!fImp) return 0;
   d_Attribute& attr = ((d_Class*)fImp)->attribute_at_position(pos);
   if(!attr) return 0;
   if(!fAttribute) fAttribute = new rooAttribute();  
   fAttribute->setImp((void*)&attr);
   return *fAttribute;
}

//______________________________________________________________________________
const rooAttribute & rooClass::attribute_with_id(UInt_t id)
{
   // Gets the attribute with the specified ID in the described class.
   //
   // Parameter: 
   //     id - the attribute ID of the desired attribute.
   //
   // Returns: 
   //     An attribute descriptor for the attribute with the specified ID, 
   //    or the null descriptor if the described class has no such attribute.
   
   if(!fImp) return 0;
   d_Attribute& attr = ((d_Class*)fImp)->attribute_with_id(id);
   if(!attr) return 0;
   if(!fAttribute) fAttribute = new rooAttribute();
   fAttribute->setImp((void*)&attr);
   return *fAttribute;
}

//______________________________________________________________________________
 Int_t rooClass::number_of_attributes() const
{
   // Gets the number of attributes in the described class.
   //
   // Returns:
   //    The number of immediate base classes, attributes, and relationships 
   //    in the defined class.
   //
   // The returned number does not include inherited attributes.

   return fImp ? ((d_Class*)fImp)->number_of_attributes()  : 0;
}

//______________________________________________________________________________
 const rooClassPosition rooClass::position_in_class(const TString& memName)
{
   // Gets the class position of the specified attribute within the 
   // described class.
   //
   // Parameters: 
   //    memName - the name of the attribute whose position is desired. 
   //    This string can be a qualified name (such as foo::base::x) to 
   //    disambiguate attributes of the same name inherited from different 
   //    base classes. You should specify a qualified name only if necessary 
   //    because it takes more time to look up a qualified name than an 
   //    unqualified one.
   //
   // Returns: 
   //    A class position that gives the layout position of the specified 
   //    attribute within the described class.
   
   if(!fImp) return 0;
   Class_Position cp = ((d_Class*)fImp)->position_in_class(memName.Data());
   if(!cp) return 0;

   if(!fPosition) fPosition = new rooClassPosition((void*)&cp);
   else fPosition->setImp((void*)&cp);
   return *fPosition;
}

//______________________________________________________________________________
 const rooClassPosition rooClass::position_in_class(const rooAttribute & ratr)
{
   // Gets the class position of the specified attribute within the 
   // described class.
   //
   // Parameters: 
   //    ratr - an attribute descriptor for the attribute whose position is 
   //    desired.
   //
   // Returns: 
   //    A class position that gives the layout position of the specified 
   //    attribute within the described class.
   
   if(!fImp) return 0;
   d_Attribute* atr = (d_Attribute*)ratr.getImp();
   Class_Position cp = ((d_Class*)fImp)->position_in_class(*atr);

   if(!fPosition) fPosition = new rooClassPosition((void*)&cp);
   else fPosition->setImp((void*)&cp);
   return *fPosition;
}

//______________________________________________________________________________
 Bool_t rooClass::is_string_type() const
{
   // Tests whether the described class is a string class.
   //
   // Returns:
   //    kTRUE if the described class is a string class; otherwise, kFALSE.
   //
   // The string classes are:
   //    The ASCII string class ooVString
   //    The optimized string classes ooString( N)
   //    The Unicode string class ooUTF8String
   //    The Smalltalk string class ooSTString 

   return fImp ? ((d_Class*)fImp)->is_string_type() : 0;
}

//______________________________________________________________________________
 Bool_t rooClass::is_internal() const
{
   // Tests whether the described class is an internal Objectivity/DB class.
   //
   // Returns: 
   //    kTRUE if the described class is an internal Objectivity/DB class; 
   //    kFALSE if the described class is an application-defined class (including 
   //    an optimized string class).

   return fImp ? ((d_Class*)fImp)->is_internal() : 0;
}

//______________________________________________________________________________
 Bool_t rooClass::is_deleted() const
{
   // Tests whether the described class is deleted.
   //
   // Returns:
   //    kTRUE if the described class has been deleted from the schema; otherwise,
   //    kFALSE.
   //
   // Active Schema cannot delete classes. However, another application could 
   // have deleted the class before Active Schema started. In that case, the 
   // class description remains in the schema but is marked as deleted.
   
   return fImp ? ((d_Class*)fImp)->is_deleted() : 0;
}

//______________________________________________________________________________
 Bool_t rooClass::has_base_class(const TString& clname) const
{
   // Tests whether the described class is derived from the specified base class.
   //
   // Parameters: 
   //       clname - the name of the base class of interest.
   //
   // Returns:
   //       kTRUE if the described class is derived from clname; 
   //       otherwise, kFALSE.

   return fImp ? ((d_Class*)fImp)->has_base_class(clname.Data()) : 0;
}

//______________________________________________________________________________
 Bool_t rooClass::has_virtual_table() const
{
   // Tests whether the described class has a virtual table.
   //
   // Returns:
   //    kTRUE if the described class has a virtual table; otherwise, kFALSE.

   return fImp ? ((d_Class*)fImp)->has_virtual_table() : 0;
}

//______________________________________________________________________________
 Int_t rooClass::shape_number() const
{
   // Returns the shape number for this class descriptor.
   //
   // If the described shape is the original shape of the described class and 
   // version, the shape number is identical to the type number.
   //
   // See also, next_shape(), previous_shape()
   
   return fImp ? ((d_Class*)fImp)->shape_number() : 0;
}

//______________________________________________________________________________
const rooClass & rooClass::next_shape() 
{   
   // next_shape() and previous_shape() return the following and preceding
    // shapes of an evolved class, respectively.
   //

   if(!fImp) return 0;
   d_Class& cl = ((d_Class*)fImp)->next_shape();
   if(!cl) return 0;

   if(!fNextShape) fNextShape = new rooClass((void*)&cl);
   fNextShape->setImp((void*)&cl);
   return *fNextShape;
}

//______________________________________________________________________________
const rooClass & rooClass::previous_shape()
{
   // Gets the previous shape of the described class.
   //
   // Returns: 
   //    A class descriptor for the previous shape of the described class, 
   //    or the null descriptor if the schema does not contain a description of 
   //    the previous shape of the described class and version.
   //
   // See also: next_shape()
   
   if(!fImp) return 0;
   d_Class& cl = ((d_Class*)fImp)->previous_shape();
   if(!cl) return 0;
   if(!fPrevShape) fPrevShape = new rooClass((void*)&cl);
   fPrevShape->setImp((void*)&cl);
   return *fPrevShape;
}

//______________________________________________________________________________
 Int_t rooClass::version_number() const
{
   // The version_number() function returns the number of a changed class
   // where "schema versioning" was used rather than "schema evolution."

   return fImp ? ((d_Class*)fImp)->version_number() : 0;
}

//______________________________________________________________________________
const rooClass & rooClass::latest_version()
{
   // The version_number() function returns the number of a changed class
   // where "schema versioning" was used rather than "schema evolution."

   if(!fImp) return 0;
   d_Class& cl = ((d_Class*)fImp)->latest_version();
   if(!cl) return 0;

   if(!fLatestVersion) fLatestVersion = new rooClass((void*)&cl);
   fLatestVersion->setImp((void*)&cl);
   return *fLatestVersion;
}

//______________________________________________________________________________
 void rooClass::enable_root_descent()
{
   // Enables access to ancestors of Objectivity/C++ persistent-object and
   // storage-object classes when iterating through inherited attributes or 
   // base classes.
   //
   // By default, the iterators returned by attributes_plus_inherited_begin() 
   // and base_classes_plus_inherited_begin() treat the Objectivity/C++
   // persistent-object base class ooObj and the storage-object classes 
   // ooContObj, ooDBObj, and ooFDObj as if they were root base classes, 
   // inheriting from no other classes. You can call this member function to 
   // override this behavior, allowing access to ancestor classes at all levels.
   //
   // See also: disable_root_descent()

   d_Class::enable_root_descent();
}

//______________________________________________________________________________
 void rooClass::disable_root_descent()
{
   // Disables access to ancestors of Objectivity/C++ persistent-object and
   // storage-object classes when iterating through inherited attributes or 
   // base classes.
   //
   // By default, the iterators returned by attributes_plus_inherited_begin() and
   // base_classes_plus_inherited_begin() treat the Objectivity/C++
   // persistent-object base class ooObj and the storage-object classes 
   // ooContObj, ooDBObj, and ooFDObj as if they were root base classes, 
   // inheriting from no other classes. You can call enable_root_descent() to 
   // override this behavior, allowing access to ancestor classes at all levels; 
   // after doing so, you can call this member function to disable access once 
   // again.
   //
   // See also: root_descent_is_enabled() 

   d_Class::disable_root_descent();
}

//______________________________________________________________________________
 Bool_t rooClass::root_descent_is_enabled()
{
   // Tests whether iteration through inherited attributes or base classes 
   // includes access to ancestors of Objectivity/C++ persistent-object and 
   // storage-object classes.
   //
   // Returns kTRUE if root descent is enabled; otherwise, kFALSE.
   //
   // By default, access is disabled; the iterators returned by
   // attributes_plus_inherited_begin() and base_classes_plus_inherited_begin()
   // treat the Objectivity/C++ persistent-object base class ooObj and the 
   // storage-object classes ooContObj, ooDBObj, and ooFDObj as if they were 
   // root base classes, inheriting from no other classes.
   //
   // See also, disable_root_descent()
   //             enable_root_descent()

   return d_Class::root_descent_is_enabled();
}


ROOT page - Class index - Top of the page

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.