diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/kstd/bits/concepts.hpp | 6 | ||||
| -rw-r--r-- | libs/kstd/kstd/flat_map.hpp | 16 | ||||
| -rw-r--r-- | libs/kstd/kstd/flat_map.tests.cpp | 67 |
3 files changed, 88 insertions, 1 deletions
diff --git a/libs/kstd/kstd/bits/concepts.hpp b/libs/kstd/kstd/bits/concepts.hpp index f43f4f55..065b6f07 100644 --- a/libs/kstd/kstd/bits/concepts.hpp +++ b/libs/kstd/kstd/bits/concepts.hpp @@ -17,6 +17,12 @@ namespace kstd::bits lockable.unlock(); }; + template<typename SuspectType> + concept allocator_like = requires(SuspectType & suspect) { + typename SuspectType::value_type; + suspect.deallocate(suspect.allocate(1), 1); + }; + } // namespace kstd::bits #endif diff --git a/libs/kstd/kstd/flat_map.hpp b/libs/kstd/kstd/flat_map.hpp index b9b05366..3eda42d8 100644 --- a/libs/kstd/kstd/flat_map.hpp +++ b/libs/kstd/kstd/flat_map.hpp @@ -1,6 +1,7 @@ #ifndef KSTD_FLAT_MAP_HPP #define KSTD_FLAT_MAP_HPP +#include <kstd/bits/concepts.hpp> #include <kstd/os/error.hpp> #include <kstd/vector.hpp> @@ -912,10 +913,25 @@ namespace kstd template<typename KeyContainer, typename MappedContainer, typename Compare = std::less<typename KeyContainer::value_type>> + requires(!bits::allocator_like<Compare>) flat_map(KeyContainer, MappedContainer, Compare = Compare{}) -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type, Compare, KeyContainer, MappedContainer>; + template<typename KeyContainer, typename MappedContainer, typename Allocator> + requires(std::uses_allocator_v<KeyContainer, Allocator> && std::uses_allocator_v<MappedContainer, Allocator>) + flat_map(KeyContainer, MappedContainer, Allocator) + -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type, + std::less<typename KeyContainer::value_type>, // NOLINT(modernize-use-transparent-functors) + KeyContainer, MappedContainer>; + + template<typename KeyContainer, typename MappedContainer, typename Compare, typename Allocator> + requires(!bits::allocator_like<Compare> && std::uses_allocator_v<KeyContainer, Allocator> && + std::uses_allocator_v<MappedContainer, Allocator>) + flat_map(KeyContainer, MappedContainer, Compare, Allocator) + -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type, Compare, KeyContainer, + MappedContainer>; + } // namespace kstd #endif
\ No newline at end of file diff --git a/libs/kstd/kstd/flat_map.tests.cpp b/libs/kstd/kstd/flat_map.tests.cpp index f3384b90..32dbafb2 100644 --- a/libs/kstd/kstd/flat_map.tests.cpp +++ b/libs/kstd/kstd/flat_map.tests.cpp @@ -9,6 +9,7 @@ #include <functional> #include <string> #include <type_traits> +#include <utility> SCENARIO("Flat Map initialization and construction", "[flat_map]") { @@ -46,11 +47,35 @@ SCENARIO("Flat Map initialization and construction", "[flat_map]") { auto copy = kstd::flat_map<int, int>{map, kstd::allocator<int>{}}; - THEN("the map compare equal") + THEN("the maps compare equal") { REQUIRE(map == copy); } } + + WHEN("contstructing by move using an allocator") + { + auto moved = kstd::flat_map<int, int>{std::move(map), kstd::allocator<int>{}}; + + THEN("the moved from map is empty") + { + REQUIRE(map.empty()); + } + + THEN("the moved to map contains all elements") + { + REQUIRE(moved.contains(1)); + REQUIRE(moved.contains(2)); + REQUIRE(moved.contains(3)); + } + + THEN("the moved to map has the correct values for each element") + { + REQUIRE(moved.at(1) == 10); + REQUIRE(moved.at(2) == 20); + REQUIRE(moved.at(3) == 30); + } + } } GIVEN("An unsorted key container and an unsorted value container") @@ -79,6 +104,46 @@ SCENARIO("Flat Map initialization and construction", "[flat_map]") REQUIRE(map.at(5) == 'f'); } } + + WHEN("constructing using the containers and an allocator") + { + auto map = kstd::flat_map{keys, values, kstd::allocator<int>{}}; + + THEN("the flat map has size 6") + { + REQUIRE(map.size() == 6); + } + + THEN("the flat map contains all pairs in order") + { + REQUIRE(map.at(0) == 'a'); + REQUIRE(map.at(1) == 'b'); + REQUIRE(map.at(2) == 'c'); + REQUIRE(map.at(3) == 'd'); + REQUIRE(map.at(4) == 'e'); + REQUIRE(map.at(5) == 'f'); + } + } + + WHEN("constructing using the containers and an allocator and a comparator") + { + auto map = kstd::flat_map{keys, values, std::less<>{}, kstd::allocator<int>{}}; + + THEN("the flat map has size 6") + { + REQUIRE(map.size() == 6); + } + + THEN("the flat map contains all pairs in order") + { + REQUIRE(map.at(0) == 'a'); + REQUIRE(map.at(1) == 'b'); + REQUIRE(map.at(2) == 'c'); + REQUIRE(map.at(3) == 'd'); + REQUIRE(map.at(4) == 'e'); + REQUIRE(map.at(5) == 'f'); + } + } } GIVEN("An unsorted key container and an unsorted value container, with duplicate keys") |
