kblib 0.2.3
General utilities library for modern C++
containers.cpp
Go to the documentation of this file.
1#include "kblib/containers.h"
2#include "catch.hpp"
3#include "kblib/algorithm.h"
4
5#include <iostream>
6#include <map>
7
8TEST_CASE("try_get") {
9 std::map<int, int> m;
10 const auto& cm = m;
11
12 // m[0] doesn't exist
13 REQUIRE(kblib::try_get(m, 0) == nullptr);
14 // Works for const maps
15 REQUIRE(kblib::try_get(cm, 0) == nullptr);
16 // Make m[0]
17 m[0] = 0;
18
19 // Basic correctness testing
20 REQUIRE(kblib::try_get(m, 0) == &m[0]);
21 *kblib::try_get(m, 0) = 1;
22 REQUIRE(m[0] == 1);
23
24 // Returns pointer to const when given const map
25 //*kblib::try_get(cm, 0) = 1;
26
27 // Can't call for temporaries because it would return a dangling pointer
28 // kblib::try_get(std::map<int, int>{{0, 1}}, 0);
29}
30
31TEST_CASE("build_iterator", "[build]") {
32 using arr = std::array<int, 8>;
33 const arr input = {2, 3, 5, 7, 11, 13, 17, 19};
34 const arr input2 = {1, 1, 1, 1, 1, 1, 1, 1};
35 const auto unary_f = [](int x) { return x * x; };
36 const auto binary_f = [](int a, int b) { return a - b; };
37 const arr squared = {4, 9, 25, 49, 121, 169, 289, 361};
38 const arr pminusone = {1, 2, 4, 6, 10, 12, 16, 18};
39
40 const auto equal = [](auto a, auto b) {
41 return std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b));
42 };
43 [[gnu::unused]] auto print_arr = [&](auto c) {
44 for (const auto& v : c) {
45 std::cout << v << ", ";
46 }
47 std::cout << '\n';
48 };
49
50 SECTION("unary dynamic build") {
51 // auto built = kblib::build<std::vector<int>>(input.begin(), input.end(),
52 // unary_f);
53 auto built
54 = std::transform(input.begin(), input.end(),
55 kblib::build_iterator<std::vector<int>>{}, unary_f)
56 .base();
57 REQUIRE(equal(squared, built));
58 }
59 SECTION("binary dynamic build") {
60 // auto built = kblib::build<std::vector<int>>(input.begin(), input.end(),
61 // input2.begin(), binary_f);
62 auto built
63 = std::transform(input.begin(), input.end(), input2.begin(),
64 kblib::build_iterator<std::vector<int>>{}, binary_f)
65 .base();
66 REQUIRE(equal(pminusone, built));
67 }
68 SECTION("unary array build") {
69 // auto built = kblib::build<arr>(input.begin(), input.end(), unary_f);
70 auto built = std::transform(input.begin(), input.end(),
72 .base();
73 REQUIRE(equal(squared, built));
74 }
75 SECTION("binary array build") {
76 // auto built = kblib::build<arr>(input.begin(), input.end(),
77 // input2.begin(), binary_f);
78 auto built = std::transform(input.begin(), input.end(), input2.begin(),
80 .base();
81 REQUIRE(equal(pminusone, built));
82 }
83 const arr iota = {0, 1, 2, 3, 4, 5, 6, 7};
84 SECTION("dynamic generator build") {
85 // auto built = kblib::build<std::vector<int>>([x = 0]() mutable { return
86 // x++; }, 8);
87 auto built = std::generate_n(kblib::build_iterator<std::vector<int>>{}, 8,
88 [x = 0]() mutable { return x++; })
89 .base();
90 REQUIRE(equal(iota, built));
91 }
92 SECTION("array generator build") {
93 // auto built = kblib::build<arr>([x = 0]() mutable { return x++; });
94 auto built
96 [x = 0]() mutable { return x++; })
97 .base();
98 // Using only the standard library, it would have to be this in order to
99 // avoid a magic number for the size.
100 // auto built = std::generate_n(kblib::build_iterator<arr>{},
101 // std::tuple_size<arr>::value,
102 // [x = 0]() mutable { return x++; })
103 // .base();
104 REQUIRE(equal(iota, built));
105 }
106 // std::iota returns void, not the iterator
107 SECTION("dynamic buildiota") {
108 // auto built = kblib::buildiota<std::vector<int>>(8, 0);
109 // auto built = ...
110 auto built
111 = kblib::construct_from_range<std::vector<int>>(kblib::range(0, 8));
112 REQUIRE(equal(iota, built));
113 }
114 SECTION("array buildiota") {
115 // auto built = kblib::buildiota<arr>(0);
116 // auto built = ...
117 // REQUIRE(equal(iota, built));
118 }
119}
120
121TEST_CASE("build_iterator is nodiscard") {
122 using arr = std::array<int, 8>;
123 KBLIB_UNUSED const arr input = {2, 3, 5, 7, 11, 13, 17, 19};
124
125 // This line correctly generates a warning that the return value is ignored.
126 // std::copy(input.begin(), input.end(), kblib::build_iterator<arr>{});
127}
Provides general-purpose algorithms, similar to the <algorithms> header.
TEST_CASE("try_get")
Definition: containers.cpp:8
Provides generic operations for containers, as well as kblib::stack.
constexpr auto a(const std::initializer_list< T > &a) -> auto
Index an array literal without naming its type.
Definition: simple.h:255
constexpr auto generate(OutputIt first, EndIt last, Generator g) noexcept(noexcept(*++first=g())) -> OutputIt
Like std::generate except that it returns the output iterator at the end. It also allows for a sentin...
Definition: algorithm.h:1545
constexpr auto iota(ForwardIt first, ForwardIt last, T value) noexcept(noexcept(*first++=value) and noexcept(++value)) -> void
Definition: algorithm.h:1575
constexpr auto generate_n(OutputIt first, Size count, Generator g) noexcept(noexcept(*first++=g())) -> OutputIt
Like std::generate_n except that it is constexpr.
Definition: algorithm.h:1565
constexpr auto range(Value min, Value max, Delta step=0) -> range_t< Value, Delta >
Constructs a range from beginning, end, and step amount. The range is half-open, that is min is in th...
Definition: iterators.h:621
constexpr struct kblib::build_end_t build_end
constexpr auto try_get(Map &map, Key &&key) -> copy_const_t< Map, typename Map::mapped_type > *
Definition: containers.h:67
constexpr auto equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) -> bool
Definition: fakestd.h:966
constexpr auto transform(InputIt first, EndIt last, OutputIt d_first, UnaryOperation unary_op) -> OutputIt
transform applies the given function to a range and stores the result in another range,...
Definition: algorithm.h:1632
#define KBLIB_UNUSED
This internal macro is used to provide a fallback for [[maybe_unused]] in C++14.
Definition: tdecl.h:130