/* pointer.h */

/* pointers store a rehashable pointer to a label.  the type during rehashing
   can be restricted by setting search_type in the constructor or by using the 
   form of set that takes two arguments.
   
   the default search_origin is the root, but the origin can be changed by using
   set_origin.
   
   when searches are performed, any pointers on the path will be expanded.
   
   pointers can not point to pointers.  
   a search_path of "" is a valid pointer to nil.
 */

#ifndef POINTER__H
#define POINTER__H

#include "data.h"

class dc_pointer : public dc_data {
private:
  dc_label *val; /* val can never point to this dc_pointer */

  /* path searched for on rehash.  search origin is parent */
  string search_path;

  dc_label *search_origin;

  /* val is restricted to search_type.
     Label_t, Undef_t, or will cause a non type-restricted search */
  dc_type search_type;

  list_item list_loc;
public:
  dc_pointer( void );
  dc_pointer( cstring label, dc_node *parent );

  dc_pointer( cstring path, dc_type T, dc_label *search_origin );
  dc_pointer( cstring path, dc_type T, dc_label *search_origin, 
	      cstring label, dc_node *parent = nil );

  ~dc_pointer( void );

  /* inherited functions */
  const dc_type type( void ) const { return Pointer_t; }
  string type_string( void ) const { return string( "pointer" ); }

  dc_pointer &operator=( const dc_pointer &P );
  bool operator==( const dc_pointer &P ) 
    { return valid && P.valid && val == P.val; }

  ostream &display( ostream &stream = cout ) { return display_c( stream ); }
  ostream &display_c( ostream &stream = cout ) const;
  friend ostream &operator<<( ostream &stream, const dc_pointer &P )
    { return P.display_c( stream ); }

  /* functions to access val */
  dc_label *get( void ) const { return val; }

  /* sets will automatically rehash.  set_origin will not */
  void set( cstring path, dc_type T );
  void set( cstring path ); /* leaves search_type unchanged */
  void set_origin( dc_label *origin ) { search_origin = origin; }

  /* rehash returns number of errors. failed rehash will set valid to false */
  int rehash( void );

  dc_label *duplicate( dc_node *parent ) const;
};

int rehash_pointers( void ); /* returns number of rehashing errors */

#endif
