// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): Jonathan Berry

// This software is copyrighted by the DIMACS Center at Rutgers, The State
// University of New Jersey.  IT IS PROVIDED AS IS, AND THE AUTHORS, DIMACS, AND
// RUTGERS, THE STATE UNIVERSITY OF NEW JERSEY  DISCLAIM
// ALL LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
// DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
// IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
// NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

// The authors hereby grant permission to use, copy, modify, distribute,
// and license this software and its documentation for any purpose, provided
// that existing copyright notices are retained in all copies and that this
// notice is included verbatim in any distributions. No written agreement,
// license, or royalty fee is required for any of the authorized uses.
// Modifications to this software may be copyrighted by their authors
// and need not follow the licensing terms described here, provided that
// the new terms are clearly indicated on the first page of each file where
// they apply.

// Last File Update: 31-Jul-1996
// 

#ifndef ELEMENTOPS_H
#define ELEMENTOPS_H

#include <fstream.h>
#include <LINK/basic/general.h>

//template <class Item> class List;


template <class Item> 
class ElementOps {
public:
    static int 		compareItems(const Item& e1, const Item& e2);
    static ostream& 	displayItem(ostream& os, const Item& e);
};

//*********************************************************************
//** If meaningful element comparisons and output are required, yet the
//** element type is a pointer, specialize the ElementOps class to 
//** redefine the compareItems() and displayItem() methods.
//**
//** the Method definitions are generated automatically by 'instantiate'
//*********************************************************************

//#ifdef DEFINE_ElementOps_TEMPLATE
#include<LINK/basic/ElementOps.cpp>
//#endif

// *****************************************************************
// EVERYTHING BELOW CAN GO WHEN VC++ SUPPORTS PARTIAL SPECIALIZATION
// *****************************************************************

typedef char *String;

int ElementOps<String>::compareItems(const String& e1, const String& e2);

class BinGraph;
class DBinGraph;
class DHyperGraph;
class Edge;
class Graph;
class HyperGraph;
class UBinGraph;
class UHyperGraph;
class UBinGraph;
class MBinGraph;
class MDBinGraph;
class MDHyperGraph;
class MEdge;
class MGraph;
class MHyperGraph;
class MUBinGraph;
class MUHyperGraph;
class MUBinGraph;
class Vertex;
class DJSet;
class GraphObject;
class ContainerNode;
class AttributeBase;
class VertexInfo;
template <class T> class Container;
template <class T> class List;
template <class T> class SortedList;
template <class T> class DList;
template <class T, class I> class Set;
template <class T> class Attribute;
template <class T> class AttributeElementOps;

typedef AttributeBase* _AttributeBasep;
typedef BinGraph* _BinGraphp;
typedef DBinGraph* _DBinGraphp;
typedef DHyperGraph* _DHyperGraphp;
typedef Edge* _Edgep;
typedef Graph* _Graphp;
typedef HyperGraph* _HyperGraphp;
typedef MBinGraph* _MBinGraphp;
typedef MDBinGraph* _MDBinGraphp;
typedef MDHyperGraph* _MDHyperGraphp;
typedef MHyperGraph* _MHyperGraphp;
typedef MUBinGraph* _MUBinGraphp;
typedef MUHyperGraph* _MUHyperGraphp;
typedef UBinGraph* _UBinGraphp;
typedef UHyperGraph* _UHyperGraphp;
typedef Vertex* _Vertexp;
typedef Attribute<ContainerNode*>* _Attribute_ContainerNodep_p;
typedef Attribute<DJSet*>* _Attribute_DJSetp_p;
typedef Attribute<Edge*>* _Attribute_Edgep_p;
typedef Attribute<GraphObject*>* _Attribute_GraphObjectp_p;
typedef Attribute<Graph*>* _Attribute_Graphp_p;
typedef Attribute<Vertex*>* _Attribute_Vertexp_p;
typedef Attribute<char>* _Attribute_char_p;
typedef Attribute<char*>* _Attribute_charp_p;
typedef Attribute<double>* _Attribute_double_p;
typedef Attribute<float>* _Attribute_float_p;
typedef Attribute<int>* _Attribute_int_p;
typedef Attribute<DList<Vertex*>* >* _Attribute_DList_Vertexp_p_p;
typedef Attribute<List<Vertex*>* > * _Attribute_List_Vertexp_p_p;
typedef Set<Vertex*, DEFAULT_SET_IMPL<Vertex*> >* _Set_Vertexp_p;
typedef VertexInfo* _VertexInfop;

