home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static const char sccsid[] = "%Z%%I% %G% %U% %W%";
- #endif
- /*
- * COMPONENT_NAME: (RTTI) Run-Time Type System for C++
- *
- * FUNCTIONS:
- *
- * ORIGINS: 27
- *
- * (C) COPYRIGHT International Business Machines Corp. 1992
- * This work was supported by a grant from International Business
- * Machines, Inc. These procedures are contributed to the public domain
- * by International Business Machines Inc. "AS IS" without any warranty
- * of any kind including the warranty of merchantability or fitness
- * for a particular purpose.
- *
- *
- * This is free software. Feel free to redistribute and/or modify it.
- * Please send us e-mail and let us know if you have any problems
- * or suggestions.
- *
- * Arindam Banerji
- * axb@cse.nd.edu
- */
-
-
- #include "rtti_entry.h"
- #include "rttiimpl.h"
-
- /*****
- SCAFFOLDING NECESSARY TO SUPPORT RTTI
- ******/
-
- // initialize a Type_info object with the name of the class and any
- // base class Type_info objects. In this case, since there are no other
- // base classes - just set the last NULL pointer.
- static const Type_info *base_set[] =
- {(const Type_info *)&CLASS::info_obj,0} ;
- const Type_info Type_info::info_obj("Type_info", base_set) ;
-
- // This is a function that returns the dynamic type of a class.
- typeid
- Type_info::get_info() const
- {
- return &info_obj ;
- } // dynamic_type()
-
- // This is a static function that returns the static type of a class.
- typeid
- Type_info::info()
- {
- return &info_obj ;
- } // static_type()
-
- NARROWING_MECHANISM(Type_info)
-
- /******
- IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS TYPEID CLASS
- *******/
- // compare two typeids
- int
- typeid::operator== (typeid i ) const
- {
- return ( id->same (i.get_type_info()) ) ;
- } // just call the same operator on the Type_info class
-
-
-
- /******
- IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS BASE_LIST CLASS
- *******/
- // internal function to add to the list of base classes.
- void
- base_list::add_to_list (const Type_info *info )
- {
- // if the array is full then extend it .
- if ( num == sz )
- {
- // allocate new array
- const Type_info **temp = new const Type_info * [sz+=BASE_LIST_INCR] ;
- // copy in old members
- for ( int i = 0 ; i != num ; i++ )
- temp[i] = list[i] ;
- // delete existing array
- delete [] (Type_info *) list ;
- // set the pointer to the array
- list = temp ;
- } // make sure that there is enough space
-
- // set the new value
- list[num++] = info ;
- } // add an entry into the list
-
- // add information from a Type_info variable into the internal array
- void
- base_list::add(const Type_info *info )
- {
- // add this Type_info to the list (array)
- add_to_list((const Type_info *) info) ;
-
- // loop thru all the base classes of this Type_info
- for ( int i = 0 ; (info->b[i] != NULL) ; i++ )
- add(info->b[i]) ;
- } // add the bases belonging to a Type_info to the list
-
- // used by the base_iterator class to copy in all the indirect and direct
- // base classes into an array.
- void
- base_list::copy_bases(const Type_info **b)
- {
- for ( int i = 0 ; i != sz ; i++)
- b[i] = list[i] ;
- b[i] = NULL ;
- } // copy all the bases into the given array
-
- // constructor that creates the initial list of base classes.
- base_list::base_list(const Type_info **bases) : sz(0), list (0), num (0)
- {
- // make sure that there are available base classes.
- if ( bases )
- {
- // allocate an array ( list) to hold the base classes.
- list = new const Type_info * [sz += BASE_LIST_INCR] ;
- // loop thru the passed list of bases and do the needful.
- for (int i = 0 ; (bases[i] != NULL) ; i++ )
- add (bases[i]) ;
- } // add all the bases - direct or indirect
- } // actually go thru the list and create the list
-
- /******
- IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS TYPE_INFO CLASS
- *******/
- // is this a base class of the called object ? if yes return(1)- else (0)
- int
- Type_info::has_base (const Type_info *t, int direct ) const
- {
-
- const Type_info *p ; // pointer to hold base class info.
- // create an iterator for this member function
- base_iterator iter(b,direct) ;
- while ( p = iter() ) // iterate thru all the base classes
- {
- if ( p->same(t) ) return ( 1 ) ; // if match, return positive
- } // loop thru
-
- // if it gets till here - then obviously no match was found
- return ( 0 ) ;
- } // see if this is one of the base classes
-
-
- // create an iterator and return it to the caller
- base_iterator
- Type_info::bases(int direct) const
- {
- return ( *(new base_iterator(b,direct)) ) ;
- } // constructor
-
- /******
- IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS BASE_ITERATOR CLASS
- *******/
-
- // constructor that does most of the work.
- base_iterator::base_iterator(const Type_info **bb, int direct )
- : i(0) , alloc(0) , b(bb)
- {
- // for direct base classes - do not do anything.
- if (! direct )
- {
- // temporarily create a complete list of bases
- base_list bases (bb) ;
- // now find out the number and allocate an array, accordingly
- b = new const Type_info * [bases.number() + 1] ;
- // copy in all bases into this iterator
- bases.copy_bases(b) ;
- // make sure that alloc is set - so that the destructor can deallocate
- alloc = 1 ;
- } // do this only for the non-default case
- } // the constructor for the base_iterator class
-
- // the iteration function - returns NULL, when iteration is done, otherwise
- // it returns the Type_info object for an appropriate base class.
- const Type_info *
- base_iterator::operator()()
- {
- // set up a pointer to the base class.
- const Type_info *p = b[i] ;
- // increment only if not at the end-of-base-class-list
- if (p) i++ ;
- // return the Type_info object (actually pointer to).
- return ( p ) ;
- } // the actual iteration function
-
- // destructor - deallocates if indirect base classes were used.
- base_iterator::~base_iterator()
- {
- if ( alloc)
- delete [] (Type_info *) b ;
- } // the destructor for base_iterators
-