131 lines
4.6 KiB
C++
131 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include "dtcore/inc/dtcontainer.h"
|
|
#include "dtcore/inc/dtvector.h"
|
|
#include "dtcore/inc/dterror.h"
|
|
|
|
#pragma warning(push)
|
|
#include <map>
|
|
#include <iterator>
|
|
#pragma warning(pop)
|
|
|
|
|
|
namespace dt
|
|
{
|
|
|
|
template <class KEY, class VALUE, class LESS = std::less<KEY>,
|
|
class ALLOCATOR = StdContainerAllocator<std::pair<const KEY, VALUE>>> class Map
|
|
: private std::map<KEY, VALUE, LESS, ALLOCATOR>
|
|
{
|
|
public:
|
|
typedef typename std::map<KEY, VALUE, LESS, ALLOCATOR> MyBase;
|
|
typedef typename MyBase::reference Reference;
|
|
typedef typename MyBase::const_reference ConstReference;
|
|
typedef typename MyBase::iterator Iterator;
|
|
typedef typename MyBase::const_iterator ConstIterator;
|
|
typedef typename MyBase::reverse_iterator ReverseIterator;
|
|
typedef typename MyBase::const_reverse_iterator ConstReverseIterator;
|
|
typedef typename std::pair<const KEY, VALUE> MyPair;
|
|
|
|
Map() = default;
|
|
Map(const Map& rhs) : MyBase::map(rhs) {}
|
|
Map(Map&& rhs) : MyBase::map(rhs) {}
|
|
Map(const std::initializer_list<MyPair>& rhs) : MyBase::map(rhs) {}
|
|
Map& operator=(const Map& rhs) { MyBase::operator =(rhs); return *this; }
|
|
Map& operator=(Map&& rhs) { MyBase::operator =(rhs); return *this; }
|
|
|
|
bool operator==(const Map& rhs) const { return std::operator==(*this, rhs); }
|
|
bool operator!=(const Map& rhs) const { return std::operator!=(*this, rhs); }
|
|
|
|
const VALUE& operator[](const KEY& key) const;
|
|
VALUE& operator[](const KEY& key);
|
|
|
|
Vector<KEY> GetKeys() const;
|
|
|
|
void Merge(const Map& rhs);
|
|
void Swap(Map& rhs) { MyBase::swap(rhs); }
|
|
|
|
std::pair<Iterator, bool> InsertOrAssign(const KEY& key, const VALUE& value);
|
|
ConstIterator Find(const KEY& key) const { return MyBase::find(key); }
|
|
Iterator Find(const KEY& key) { return MyBase::find(key); }
|
|
|
|
Iterator Erase(const ConstIterator& rhs);
|
|
void Clear() { MyBase::clear(); }
|
|
|
|
Iterator Begin() { return MyBase::begin(); }
|
|
ConstIterator Begin() const { return MyBase::begin(); }
|
|
Iterator begin() { return MyBase::begin(); }
|
|
ConstIterator begin() const { return MyBase::begin(); }
|
|
|
|
Iterator End() { return MyBase::end(); }
|
|
ConstIterator End() const { return MyBase::end(); }
|
|
Iterator end() { return MyBase::end(); }
|
|
ConstIterator end() const { return MyBase::end(); }
|
|
|
|
SizeT Size() const { return static_cast<SizeT>(MyBase::size()); }
|
|
bool Empty() const { return MyBase::empty(); }
|
|
|
|
};
|
|
|
|
template <class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
const VALUE& Map<KEY, VALUE, LESS, ALLOCATOR>::operator[](const KEY& key) const
|
|
{
|
|
// don't convert to the built in operator[], it is not equivalent
|
|
// the default operator[] will create the key with a default value
|
|
// if it does not exists.
|
|
auto i = MyBase::find(key);
|
|
DT_ASSERT(i != end());
|
|
return i->second;
|
|
}
|
|
|
|
template <class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
VALUE& Map<KEY, VALUE, LESS, ALLOCATOR>::operator[](const KEY& key)
|
|
{
|
|
// see comment for the const version of operator[]
|
|
auto i = MyBase::find(key);
|
|
DT_ASSERT(i != end());
|
|
return i->second;
|
|
}
|
|
|
|
template <class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
Vector<KEY> Map<KEY, VALUE, LESS, ALLOCATOR>::GetKeys() const
|
|
{
|
|
Vector<KEY> result;
|
|
result.Reserve(Size());
|
|
for (const auto& v : *this)
|
|
{
|
|
result.PushBack(v.first);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template <class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
void Map<KEY, VALUE, LESS, ALLOCATOR>::Merge(const Map& rhs)
|
|
{
|
|
for (const auto& v : rhs)
|
|
{
|
|
InsertOrAssign(v.first, v.second);
|
|
}
|
|
}
|
|
|
|
template<class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
std::pair<typename Map<KEY, VALUE, LESS, ALLOCATOR>::Iterator, bool>
|
|
Map<KEY, VALUE, LESS, ALLOCATOR>::InsertOrAssign(const KEY& key, const VALUE& value)
|
|
{
|
|
// this is the equivalent of insert_or_assign in C++17
|
|
auto result = MyBase::insert(MyPair(key, value));
|
|
if (!result.second)
|
|
{
|
|
result.first->second = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template<class KEY, class VALUE, class LESS, class ALLOCATOR> inline
|
|
typename Map<KEY, VALUE, LESS, ALLOCATOR>::Iterator Map<KEY, VALUE, LESS, ALLOCATOR>::Erase(const ConstIterator& rhs)
|
|
{
|
|
return rhs == End() ? End() : MyBase::erase(rhs);
|
|
}
|
|
|
|
}
|
|
|