#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>

template <typename Iterator, typename Funktion>
void fuerAlle(Iterator anfang, Iterator ende,Funktion f){
  for (;anfang != ende;anfang++){
    f(*anfang);
  }
}

template <typename A>
void printout(A el){
 std::cout << el << " ";
}

void printint(int el){
 std::cout << el << " ";
}

template <typename P>
void printPair(P p ){
  std::cout << "("<<p.first << ", "<<p.second <<") ";
}

template <typename Iterator>
void print(Iterator anfang, Iterator ende){
  fuerAlle(anfang,ende,printint);
}

int main(){
  int xs [] = {1,2,3,4,5,6,7};
  //  std::cout << sizeof(xs) << std::endl;
  print(xs,xs+7);

  std::cout << xs[5]   << " "
	    << *(xs+5) << " " 
	    << *(5+xs) << " " 
	    << 5[xs]   << " " 
	    << std::endl;

  std::vector<int> ys;
  ys.push_back(1);
  ys.push_back(2);
  ys.push_back(3);
  ys.push_back(4);
  ys.push_back(5);
  ys.push_back(6);
  ys.push_back(7);
  print(ys.begin(),ys.end());

  std::vector<int>::iterator anfang=ys.begin();
  std::vector<int>::iterator ende=ys.end();
  for (;anfang<ende;anfang++){
    std::cout << *anfang << " ";
  }

  std::list<int> zs;
  zs.push_back(1);
  zs.push_back(2);
  zs.push_back(3);
  zs.push_back(4);
  zs.push_back(5);
  zs.push_back(6);
  zs.push_back(7);
  print(zs.begin(),zs.end());

  std::map<std::string,float> noten;
  noten["programmieren 3"] = 1.0;
  noten["programmieren 1"] = 3.0;
  noten["analysis"] = 4.0;

  std::cout << noten["analysis"] << std::endl;
  std::cout << noten["l.a."] << std::endl;

  for_each(noten.begin(),noten.end()
	   ,printPair<std::pair<std::string,float> >);

  std::string str  = "hallo";
  for_each(str.begin(),str.end(),printout<char>);

  return 0;
}
