#ifndef CDB_XX_MAP_HH__
#define CDB_XX_MAP_HH__

#include <cdbxx/db.hh>

namespace cdbxx
{

    template <typename T> struct item_traits {};

    template<>
    struct item_traits<std::string>
    {
	typedef char elem_type;
	typedef std::vector<elem_type>	vector_type;
	static vector_type pack_value(const std::string& str)
	{
	    return vector_type(str.begin(),str.end());
	}
	static std::string def_value() { return ""; }
	static void assign(std::string& to,const data_pair& item)
	{
	    to.assign(reinterpret_cast<const char*>(item.second.data_),
		      reinterpret_cast<const char*>(item.second.data_) + item.second.len_);
	}
    };

    template<>
    struct item_traits<int>
    {
	typedef int	elem_type;
	typedef std::vector<elem_type>	vector_type;
	static vector_type pack_value(const int val)
	{
	    vector_type v(1);
	    v[0]=val;
	    return v;
	}
	static int16_t def_value() { return 0; }
	static void assign(int& to,const data_pair& item)
	{
	    to = *reinterpret_cast<const int *>(item.second.data_);
	}
    };


    template <typename KeyT,typename ValueT,
    	      typename KTraitsT = item_traits<KeyT>,
	      typename VTraitsT = item_traits<ValueT> >
    class out_map: public out_db
    {
	typedef KTraitsT key_traits;
	typedef VTraitsT value_traits;
	
	public:
	out_map(const std::string& fname): out_db(fname)
	{}

	template <class K, class V> void insert(const std::vector<K> &key, const std::vector<V> &value);

	void set(const KeyT& key,const ValueT& value)
	{
	    typename key_traits::vector_type k=key_traits::pack_value(key);
	    typename value_traits::vector_type v=value_traits::pack_value(value);
	    out_db::insert<typename key_traits::elem_type,
		   typename value_traits::elem_type>(k,v);
	}

    };


    template <typename KeyT,typename ValueT,
    	      typename KTraitsT = item_traits<KeyT>,
	      typename VTraitsT = item_traits<ValueT> >
    class in_map: public in_db
    {
	typedef KTraitsT key_traits;
	typedef VTraitsT value_traits;
	public:
	in_map(const std::string& fname): in_db(fname)
	{}
	
	template <class K> iterator find(const std::vector<K> &key) const;
	
	ValueT get(const KeyT& key)
	{
	    ValueT value = value_traits::def_value();
	    iterator it = in_db::find<typename key_traits::elem_type>(key_traits::pack_value(key));
	    if (it != end())
		value_traits::assign(value,*it);
	    return value;
	}

    };

}

#endif

