namespace LocARNA {


    template<class T>
    Alphabet<T>::Alphabet()
	: alph_vec(),alph_hash() {
    }

    template<class T>
    Alphabet<T>::Alphabet(const elem_vector_type &a)
	: alph_vec(),alph_hash()
    {
	init(a);
    }

    template<class T>
    Alphabet<T>::Alphabet(const elem_type *s,int len)
	: alph_vec(),alph_hash()
    {
	vec_t a(s,s+len);
	init(a);
    }

    template<class T>
    typename Alphabet<T>::size_type
    Alphabet<T>::size() const {
	return alph_vec.size();
    }
    
    template<class T>
    typename Alphabet<T>::size_type
    Alphabet<T>::idx(const elem_type &elem) const {
	assert(alph_hash.find(elem) != alph_hash.end());
	
	return alph_hash.find(elem)->second;
    }
    
    template<class T>
    const typename Alphabet<T>::elem_type &
    Alphabet<T>::elem(size_type idx) const {
	assert(idx<alph_vec.size());
	
	return alph_vec[idx];
    }
    
    template<class T>
    bool
    Alphabet<T>::in(const elem_type &elem) const {
	return alph_hash.find(elem) != alph_hash.end();
    }
    
    template<class T>
    void Alphabet<T>::init(const vec_t &a) {
	alph_vec=a;
    
	for(typename Alphabet<T>::vec_t::size_type i=0; i < a.size() ; ++i) {
	    alph_hash[alph_vec[i]] = i;
	}
    }

    template<class T>
    std::ostream & 
    operator << (std::ostream &out ,Alphabet<T> a) {
	for (typename Alphabet<T>::elem_vector_type::const_iterator it=a.begin();
	     it!=a.end(); ++it ) {
	    out << (*it) << " ";
	}
    
	return out;
    }

} // end namespace LocARNA