int ElementOps<_AttributeBasep>::compareItems(const _AttributeBasep& e1, 
					      const _AttributeBasep& e2) ;
ostream& ElementOps<_AttributeBasep>::displayItem(ostream& os, 
					      const _AttributeBasep& e);
int ElementOps<_BinGraphp>::compareItems(const _BinGraphp& e1, 
					      const _BinGraphp& e2) ;
ostream& ElementOps<_BinGraphp>::displayItem(ostream& os, 
					      const _BinGraphp& e);
int ElementOps<_DBinGraphp>::compareItems(const _DBinGraphp& e1, 
					      const _DBinGraphp& e2) ;
ostream& ElementOps<_DBinGraphp>::displayItem(ostream& os, 
					      const _DBinGraphp& e);
int ElementOps<_DHyperGraphp>::compareItems(const _DHyperGraphp& e1, 
					      const _DHyperGraphp& e2) ;
ostream& ElementOps<_DHyperGraphp>::displayItem(ostream& os, 
					      const _DHyperGraphp& e);
int ElementOps<_Edgep>::compareItems(const _Edgep& e1, 
					      const _Edgep& e2) ;
ostream& ElementOps<_Edgep>::displayItem(ostream& os, 
					      const _Edgep& e);
int ElementOps<_Graphp>::compareItems(const _Graphp& e1, 
					      const _Graphp& e2) ;
ostream& ElementOps<_Graphp>::displayItem(ostream& os, 
					      const _Graphp& e);
int ElementOps<_HyperGraphp>::compareItems(const _HyperGraphp& e1, 
					      const _HyperGraphp& e2) ;
ostream& ElementOps<_HyperGraphp>::displayItem(ostream& os, 
					      const _HyperGraphp& e);
int ElementOps<_MBinGraphp>::compareItems(const _MBinGraphp& e1, 
					      const _MBinGraphp& e2) ;
ostream& ElementOps<_MBinGraphp>::displayItem(ostream& os, 
					      const _MBinGraphp& e);
int ElementOps<_MDBinGraphp>::compareItems(const _MDBinGraphp& e1, 
					      const _MDBinGraphp& e2) ;
ostream& ElementOps<_MDBinGraphp>::displayItem(ostream& os, 
					      const _MDBinGraphp& e);
int ElementOps<_MDHyperGraphp>::compareItems(const _MDHyperGraphp& e1, 
					      const _MDHyperGraphp& e2) ;
ostream& ElementOps<_MDHyperGraphp>::displayItem(ostream& os, 
					      const _MDHyperGraphp& e);
int ElementOps<_MHyperGraphp>::compareItems(const _MHyperGraphp& e1, 
					      const _MHyperGraphp& e2) ;
ostream& ElementOps<_MHyperGraphp>::displayItem(ostream& os, 
					      const _MHyperGraphp& e);
int ElementOps<_MUBinGraphp>::compareItems(const _MUBinGraphp& e1, 
					      const _MUBinGraphp& e2) ;
ostream& ElementOps<_MUBinGraphp>::displayItem(ostream& os, 
					      const _MUBinGraphp& e);
int ElementOps<_MUHyperGraphp>::compareItems(const _MUHyperGraphp& e1, 
					      const _MUHyperGraphp& e2) ;
ostream& ElementOps<_MUHyperGraphp>::displayItem(ostream& os, 
					      const _MUHyperGraphp& e);
int ElementOps<_UBinGraphp>::compareItems(const _UBinGraphp& e1, 
					      const _UBinGraphp& e2) ;
ostream& ElementOps<_UBinGraphp>::displayItem(ostream& os, 
					      const _UBinGraphp& e);
int ElementOps<_UHyperGraphp>::compareItems(const _UHyperGraphp& e1, 
					      const _UHyperGraphp& e2) ;
ostream& ElementOps<_UHyperGraphp>::displayItem(ostream& os, 
					      const _UHyperGraphp& e);
int ElementOps<_VertexInfop>::compareItems(const _VertexInfop& e1, 
					      const _VertexInfop& e2) ;
ostream& ElementOps<_VertexInfop>::displayItem(ostream& os, 
					      const _VertexInfop& e);
int ElementOps<_Vertexp>::compareItems(const _Vertexp& e1, 
					      const _Vertexp& e2) ;
ostream& ElementOps<_Vertexp>::displayItem(ostream& os, 
					      const _Vertexp& e);
