RelocatableMap.h

// RelocatableMap.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2013

#pragma once
#ifndef Ceda_cxUtils_RelocatableMap_H
#define Ceda_cxUtils_RelocatableMap_H

#include "Archive.h"
#include <algorithm>
#include <utility>

namespace ceda
{

template<typename M>
class RelocatableMap
{
public:
    using map = M;
    using key_type = typename map::key_type;
    using mapped_type = typename map::mapped_type;
    using value_type = typename map::value_type;

    using key_compare = typename map::key_compare;
    using value_compare = typename map::value_compare;

    using allocator_type = typename map::allocator_type;
    using reference = typename map::reference;
    using const_reference = typename map::const_reference;
    using pointer = typename map::pointer;
    using const_pointer = typename map::const_pointer;
    
    using iterator = typename map::iterator;
    using const_iterator = typename map::const_iterator;
    using reverse_iterator = typename map::reverse_iterator;
    using const_reverse_iterator = typename map::const_reverse_iterator;
    
    using difference_type = typename map::difference_type;
    using size_type = typename map::size_type;

    RelocatableMap()
    {
        m_map = new map;
    }
    ~RelocatableMap()
    {
        delete m_map;
    }
    RelocatableMap(const RelocatableMap& rhs) :
        m_map(new map(*rhs.m_map))
    {
    }
    RelocatableMap(const map& rhs) :
        m_map(new map(rhs))
    {
    }
    RelocatableMap& operator=(const RelocatableMap& rhs)
    {
        map* temp = new map(*rhs.m_map);
        delete m_map;
        m_map = temp;
        return *this;
    }
    RelocatableMap& operator=(const map& rhs)
    {
        map* temp = new map(rhs);
        delete m_map;
        m_map = temp;
        return *this;
    }
    void swap(RelocatableMap& rhs)
    {
        using std::swap;
        swap(m_map, rhs.m_map);
    }
    void swap(map& rhs)
    {
        using std::swap;
        swap(*m_map, rhs);
    }
    
    iterator begin()
    {
        return m_map->begin();
    }
    const_iterator begin() const
    {
        return m_map->begin();
    }
    iterator end()
    {
        return m_map->end();
    }
    const_iterator end() const
    {
        return m_map->end();
    }
    reverse_iterator rbegin()
    {
        return m_map->rbegin();
    }
    const_reverse_iterator rbegin() const
    {
        return m_map->rbegin();
    }
    reverse_iterator rend()
    {
        return m_map->rend();
    }
    const_reverse_iterator rend() const
    {
        return m_map->rend();
    }
    
    size_type size() const
    {
        return m_map->size();
    }
    size_type max_size() const
    {
        return m_map->max_size();
    }
    size_type count(const key_type& k) const
    {
        return m_map->count(k);
    }
    bool empty() const
    {
        return m_map->empty();
    }
    allocator_type get_allocator() const
    {
        return m_map->get_allocator();
    }
    
    /*
    mapped_type& at(const key_type& k)
    {
        return m_map->at(k);
    }
    const mapped_type& at(const key_type& k) const
    {
        return m_map->at(k);
    }
    */
    mapped_type& operator[](const key_type& k)
    {
        return m_map->operator[](k);
    }

    iterator lower_bound(const key_type& k)
    {
        return m_map->lower_bound(k);
    }
    const_iterator lower_bound(const key_type& k) const
    {
        return m_map->lower_bound(k);
    }
    iterator upper_bound(const key_type& k)
    {
        return m_map->upper_bound(k);
    }
    const_iterator upper_bound(const key_type& k) const
    {
        return m_map->upper_bound(k);
    }
    std::pair<const_iterator,const_iterator> equal_range(const key_type& k) const
    {
        return m_map->equal_range(k);
    }
    std::pair<iterator,iterator> equal_range(const key_type& k)
    {
        return m_map->equal_range(k);
    }

    iterator find(const key_type& k)
    {
        return m_map->find(k);
    }
    const_iterator find(const key_type& k) const
    {
        return m_map->find(k);
    }

    value_compare value_comp() const
    {
        return m_map->value_comp();
    }

    key_compare key_comp() const
    {
        return m_map->key_comp();
    }

    void clear()
    {
        m_map->clear();
    }

    void erase(iterator position)
    {
        m_map->erase(position);
    }
    size_type erase(const key_type& k)
    {
        return m_map->erase(k);
    }
    void erase(iterator first, iterator last)
    {
        m_map->erase(first,last);
    }
     
    std::pair<iterator,bool> insert(const value_type& val)
    {
        return m_map->insert(val);
    }
    iterator insert(iterator position, const value_type& val)
    {
        return m_map->insert(position,val);
    }
    template <typename InputIterator>
    void insert(InputIterator first, InputIterator last)
    {
        m_map->insert(first,last);
    }
    
    map& getmap() { return *m_map; }
    const map& getmap() const { return *m_map; }

private:
    map* m_map;
};

template <typename M>
bool operator==(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() == rhs.getmap();
}
template <typename M>
bool operator!=(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() != rhs.getmap();
}
template <typename M>
bool operator<(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() < rhs.getmap();
}
template <typename M>
bool operator<=(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() <= rhs.getmap();
}
template <typename M>
bool operator>(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() > rhs.getmap();
}
template <typename M>
bool operator>=(const RelocatableMap<M>& lhs,const RelocatableMap<M>& rhs)
{
    return lhs.getmap() >= rhs.getmap();
}

class xostream;
class Archive;
class InputArchive;

template <typename M>
inline xostream& operator<<(xostream& os, const RelocatableMap<M>& x)
{
	os << x.getmap();
	return os;
}

template <typename Archive, typename M>
inline void Serialise(Archive& ar, const RelocatableMap<M>& x)
{
	ar << x.getmap();
}

template <typename Archive, typename M>
inline void Deserialise(Archive& ar, RelocatableMap<M>& x)
{
	ar >> x.getmap();
}

} // namespace ceda

#endif // include guard