#include <config.h>
#include <functions/FuncTab.h>

#include <functions/Add.h>
#include <functions/Subtract.h>
#include <functions/Multiply.h>
#include <functions/Divide.h>
#include <functions/NEG.h>

#include <functions/CLogLog.h>
#include <functions/Equals.h>

#include <functions/InProd.h>
#include <functions/Log.h>
#include <functions/LogFact.h>
#include <functions/LogGam.h>
#include <functions/Logit.h>
#include <functions/Max.h>
#include <functions/Mean.h>
#include <functions/Min.h>
#include <functions/Pow.h>
#include <functions/Probit.h>
#include <functions/SD.h>
#include <functions/Sqrt.h>
#include <functions/Step.h>
#include <functions/Sum.h>
#include <functions/Inverse.h>
#include <functions/LogDet.h>
#include <functions/Mexp.h>

/* Link functions */
#include <functions/Phi.h>
#include <functions/Exp.h>
#include <functions/ICLogLog.h>
#include <functions/ILogit.h>

#include <functions/Sort.h>
#include <functions/Rank.h>

using std::map;
using std::string;

FuncTab::FuncTab ()
{
  /* Operators */
  insert (new Add);
  insert (new Subtract);
  insert (new Multiply);
  insert (new Divide);

  /* Functions */
  insert (new Equals);
  insert (new InProd);
  insert (new Inverse);
  insert (new LogDet);
  insert (new LogFact);
  insert (new LogGam);
  insert (new Max);
  insert (new Mean);
  insert (new Min);
  insert (new Pow);
  insert (new SD);
  insert (new Sqrt);
  insert (new Step);
  insert (new Sum);
  insert (new NEG);
  insert (new Mexp);

  /* Link Functions and their inverses */
  insert (new CLogLog); insert (new ICLogLog);
  insert (new Log); insert (new Exp);
  insert (new Logit); insert (new ILogit);
  insert (new Probit); insert (new Phi);

  /* New functions */
  insert (new Sort);
  insert (new Rank);
}

FuncTab::~FuncTab ()
{
  map < const string, const Function *>::iterator p;
  for (p = _table.begin (); p != _table.end (); ++p)
    {
      delete p->second;
    }
}

bool
FuncTab::insert (Function const *func)
{
  string const &name = func->name ();
  if (_table.find (name) == _table.end ())
    {
      _table[name] = func;
      return true;
    }
  else
    {
      return false;
    }
}

bool
FuncTab::insert (InverseLinkFunc const *lfunc)
{
  string const &name = lfunc->name ();
  string const &linkname = lfunc->linkName ();
  if (_link_table.find (linkname) == _link_table.end () &&
      _table.find (name) == _table.end ())
    {
      _link_table[linkname] = lfunc;
      _table[name] = lfunc;
      return true;
    }
  else
    {
      return false;
    }
}

bool
FuncTab::erase (string const &name)
{
  map < const string, const Function *>::iterator p (_table.find (name));

  if (p == _table.end ())
    {
      return false;
    }
  else
    {
      _table.erase (p);
      return true;
    }
}

Function const *
FuncTab::find (string const &name) const
{
  map < const string, const Function *>::const_iterator 
    p = _table.find (name);

  if (p == _table.end ())
    {
      return 0;
    }
  else
    {
      return p->second;
    }
}

Function const *
FuncTab::findInverse (string const &name) const
{
  map < const string, const Function *>::const_iterator 
    p =_link_table.find (name);

  if (p == _link_table.end ())
    {
      return 0;
    }
  else
    {
      return p->second;
    }
}


syntax highlighted by Code2HTML, v. 0.9.1