diff --git a/alib2std/src/extensions/map.hpp b/alib2std/src/extensions/map.hpp index 173c3de12be933f2345598798487dad2bed9dae5..e0b905e4a7c96bab5f20f67c6c1438d5284536b0 100644 --- a/alib2std/src/extensions/map.hpp +++ b/alib2std/src/extensions/map.hpp @@ -42,6 +42,23 @@ public: using std::map < T, R, Cmp, Alloc >::operator =; #endif + using iterator = typename std::map<T, R, Cmp, Alloc>::iterator; + using key_type = typename std::map<T, R, Cmp, Alloc>::key_type; + + // Follow interface from C++17 + // TODO: Remove this member function after move to C++17 + template < typename M > + pair < iterator, bool > insert_or_assign ( const key_type & k, M && obj ) { + iterator pos = this->find ( k ); + if ( pos == this->end ( ) ) { + pos = this->insert ( ext::make_pair ( k, std::forward < M > ( obj ) ) ).first; + return ext::make_pair ( pos, true ); + } else { + pos->second = std::forward < M > ( obj ); + return ext::make_pair ( pos, false ); + } + } + }; template< class T, class R, class ... Ts > diff --git a/alib2std/test-src/extensions/MapTest.cpp b/alib2std/test-src/extensions/MapTest.cpp index c13f5cff4c966c7cb4f47efff07181ffaa91c3aa..05fcb83615aa782f79eb5d720797baad89994aad 100644 --- a/alib2std/test-src/extensions/MapTest.cpp +++ b/alib2std/test-src/extensions/MapTest.cpp @@ -23,6 +23,10 @@ void MapTest::test3() { map2.insert(std::move(moveablePair)); } + bool res = map2.insert_or_assign ( MapTest::Moveable ( moves, copies ), MapTest::Moveable ( moves, copies ) ).second; + + CPPUNIT_ASSERT ( res == false ); + CPPUNIT_ASSERT(copies == 0); } diff --git a/alib2std/test-src/extensions/MapTest.h b/alib2std/test-src/extensions/MapTest.h index 708fc3411165a10842968af10e837569e6ffeb20..a43132aeccc0b06d08395edb9c78f5d1c97cb5ed 100644 --- a/alib2std/test-src/extensions/MapTest.h +++ b/alib2std/test-src/extensions/MapTest.h @@ -28,6 +28,16 @@ public: m_moves++; } + Moveable & operator = ( const Moveable & ) { + m_copies ++; + return * this; + } + + Moveable & operator = ( Moveable && ) { + m_moves ++; + return * this; + } + bool operator<(const Moveable&) const { return false; }