#pragma once #include "dtcore/inc/dtcontainer.h" #include "dtcore/inc/dtvector.h" #include "dtcore/inc/dterror.h" #pragma warning(push) #include #include #pragma warning(pop) namespace dt { template , class ALLOCATOR = StdContainerAllocator>> class Map : private std::map { public: typedef typename std::map 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 MyPair; Map() = default; Map(const Map& rhs) : MyBase::map(rhs) {} Map(Map&& rhs) : MyBase::map(rhs) {} Map(const std::initializer_list& 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 GetKeys() const; void Merge(const Map& rhs); void Swap(Map& rhs) { MyBase::swap(rhs); } std::pair 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(MyBase::size()); } bool Empty() const { return MyBase::empty(); } }; template inline const VALUE& Map::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 inline VALUE& Map::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 inline Vector Map::GetKeys() const { Vector result; result.Reserve(Size()); for (const auto& v : *this) { result.PushBack(v.first); } return result; } template inline void Map::Merge(const Map& rhs) { for (const auto& v : rhs) { InsertOrAssign(v.first, v.second); } } template inline std::pair::Iterator, bool> Map::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 inline typename Map::Iterator Map::Erase(const ConstIterator& rhs) { return rhs == End() ? End() : MyBase::erase(rhs); } }