// -*- mode: C++ -*-
#ifndef MiX_ATTRMAP_H_
#define MiX_ATTRMAP_H_

#include <vector>
#include "XMLString.h"
#include "misc.h"

namespace MiX{
  template <class charT,class char_traits,class xml_traits>
  class AttrMap {
  public:
    MiX_Template_Typedef(charT,char_traits,xml_traits);
    typedef std::pair<string_type,string_type> val_type;
    typedef std::vector<val_type> container_type;
    typedef typename container_type::iterator iterator;
    typedef typename container_type::const_iterator const_iterator;
  private:
    container_type impl_;
    struct search_by_key{
      string_type key_;
      search_by_key(const string_type& key) : key_(key) { };
      bool operator()(const val_type& v){ return v.first==key_; }
    };

  public:
    /// コンストラクタ
    AttrMap(){ impl_.clear(); }
    /// コンテナの最初の要素を示すイテレータを得る
    iterator begin() { return impl_.begin(); }
    /// コンテナの最後の要素の一つ後を示すイテレータを得る
    iterator end() { return impl_.end(); }
    /// コンテナの最初の要素を示すイテレータを得る(const版)
    const_iterator begin()const{ return impl_.begin(); }
    /// コンテナの最後の要素の一つ後を示すイテレータを得る(const版)
    const_iterator end()const{ return impl_.end(); }
    /// コンテナに格納されている要素数を得る
    size_t size()const{ return impl_.size(); }
    /// コンテナが空かどうかを得る
    bool empty()const{ return impl_.empty(); }
    /// コンテナに値を追加する
    void insert(const val_type& data){ impl_.push_back(data); }
    /// コンテナを空にする
    void clear(){ impl_.clear(); }
    /// keyによって要素を検索しイテレータを返す
    iterator find(const string_type& key){ 
      return find_if(begin(),end(),search_by_key(key));
    }
    /// keyによって要素を検索しイテレータを返す(const版)
    const_iterator find(const string_type key)const{ 
      return find_if(begin(),end(),search_by_key(key));
    }
    /// keyによって示される要素を削除する
    void erase(const string_type key){
      iterator it = find(key);
      if(it!=end()) impl_.erase(it);
    }
    /// keyによって示される要素の値を得る
    string_type operator[](const string_type& key) const;
  };
}

#ifndef MiX_ATTRMAP_CPP_
#include "AttrMap.cpp"
#endif

#endif
