/*******************************************************************************
+
+  LEDA 3.5
+
+  node_map.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#ifndef LEDA_NODE_MAP_H
#define LEDA_NODE_MAP_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 350080
#include <LEDA/REDEFINE_NAMES.h>
#endif


//------------------------------------------------------------------------------
// node maps
//
// S. Naeher (1995)
//------------------------------------------------------------------------------


/*{\Manpage {node_map} {E} {Node Maps} }*/

#include <LEDA/graph.h>

template <class E>
class node_map : public graph_map {

/*{\Mdefinition
An instance of the data type |\Mname| is a map for the nodes of a graph
$G$, i.e., equivalent to $map\<node,E\>$ (cf. \ref{Maps}). It can be
used as a dynamic variant of the data type $node\_array$
(cf. \ref{Node Arrays}). }*/


  E def;

void clear_entry(GenPtr& x) const { LEDA_CLEAR(E,x); }
void copy_entry(GenPtr& x)  const { LEDA_COPY(E,x);  }
void init_entry(GenPtr& x)  const { x = leda_copy(def); }
/*
void read_entry(istream& i, GenPtr& x) { LEDA_READ(E,x,i); }
void write_entry(ostream& o, GenPtr& x) const { LEDA_PRINT(E,x,o);}
*/


  
public:

const char* elem_type_name() const { return LEDA_TYPE_NAME(E); }

/*{\Mcreation M }*/

node_map() : graph_map(nil,0,0) { init_def_entry(); }
/*{\Mcreate  introduces a variable |\Mvar| of type |\Mname| and initializes
             it to the map with empty domain. }*/

node_map(const graph& G) : graph_map(&G,G.max_node_index()+1,0) 
{ init_table();  init_def_entry(); }
/*{\Mcreate  introduces a variable |\Mvar| of type |\Mname| and initializes
             it with a mapping $m$ from the set of all nodes of $G$ into 
             the set of variables of type $E$. The variables in the range 
             of $m$ are initialized by a call of the default constructor 
             of type $E$. }*/

node_map(const graph& G, E x) : graph_map(&G,G.max_node_index()+1,0) 
{ def = x; init_table();  init_def_entry(); }
/*{\Mcreate  introduces a variable |\Mvar| of type |\Mname| and initializes
             it with a mapping $m$ from the set of all nodes of $G$ into 
             the set of variables of type $E$. The variables in the range 
             of $m$ are initialized with a copy of $x$. }*/

node_map(const node_map<E>& A) : graph_map(A), def(A.def)   
{ init_def_entry(); }

node_map<E>& operator=(const node_map<E>& A) 
{ clear_def_entry();
  graph_map::operator=(A);  
  def = A.def;
  init_def_entry();
  return *this;
 }

~node_map() { clear_table(); clear_def_entry(); }


/*{\Moperations 1.3 4.3 }*/


void init()  { graph_map::init(nil,1,0); }
/*{\Mop      makes |\Mvar| a node map with empty domain. }*/

void init(const graph& G)      
{ graph_map::init(&G,G.max_node_index()+1,0); 
  init_table(); }
/*{\Mop       makes |\Mvar| to a mapping $m$ from the set of all nodes of $G$ 
              into the set of variables of type $E$. The variables in the 
              range of $m$ are initialized by a call of the default 
              constructor of type $E$. }*/

void init(const graph& G, E x) 
{ graph_map::init(&G,G.max_node_index()+1,0); 
  def = x;
  init_table(); }
/*{\Mop       makes |\Mvar| to a mapping $m$ from the set of all nodes of $G$ 
              into the set of variables of type $E$. The variables in the 
              range of $m$ are initialized with a copy of $x$. }*/

const E& operator()(node v) const 
{  return LEDA_CONST_ACCESS(E,graph_map::map_read(v)); }

const E& operator[](node v) const 
{  return LEDA_CONST_ACCESS(E,graph_map::map_read(v)); }

E& operator[](node v) {  return LEDA_ACCESS(E,graph_map::map_access(v)); }
/*{\Marrop    returns the variable $M(v)$. }*/

};

/*{\Mimplementation
Node maps are implemented by an efficient hashing method based on the 
internal numbering of the nodes. An access operation takes expected 
time $O(1)$. 
}*/



#if LEDA_ROOT_INCL_ID == 350080
#undef LEDA_ROOT_INCL_ID
#include <LEDA/UNDEFINE_NAMES.h>
#endif

#endif
