diff --git a/include/tsl/ordered_hash.h b/include/tsl/ordered_hash.h index 614ec94..8ab7798 100644 --- a/include/tsl/ordered_hash.h +++ b/include/tsl/ordered_hash.h @@ -288,7 +288,7 @@ class bucket_entry { */ template + class IndexType, class ValueTypeIt> class ordered_hash : private Hash, private KeyEqual { private: template @@ -334,6 +334,12 @@ class ordered_hash : private Hash, private KeyEqual { using values_container_type = ValueTypeContainer; + using value_type_it = ValueTypeIt; + using reference_it = value_type_it&; + using const_reference_it = const value_type_it&; + using pointer_it = value_type_it*; + using const_pointer_it = const value_type_it*; + public: template class ordered_iterator { @@ -348,10 +354,16 @@ class ordered_hash : private Hash, private KeyEqual { public: using iterator_category = std::random_access_iterator_tag; - using value_type = const typename ordered_hash::value_type; + using value_type = typename ordered_hash::value_type_it; using difference_type = typename iterator::difference_type; - using reference = value_type&; - using pointer = value_type*; + using reference = + typename std::conditional::type; + using pointer = + typename std::conditional::type; ordered_iterator() noexcept {} @@ -384,8 +396,12 @@ class ordered_hash : private Hash, private KeyEqual { return U()(*m_iterator); } - reference operator*() const { return *m_iterator; } - pointer operator->() const { return m_iterator.operator->(); } + reference operator*() const { + return reinterpret_cast(*m_iterator); + } + pointer operator->() const { + return reinterpret_cast(std::addressof(*m_iterator)); + } ordered_iterator& operator++() { ++m_iterator; @@ -407,7 +423,9 @@ class ordered_hash : private Hash, private KeyEqual { return tmp; } - reference operator[](difference_type n) const { return m_iterator[n]; } + reference operator[](difference_type n) const { + return reinterpret_cast(m_iterator[n]); + } ordered_iterator& operator+=(difference_type n) { m_iterator += n; diff --git a/include/tsl/ordered_map.h b/include/tsl/ordered_map.h index 8350075..2a41125 100644 --- a/include/tsl/ordered_map.h +++ b/include/tsl/ordered_map.h @@ -95,6 +95,15 @@ class ordered_map { key_type& operator()(std::pair& key_value) noexcept { return key_value.first; } + + const key_type& operator()( + const std::pair& key_value) const noexcept { + return key_value.first; + } + + const key_type& operator()(std::pair& key_value) noexcept { + return key_value.first; + } }; class ValueSelect { @@ -111,10 +120,9 @@ class ordered_map { } }; - using ht = - detail_ordered_hash::ordered_hash, KeySelect, - ValueSelect, Hash, KeyEqual, Allocator, - ValueTypeContainer, IndexType>; + using ht = detail_ordered_hash::ordered_hash< + std::pair, KeySelect, ValueSelect, Hash, KeyEqual, Allocator, + ValueTypeContainer, IndexType, std::pair>; public: using key_type = typename ht::key_type; @@ -409,7 +417,7 @@ class ordered_map { * It can still be cleared and destroyed without leaking memory. */ template - friend size_type erase_if(ordered_map &map, Predicate pred) { + friend size_type erase_if(ordered_map& map, Predicate pred) { return map.m_ht.erase_if(pred); } @@ -991,6 +999,11 @@ class ordered_map { ht m_ht; }; +template > +using vector_map = tsl::ordered_map, std::equal_to, + std::allocator>, + std::vector>>; + } // end namespace tsl #endif diff --git a/include/tsl/ordered_set.h b/include/tsl/ordered_set.h index a25f255..7465bfa 100644 --- a/include/tsl/ordered_set.h +++ b/include/tsl/ordered_set.h @@ -92,9 +92,10 @@ class ordered_set { key_type& operator()(Key& key) noexcept { return key; } }; - using ht = detail_ordered_hash::ordered_hash; + using ht = + detail_ordered_hash::ordered_hash; public: using key_type = typename ht::key_type; @@ -334,7 +335,7 @@ class ordered_set { * It can still be cleared and destroyed without leaking memory. */ template - friend size_type erase_if(ordered_set &set, Predicate pred) { + friend size_type erase_if(ordered_set& set, Predicate pred) { return set.m_ht.erase_if(pred); } @@ -826,6 +827,10 @@ class ordered_set { ht m_ht; }; +template > +using vector_set = tsl::ordered_set, std::equal_to, + std::allocator, std::vector>; + } // end namespace tsl #endif diff --git a/tests/ordered_map_tests.cpp b/tests/ordered_map_tests.cpp index 405fcf5..1040d1a 100644 --- a/tests/ordered_map_tests.cpp +++ b/tests/ordered_map_tests.cpp @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(test_insert_at_position) { {"Key12", 12}})); auto it = map.insert_at_position(map.nth(2), {"Key3", 3}); - BOOST_CHECK(*it.first == (std::pair("Key3", 3))); + BOOST_CHECK(*it.first == (std::pair("Key3", 3))); BOOST_CHECK(it.second); BOOST_CHECK(utils::test_is_equal( map, tsl::ordered_map{{"Key1", 1}, @@ -413,7 +413,7 @@ BOOST_AUTO_TEST_CASE(test_insert_at_position) { {"Key7", 7}})); it = map.insert_at_position(map.nth(3), {"Key8", 8}); - BOOST_CHECK(*it.first == (std::pair("Key8", 8))); + BOOST_CHECK(*it.first == (std::pair("Key8", 8))); BOOST_CHECK(!it.second); BOOST_CHECK(utils::test_is_equal( map, tsl::ordered_map{{"Key1", 1}, @@ -436,7 +436,7 @@ BOOST_AUTO_TEST_CASE(test_insert_at_position_high_collisions) { map.insert({{0, 0}, {32, -32}, {64, -64}, {96, -96}, {128, -128}}); auto it = map.insert_at_position(map.begin(), {160, -160}); - BOOST_CHECK(*it.first == (std::pair(160, -160))); + BOOST_CHECK(*it.first == (std::pair(160, -160))); BOOST_CHECK(it.second); BOOST_CHECK(utils::test_is_equal( map, @@ -465,7 +465,7 @@ BOOST_AUTO_TEST_CASE(test_try_emplace_at_position) { {"Key12", 12}})); auto it = map.try_emplace_at_position(map.nth(2), "Key3", 3); - BOOST_CHECK(*it.first == (std::pair("Key3", 3))); + BOOST_CHECK(*it.first == (std::pair("Key3", 3))); BOOST_CHECK(it.second); BOOST_CHECK(utils::test_is_equal( map, tsl::ordered_map{{"Key1", 1}, @@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(test_try_emplace_at_position) { {"Key7", 7}})); it = map.try_emplace_at_position(map.nth(3), "Key8", 8); - BOOST_CHECK(*it.first == (std::pair("Key8", 8))); + BOOST_CHECK(*it.first == (std::pair("Key8", 8))); BOOST_CHECK(!it.second); BOOST_CHECK(utils::test_is_equal( map, tsl::ordered_map{{"Key1", 1}, @@ -567,7 +567,7 @@ BOOST_AUTO_TEST_CASE(test_range_erase) { if (i >= 10 && i < 220) { continue; } - BOOST_CHECK(*it == (std::pair( + BOOST_CHECK(*it == (std::pair( utils::get_key(i), utils::get_value(i)))); ++it; @@ -1457,13 +1457,13 @@ BOOST_AUTO_TEST_CASE(test_nth) { map.insert({0, 0}); BOOST_REQUIRE(map.nth(0) != map.end()); - BOOST_CHECK(*map.nth(0) == (std::pair(1, 10))); + BOOST_CHECK(*map.nth(0) == (std::pair(1, 10))); BOOST_REQUIRE(map.nth(1) != map.end()); - BOOST_CHECK(*map.nth(1) == (std::pair(2, 20))); + BOOST_CHECK(*map.nth(1) == (std::pair(2, 20))); BOOST_REQUIRE(map.nth(2) != map.end()); - BOOST_CHECK(*map.nth(2) == (std::pair(0, 0))); + BOOST_CHECK(*map.nth(2) == (std::pair(0, 0))); BOOST_REQUIRE(map.nth(3) == map.end());