home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 415_02 / rtti / src / rtti.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-04  |  5.8 KB  |  200 lines

  1. #ifndef lint
  2. static const char sccsid[] = "%Z%%I%  %G% %U% %W%";
  3. #endif
  4. /*
  5.  * COMPONENT_NAME: (RTTI) Run-Time Type System for C++
  6.  *
  7.  * FUNCTIONS:
  8.  *
  9.  * ORIGINS: 27
  10.  *
  11.  * (C) COPYRIGHT International Business Machines Corp. 1992
  12.  * This work was supported by a grant from International Business
  13.  * Machines, Inc. These procedures are contributed to the public domain
  14.  * by International Business Machines Inc. "AS IS" without any warranty
  15.  * of any kind including the warranty of merchantability or fitness
  16.  * for a particular purpose.
  17.  *
  18.  *
  19.  * This is free software. Feel free to redistribute and/or modify it.
  20.  * Please send us e-mail and let us know if you have any problems
  21.  * or suggestions.
  22.  *
  23.  * Arindam Banerji
  24.  * axb@cse.nd.edu
  25.  */
  26.  
  27.  
  28. #include   "rtti_entry.h"
  29. #include   "rttiimpl.h"
  30.  
  31. /*****
  32.    SCAFFOLDING NECESSARY TO SUPPORT RTTI
  33. ******/
  34.  
  35. // initialize a Type_info object with the name of the class and any
  36. // base class Type_info objects. In this case, since there are no other
  37. // base classes - just set the last NULL pointer.
  38. static const Type_info *base_set[] =
  39.            {(const Type_info *)&CLASS::info_obj,0} ;
  40. const Type_info Type_info::info_obj("Type_info", base_set) ;
  41.  
  42. // This is a function that returns the dynamic type of a class.
  43. typeid
  44. Type_info::get_info() const
  45. {
  46.  return &info_obj ;
  47. } // dynamic_type()
  48.  
  49. // This is a static function that returns the static type of a class.
  50. typeid
  51. Type_info::info()
  52. {
  53.  return &info_obj ;
  54. } // static_type()
  55.  
  56. NARROWING_MECHANISM(Type_info)
  57.  
  58. /******
  59.    IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS TYPEID CLASS
  60. *******/
  61. // compare two typeids
  62. int
  63. typeid::operator== (typeid i ) const
  64. {
  65.   return ( id->same (i.get_type_info()) ) ;
  66. } // just call the same operator on the Type_info class
  67.  
  68.  
  69.  
  70. /******
  71.    IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS BASE_LIST CLASS
  72. *******/
  73. // internal function to add to the list of base classes.
  74. void
  75. base_list::add_to_list (const Type_info *info )
  76. {
  77.  // if the array is full then extend it .
  78.   if ( num == sz )
  79.    {
  80.      // allocate new array
  81.      const Type_info **temp =  new const Type_info * [sz+=BASE_LIST_INCR] ;
  82.      // copy in old members
  83.      for ( int i = 0 ; i != num ; i++ )
  84.       temp[i] = list[i] ;
  85.      // delete existing array
  86.      delete [] (Type_info *) list ;
  87.      // set the pointer to the array
  88.      list = temp ;
  89.    } // make sure that there is enough space
  90.  
  91.   // set the new value
  92.   list[num++] = info ;
  93. } // add an entry into the list
  94.  
  95. // add information from a Type_info variable into the internal array
  96. void
  97. base_list::add(const Type_info *info )
  98. {
  99.   // add this Type_info  to the list (array)
  100.   add_to_list((const Type_info *) info) ;
  101.  
  102.   // loop thru all the base classes of this Type_info
  103.   for ( int i = 0 ; (info->b[i] != NULL) ; i++ )
  104.      add(info->b[i]) ;
  105. } // add the bases belonging to a Type_info to the list
  106.  
  107. // used by the base_iterator class to copy in all the indirect and direct
  108. // base classes into an array.
  109. void
  110. base_list::copy_bases(const Type_info **b)
  111. {
  112.  for ( int i = 0 ; i != sz ; i++)
  113.      b[i] = list[i] ;
  114.  b[i] = NULL ;
  115. } // copy all the bases into the given array
  116.  
  117. // constructor that creates the initial list of base classes.
  118. base_list::base_list(const Type_info **bases) : sz(0), list (0), num (0)
  119. {
  120.    // make sure that there are available base classes.
  121.    if ( bases )
  122.      {
  123.       // allocate an array ( list) to hold the base classes.
  124.       list = new const Type_info * [sz += BASE_LIST_INCR] ;
  125.       // loop thru the passed list of bases and do the needful.
  126.       for (int  i = 0 ; (bases[i] != NULL)  ; i++ )
  127.            add (bases[i]) ;
  128.      } // add all the bases - direct or indirect
  129. } // actually go thru the list and create the list
  130.  
  131. /******
  132.    IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS TYPE_INFO CLASS
  133. *******/
  134. // is this a base class of the called object ? if yes return(1)- else (0)
  135. int
  136. Type_info::has_base (const Type_info *t, int direct  ) const
  137. {
  138.  
  139.   const Type_info  *p ;   // pointer to hold base class info.
  140.   // create an iterator for this member function
  141.   base_iterator    iter(b,direct) ;
  142.   while ( p = iter() ) // iterate thru all the base classes
  143.    {
  144.      if ( p->same(t) )  return ( 1 ) ; // if match, return positive
  145.    } // loop thru
  146.  
  147.   // if it gets till here - then obviously no match was found
  148.   return ( 0 ) ;
  149. } // see if this is one of the base classes
  150.  
  151.  
  152. // create an iterator and return it to the caller
  153. base_iterator
  154. Type_info::bases(int direct) const
  155. {
  156.  return ( *(new base_iterator(b,direct)) ) ;
  157. } // constructor
  158.  
  159. /******
  160.    IMPLEMENTATION OF NON-INLINE MEMBER FUNCTIONS BASE_ITERATOR CLASS
  161. *******/
  162.  
  163. // constructor that does most of the work.
  164. base_iterator::base_iterator(const Type_info **bb, int direct  )
  165.    : i(0) , alloc(0) , b(bb)
  166. {
  167.   // for direct base classes - do not do anything.
  168.   if (! direct )
  169.     {
  170.       // temporarily create a complete list of bases
  171.       base_list    bases (bb) ;
  172.       // now find out the number and allocate an array, accordingly
  173.       b = new const Type_info * [bases.number() + 1] ;
  174.       // copy in all bases into this iterator
  175.       bases.copy_bases(b) ;
  176.       // make sure that alloc is set - so that the destructor can deallocate
  177.       alloc = 1 ;
  178.     } // do this only for the non-default case
  179. } // the constructor for the base_iterator class
  180.  
  181. // the iteration function - returns NULL, when iteration is done, otherwise
  182. // it returns the Type_info object for an appropriate base class.
  183. const Type_info *
  184. base_iterator::operator()()
  185. {
  186.  // set up a pointer to the base class.
  187.  const Type_info *p = b[i] ;
  188.  // increment only if not at the end-of-base-class-list
  189.  if (p) i++ ;
  190.  // return the Type_info object (actually pointer to).
  191.  return ( p ) ;
  192. } // the actual iteration function
  193.  
  194. // destructor - deallocates if indirect base classes were used.
  195. base_iterator::~base_iterator()
  196. {
  197.   if ( alloc)
  198.      delete [] (Type_info *) b ;
  199. } // the destructor for base_iterators
  200.