#ifndef ELEMENT_H
#define ELEMENT_H

#include <visitor.h>

/*!
\brief Base of data tree in Visitor pattern.
*/
class Element
{
public:

  /** Forward this elements type to Visitor. */
  virtual void accept(const Visitor& v)=0;

  virtual ~Element() {};
};


/*!
\brief A data element in the data tree. 
*/
class ElementA : public Element
{
public:

  /** Forward ElementA's type to Visitor. */
  void accept(const Visitor& v);

  /** Simulated templated virtual function. */
  template<typename T>
  void print(T t) const;

  template<typename T>
  void print2(T t) const;
};

/*!
\brief A data element in the data tree. 
*/
class ElementB : public Element
{
public:

  /** Forward ElementB's type to Visitor. */
  void accept(const Visitor& v);

  /** Simulated templated virtual function. */
  template<typename T>
  void print(T t) const;

  template<typename T>
  void print2(T t) const;
};


// -------------------------------------------------- 
//  Implementation

template<typename T>
void ElementA::print(T t) const
{
   cout << "*A:t=" << t << endl;
}

template<typename T>
void ElementB::print(T t) const
{
   cout << "#B:t=" << t << endl;
}

void ElementA::accept(const Visitor& v)
{
     v.visit(*this);
}

void ElementB::accept(const Visitor& v)
{
     v.visit(*this);
}

template<typename T>
void ElementA::print2(T t) const
{
   cout << "<tagA>" << t << "</tagA>" << endl;
}

template<typename T>
void ElementB::print2(T t) const
{
   cout << "<tagB>" << t << "</tagB>" << endl;
}


#endif


