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, const 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