int ElementOps<_Attribute_ContainerNodep_p>::compareItems(
			const _Attribute_ContainerNodep_p& e1, 
			const _Attribute_ContainerNodep_p& e2) ;
ostream& ElementOps<_Attribute_ContainerNodep_p>::displayItem(ostream& os, 
			const _Attribute_ContainerNodep_p& e);
int ElementOps<_Attribute_DJSetp_p>::compareItems(
			const _Attribute_DJSetp_p& e1, 
			const _Attribute_DJSetp_p& e2) ;
ostream& ElementOps<_Attribute_DJSetp_p>::displayItem(ostream& os, 
			const _Attribute_DJSetp_p& e);
int ElementOps<_Attribute_Edgep_p>::compareItems(
			const _Attribute_Edgep_p& e1, 
			const _Attribute_Edgep_p& e2) ;
ostream& ElementOps<_Attribute_Edgep_p>::displayItem(ostream& os, 
			const _Attribute_Edgep_p& e);
int ElementOps<_Attribute_GraphObjectp_p>::compareItems(
			const _Attribute_GraphObjectp_p& e1, 
			const _Attribute_GraphObjectp_p& e2) ;
ostream& ElementOps<_Attribute_GraphObjectp_p>::displayItem(ostream& os, 
			const _Attribute_GraphObjectp_p& e);
int ElementOps<_Attribute_Graphp_p>::compareItems(
			const _Attribute_Graphp_p& e1, 
			const _Attribute_Graphp_p& e2) ;
ostream& ElementOps<_Attribute_Graphp_p>::displayItem(ostream& os, 
			const _Attribute_Graphp_p& e);
int ElementOps<_Attribute_Vertexp_p>::compareItems(
			const _Attribute_Vertexp_p& e1, 
			const _Attribute_Vertexp_p& e2) ;
ostream& ElementOps<_Attribute_Vertexp_p>::displayItem(ostream& os, 
			const _Attribute_Vertexp_p& e);
int ElementOps<_Attribute_char_p>::compareItems(
			const _Attribute_char_p& e1, 
			const _Attribute_char_p& e2) ;
ostream& ElementOps<_Attribute_char_p>::displayItem(ostream& os, 
			const _Attribute_char_p& e);
int ElementOps<_Attribute_charp_p>::compareItems(
			const _Attribute_charp_p& e1, 
			const _Attribute_charp_p& e2) ;
ostream& ElementOps<_Attribute_charp_p>::displayItem(ostream& os, 
			const _Attribute_charp_p& e);
int ElementOps<_Attribute_double_p>::compareItems(
			const _Attribute_double_p& e1, 
			const _Attribute_double_p& e2) ;
ostream& ElementOps<_Attribute_double_p>::displayItem(ostream& os, 
			const _Attribute_double_p& e);
int ElementOps<_Attribute_float_p>::compareItems(
			const _Attribute_float_p& e1, 
			const _Attribute_float_p& e2) ;
ostream& ElementOps<_Attribute_float_p>::displayItem(ostream& os, 
			const _Attribute_float_p& e);
int ElementOps<_Attribute_int_p>::compareItems(
			const _Attribute_int_p& e1, 
			const _Attribute_int_p& e2) ;
ostream& ElementOps<_Attribute_int_p>::displayItem(ostream& os, 
			const _Attribute_int_p& e);
int ElementOps<_Set_Vertexp_p>::compareItems(
			const _Set_Vertexp_p& e1, 
			const _Set_Vertexp_p& e2) ;
ostream& ElementOps<_Set_Vertexp_p>::displayItem(ostream& os, 
			const _Set_Vertexp_p& e);
int ElementOps<_Attribute_DList_Vertexp_p_p>::compareItems(
			const _Attribute_DList_Vertexp_p_p& e1, 
			const _Attribute_DList_Vertexp_p_p& e2) ;
ostream& ElementOps<_Attribute_DList_Vertexp_p_p>::displayItem(ostream& os, 
			const _Attribute_DList_Vertexp_p_p& e);
int ElementOps<_Attribute_List_Vertexp_p_p>::compareItems(
			const _Attribute_List_Vertexp_p_p& e1, 
			const _Attribute_List_Vertexp_p_p& e2) ;
ostream& ElementOps<_Attribute_List_Vertexp_p_p>::displayItem(ostream& os, 
			const _Attribute_List_Vertexp_p_p& e);
#endif
