//////////////////////////////////////////////////////////////////////////////
// $Id: SmallList_tmpl.h,v 1.1.1.2 2004/10/04 17:25:10 nthiery Exp $
// Name:	SmallList_tmpl.h
// Purpose:	Class SmallList for efficient small lists of small objects
//		(Template implementation)
// Author:	Nicolas M. Thiéry <nthiery@mines.edu>
// Created:	2000/04
// Copyright:	LGPL
//////////////////////////////////////////////////////////////////////////////

#ifndef GLIP_SMALLLIST_TMPL_H
#define GLIP_SMALLLIST_TMPL_H

#include <GLIP/SmallList.h>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>

// Static members

// Constructors

template<class T, class S>
template<class InputIterator>
GLIP::SmallList<T,S>::SmallList(InputIterator first, InputIterator last) {
  init(first, last, std::distance(first,last));
}

template <class T, class S>
template<class InputIterator>
GLIP::SmallList<T,S>::SmallList(InputIterator first, InputIterator last,
				GLIP::SmallList<T,S>::size_type len)  {
  init(first, last, len);
}

template <class T, class S>
GLIP::SmallList<T,S>::SmallList(const string &s) {
  std::istringstream i(s);
  std::list<T>* v = parse_stream(i);
  if (v==0) { throw "Parse error: SmallList expected"; };
  init(v->begin(), v->end(), v->size());
  delete(v);
}

// Input Output

template <class T, class S>
std::ostream & GLIP::operator << (std::ostream &o, const SmallList<T,S> &p) {
  typename SmallList<T,S>::const_iterator i(p.begin());
  o << '[';
  if (i!=p.end()) {
    o << *i;
    i++;
    for(;i!=p.end();i++) {
      o << "," << *i;
    }
  }
  o << "]";
  return(o);
}

template <class T, class S>
std::list<T>* GLIP::SmallList<T,S>::parse_stream(std::istream &i) {
  char c;
  i >> c;
  if (c!='[') { i.setstate(std::ios::badbit); return 0; }
  std::list<T>* v = new std::list<T>(0);
  if (i.peek()==']') {
    i >> c;
  } else {
    while(1) {
      T t;
      // The strange segmentation fault happens at the next line
      if (!(i >> t)) {
	i.setstate(std::ios::badbit); delete(v); return 0;
      }
      v->push_back(t);
      if (!(i >> c)) { i.setstate(std::ios::badbit); delete(v); return 0; }
      if (c==',') {
	continue;
      } else if (c==']') {
	break;
      } else {
	i.setstate(std::ios::badbit); delete(v); return 0;
      }
    }
  }
  return v;
}

template <class T, class S>
std::istream &GLIP::operator >> (std::istream &i, SmallList<T,S> &p) {
  p.assign(i);
  return i;
}

#endif	/* GLIP_SMALLLIST_TMPL_H */

// Local Variables: 
// mode: c++
// End:
