12 auto smart_ptr = std::make_unique<int>(0);
14 CHECK(raw_pointer == smart_ptr.get());
15 const auto& smart_ptr_const_ref = smart_ptr;
17 CHECK(raw_pointer2 == smart_ptr_const_ref.get());
22 std::vector<int> v(100);
23 CHECK(v.begin() == *
kblib::range(v.begin(), v.end()).begin());
24 CHECK(v.end() == *
kblib::range(v.begin(), v.end()).end());
26 std::vector<int> r{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
28 CHECK(r.size() == r2.size());
29 CHECK(
std::equal(r.begin(), r.end(), r2.begin()));
60 auto v = std::vector<int>(r);
61 CHECK(v.size() == r.size());
62 CHECK(
std::equal(v.begin(), v.end(), r.begin()));
66 auto v = std::string(r);
67 CHECK(v ==
"abcdefghijklmnopqrstuvwxyz");
68 CHECK(v.size() == r.size());
69 CHECK(
std::equal(v.begin(), v.end(), r.begin()));
75 auto equal = [](
auto r1,
auto r2) {
76 auto r1b = r1.begin();
78 auto r2b = r2.begin();
80 return std::distance(r1b, r1e) == std::distance(r2b, r2e)
84 SECTION(
"equivalency") {
86 auto target10 = std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
87 auto target10m = std::vector<int>{0, -1, -2, -3, -4, -5, -6, -7, -8, -9};
88 auto target10r = std::vector<int>{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
105 SECTION(
"comparisons") {
114 SECTION(
"buildiota equivalency") {
115 auto l = kblib::buildiota<std::list<int>>(10u, 10, -1);
121 std::string str =
"abcdefghijklmnopqrstuvwxyz";
123 for ([[gnu::unused]] std::string::iterator c :
130 for (
auto i :
kblib::range(
static_cast<unsigned char>(255))) {
139 std::vector<int> persistent{0, 1, 1, 2, 3, 5, 8};
142 REQUIRE(&v == &persistent[i]);
145 SECTION(
"non-forwarding lvalue") {
147 REQUIRE(&v == &persistent[i]);
152 REQUIRE(v == persistent[i]);
153 REQUIRE(&v != &persistent[i]);
157 SECTION(
"const lvalue") {
158 const auto& cp = persistent;
160 REQUIRE(&v == &cp[i]);
162 "v must refer to const when the range is const");
165 SECTION(
"const reference") {
167 REQUIRE(&v == &persistent[i]);
170 "v must refer to const when the bound reference is const");
173 SECTION(
"copy from const") {
174 const auto& cp = persistent;
176 REQUIRE(v == persistent[i]);
177 REQUIRE(&v != &persistent[i]);
180 "v must not be const when copied from a const range");
183 SECTION(
"const copy from non-const") {
184# if defined(__clang__)
186# pragma clang diagnostic push
187# pragma clang diagnostic ignored "-Wrange-loop-analysis"
190 REQUIRE(v == persistent[i]);
191 REQUIRE(&v != &persistent[i]);
193 "v must refer to const in a const copy");
195# if defined(__clang__)
196# pragma clang diagnostic pop
200 SECTION(
"iterators") {
203 REQUIRE(&v == &persistent[i]);
206 SECTION(
"mutable iterators") {
207 std::vector<int>
range{0, 1, 2, 3, 4, 5, 6, 7};
212 [](
int v) { return v == 0; }));
214 SECTION(
"reverse iterators") {
215 std::vector<int> reversed{7, 6, 5, 4, 3, 2, 1, 0};
219 REQUIRE(v ==
static_cast<int>(i));
223 REQUIRE(last == reversed.front());
226 SECTION(
"temporary") {
229 REQUIRE(v == persistent[i]);
230 REQUIRE(&v != &persistent[i]);
233 SECTION(
"input iterators") {
234 std::istringstream is{
"0 0 1 1 2 2 3 3 4 4 5 5 6 6"};
236 std::istream_iterator<int>(is), std::istream_iterator<int>())) {
237 REQUIRE(v ==
static_cast<int>(i) / 2);
240 SECTION(
"copied input iterators") {
241 std::istringstream is{
"0 0 1 1 2 2 3 3 4 4 5 5 6 6"};
243 std::istream_iterator<int>())) {
244 REQUIRE(v ==
static_cast<int>(i) / 2);
248 SECTION(
"move-only") {
249 std::vector<std::unique_ptr<int>> ptr_vec(10);
256 int arr[5] = {0, 1, 2, 3, 4};
258 REQUIRE(&arr[i] != &v);
259 REQUIRE(
static_cast<int>(i) == v);
260 REQUIRE(arr[i] == v);
262 REQUIRE(arr[i] != v);
266 SECTION(
"array by ref") {
267 int arr[5] = {0, 1, 2, 3, 4};
269 REQUIRE(&arr[i] == &v);
273 SECTION(
"array by const ref") {
274 int arr[5] = {0, 1, 2, 3, 4};
276 REQUIRE(&arr[i] == &v);
280 SECTION(
"array by forwarding ref") {
281 int arr[5] = {0, 1, 2, 3, 4};
283 REQUIRE(&arr[i] == &v);
289 std::vector<int> persistent{0, 1, 1, 2, 3, 5, 8};
292 REQUIRE(v == persistent[i]);
293 REQUIRE(&v == &persistent[i]);
296 SECTION(
"non-forwarding lvalue") {
298 REQUIRE(&v == &persistent[i]);
303 REQUIRE(v == persistent[i]);
304 REQUIRE(&v != &persistent[i]);
308 SECTION(
"const lvalue") {
309 const auto& cp = persistent;
311 REQUIRE(&v == &cp[i]);
314 typename std::remove_reference<
decltype(v)>::type>::value,
315 "v must refer to const when the range is const");
318 SECTION(
"const reference") {
320 REQUIRE(&v == &persistent[i]);
323 typename std::remove_reference<
decltype(v)>::type>::value,
324 "v must refer to const when the bound reference is const");
327 SECTION(
"copy from const") {
328 const auto& cp = persistent;
330 REQUIRE(v == persistent[i]);
331 REQUIRE(&v != &persistent[i]);
339 SECTION(
"const copy from non-const") {
340# if defined(__clang__)
342# pragma clang diagnostic push
343# pragma clang diagnostic ignored "-Wrange-loop-analysis"
346 REQUIRE(v == persistent[i]);
347 REQUIRE(&v != &persistent[i]);
350 typename std::remove_reference<
decltype(v)>::type>::value,
351 "v must refer to const in a const copy");
353# if defined(__clang__)
354# pragma clang diagnostic pop
358 SECTION(
"iterators") {
361 REQUIRE(&v == &persistent[i]);
364 SECTION(
"mutable iterators") {
365 std::vector<int>
range{0, 1, 2, 3, 4, 5, 6, 7};
370 [](
int v) { return v == 0; }));
372 SECTION(
"reverse iterators") {
373 std::vector<int> reversed{7, 6, 5, 4, 3, 2, 1, 0};
376 REQUIRE(v ==
static_cast<int>(i));
380 SECTION(
"temporary") {
382 REQUIRE(v == persistent[i]);
383 REQUIRE(&v != &persistent[i]);
386 SECTION(
"input iterators") {
387 std::istringstream is{
"0 0 1 1 2 2 3 3 4 4 5 5 6 6"};
389 std::istream_iterator<int>())) {
390 REQUIRE(v ==
static_cast<int>(i) / 2);
393 SECTION(
"copied input iterators") {
394 std::istringstream is{
"0 0 1 1 2 2 3 3 4 4 5 5 6 6"};
396 std::istream_iterator<int>())) {
397 REQUIRE(v ==
static_cast<int>(i) / 2);
401 SECTION(
"move-only") {
402 std::vector<std::unique_ptr<int>> ptr_vec(10);
409 int arr[5] = {0, 1, 2, 3, 4};
411 REQUIRE(
static_cast<int>(i) == v);
415 SECTION(
"array by ref") {
416 int arr[5] = {0, 1, 2, 3, 4};
418 REQUIRE(
static_cast<int>(i) == v);
422 SECTION(
"array by const ref") {
423 int arr[5] = {0, 1, 2, 3, 4};
425 REQUIRE(
static_cast<int>(i) == v);
429 SECTION(
"array by forwarding ref") {
430 int arr[5] = {0, 1, 2, 3, 4};
432 REQUIRE(
static_cast<int>(i) == v);
Provides by-value algorithms which produce containers.
This file provides some iterators, ranges, iterator/range adapters, and operations that can be perfor...
constexpr auto size(const C &c) -> decltype(c.size())
auto magic_enumerate(It begin, EIt end) -> enumerator_t< It, EIt >
Allow access to indexes while using range-based for loops.
constexpr auto to_pointer(P &&p) noexcept -> auto *
Gets a raw pointer out of any smart pointer or iterator you might pass in, without dereferencing it o...
typename std::remove_reference< T >::type remove_reference_t
Abbreviated name for std::remove_reference<T>::type for C++14.
auto cry_enumerate(Range &&range) -> auto
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...
constexpr auto all_of(InputIt begin, InputIt end, UnaryPredicate pred) -> enable_if_t< is_input_iterator< InputIt >::value, bool >
Determine if pred is true for every element of the range.
constexpr auto equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) -> bool
A struct which decrements anything it is added to. Suitable for use as a Delta type for range_t.
A struct which increments anything it is added to. Suitable for use as a Delta type for range_t.