#ifndef INCLUDED_BOBCAT_LINEARMAP_
#define INCLUDED_BOBCAT_LINEARMAP_

#include <vector>
#include <algorithm>
#include <stdexcept>
#include <initializer_list>

namespace FBB
{

template <typename Key, typename Value>
class LinearMap: private std::vector<std::pair<Key, Value>>
{
        using Base =  std::vector<std::pair<Key, Value>>;
        using LinMap =  LinearMap<Key, Value>;
        using ConstIterPair =  std::pair<
                    typename LinearMap<Key, Value>::const_iterator,
                    typename LinearMap<Key, Value>::const_iterator
                >;
        using IterPair = std::pair<
                    typename LinearMap<Key, Value>::iterator,
                    typename LinearMap<Key, Value>::iterator
                >;

    public:
        using value_type =  std::pair<Key, Value>;
        using iterator =  typename Base::iterator;
        using const_iterator =  typename Base::const_iterator;
        using reverse_iterator =  typename Base::reverse_iterator;
        using const_reverse_iterator =  typename Base::const_reverse_iterator;

        LinearMap()                     = default;

        template <typename Iterator>
        LinearMap(Iterator begin, Iterator end);

        LinearMap(std::initializer_list<value_type> initial);

        Value &operator[](Key const &key);

        Value &at(Key const &key);

        using Base::begin;
        using Base::capacity;
        using Base::cbegin;
        using Base::cend;
        using Base::clear;

        size_t count(Key const &key) const;

        using Base::crbegin;
        using Base::crend;

        using Base::emplace;
        using Base::empty;
        using Base::end;

        IterPair        equal_range(Key const &key);
        ConstIterPair   equal_range(Key const &key) const;

        bool erase(Key const &key);
        void erase(iterator iter);
        void erase(iterator begin, iterator end);

        iterator find(Key const &key);
        const_iterator find(Key const &key) const;

        using Base::get_allocator;

        std::pair<iterator, bool> insert(value_type const &keyvalue);
        iterator insert(iterator pos, value_type const &keyValue);
        template <typename Iterator>
        void insert(Iterator begin, Iterator end);

        iterator lower_bound(Key const &key);
        const_iterator lower_bound(Key const &key) const;

        using Base::max_size;
        using Base::rbegin;
        using Base::rend;
        using Base::reserve;
        using Base::size;
        using Base::swap;

        iterator upper_bound(Key const &key);
        const_iterator upper_bound(Key const &key) const;

    private:
        value_type *findPtr(Key const &key) const;
};

#include "count.f"
#include "equalrange1.f"
#include "erase1.f"
#include "erase2.f"
#include "erase3.f"
#include "find1.f"
#include "find2.f"
#include "findptr.f"
#include "insert1.f"
#include "insert2.f"
#include "insert3.f"
#include "linearmap1.f"
#include "linearmap2.f"
#include "lowerbound1.f"
#include "lowerbound2.f"
#include "operatorindex.f"
#include "upperbound1.f"
#include "upperbound2.f"

} // FBB
#endif
