// -*- c++ -*-
#ifndef AKAXISO_ELEMENTLIST_H__
#define AKAXISO_ELEMENTLIST_H__


namespace akaxiso {


  template<class E>
  class elementlist_base_impl {
  protected:
    elementlist_base_impl() {}
  public:
    enum { this_class_derives_from_the_elementlist_impl};
    typedef E element_type;
    typedef std::list<E*> container;

    typedef refiterator<typename container::iterator, E> iterator;
    typedef const_refiterator<typename container::const_iterator, 
      typename container::iterator, E> const_iterator;

    iterator begin() {
      return iterator(container_.begin());
    }
    iterator end() {
      return iterator(container_.end());
    }
    const_iterator begin() const {
      return const_iterator(container_.begin());
    }
    const_iterator end() const {
      return const_iterator(container_.end());
    }

    bool empty() const {
      return container_.empty();
    }
    size_t size() const {
      return container_.size();
    }


    E& operator[](int index);
    const E& operator[](int index) const;

    void push_back(E* e) {
      container_.push_back(e);
    }

  private:
    container container_;
  };


  class choice;

  template<class E>
  class elementlist_impl : public elementlist_base_impl<E> { 
    friend class choice;
  };

  template<class E>
  class const_elementlist_impl : public elementlist_base_impl<const E> { 
    friend class choice;
  };

}

#endif


  /*
  typedef elementlist_impl<element> elementlist;
  typedef elementlist_impl<const element> elementlist_const;
    void get_elementlist(const std::string &tagname, elementlist& el);
    void get_elementlist(const std::string &tagname, elementlist_const& el) const;
  protected:
    template<class E>
    void get_elementlist_impl(const name& name, E &el) { 
      for (container::iterator it = items_.begin(); it != items_.end(); ++it)
        if (it->get_qname() == name)
          el.push_back(static_cast<typename E::element_type*>(it->get_element()));
    }

    template<class E>
    void get_elementlist_impl(const name& name, E &el) const { 
      typedef typename E::element_type element_type;
      for (container::const_iterator it = items_.begin(); it != items_.end(); ++it)
        if (it->get_qname() == name)
          el.push_back(static_cast<const element_type*>(it->get_element()));
    }
    template<class E>
    void get_typesafe_elementlist(E &el, const std::string &tagname) {
      int dummy; dummy = E::this_class_derives_from_the_elementlist_impl;
      name name;
      name.set_name(tagname);
      get_elementlist_impl(name, el);
    }

    template<class E>
    void get_typesafe_elementlist(E &el, const std::string &tagname) const{
      int dummy;
      dummy = E::this_class_derives_from_the_elementlist_impl;
      name name;
      name.set_name(tagname);
      get_elementlist_impl(name, el);
    }
  */

