#include <lemon/concept_check.h>
#include <lemon/concept/maps.h>
#include <lemon/maps.h>

#include "test_tools.h"

using namespace lemon;
using namespace lemon::concept;

struct A {};
struct B {};
class F
{
public:
  B operator()(const A &a) const {return B();}
};

int func(A a) {return 3;}

typedef ReadMap<A,double> DoubleMap;

int main()
{ // checking graph components
  
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();

  checkConcept<ReadMap<A,double>, AddMap<DoubleMap,DoubleMap> >();
  checkConcept<ReadMap<A,double>, SubMap<DoubleMap,DoubleMap> >();
  checkConcept<ReadMap<A,double>, MulMap<DoubleMap,DoubleMap> >();
  checkConcept<ReadMap<A,double>, DivMap<DoubleMap,DoubleMap> >();
  checkConcept<ReadMap<A,double>, NegMap<DoubleMap> >();
  checkConcept<ReadMap<A,double>, AbsMap<DoubleMap> >();
  checkConcept<ReadMap<A,double>, ShiftMap<DoubleMap> >();
  checkConcept<ReadMap<A,double>, ScaleMap<DoubleMap> >();
  
  checkConcept<ReadMap<B,double>, ComposeMap<DoubleMap,ReadMap<B,A> > >();

  checkConcept<ReadMap<A,B>, FunctorMap<A,B,F> >();

  int a;
  
  a=mapFunctor(constMap<A,int>(2))(A());
  check(a==2,"Something is wrong with mapFunctor");

  B b;
  b=functorMap<A,B>(F())[A()];

  a=functorMap<A,int>(&func)[A()];
  check(a==3,"Something is wrong with functorMap");

  std::cout << __FILE__ ": All tests passed.\n";
  
  return 0;
}
