Skip to content

Commit 6e5af9f

Browse files
committed
[feature] add radr::all for compatibility
1 parent d8ac7e4 commit 6e5af9f

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

include/radr/rad/all.hpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Copyright (c) 2023-2025 Hannes Hauswedell
5+
//
6+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
7+
// See the LICENSE file for details.
8+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#pragma once
13+
14+
#include "radr/custom/subborrow.hpp"
15+
#include "radr/detail/pipe.hpp"
16+
#include "radr/rad/to_single_pass.hpp"
17+
18+
namespace radr
19+
{
20+
21+
inline namespace cpo
22+
{
23+
/*!\brief A NOOP range adaptor provided for compatibility.
24+
* \param urange The underlying range.
25+
*
26+
* This range adaptor is semantically a NOOP, i.e. the returned range has the same elements
27+
* and generally satisfies the same concepts. However, the actual range type will be different
28+
* (and may be customised).
29+
*
30+
* ### Multi-pass adaptor
31+
*
32+
* Requirements:
33+
* * `radr::mp_range<URange>`
34+
*
35+
* Calls radr::borrow on \p urange which may result in a customised range type being returned.
36+
*
37+
* Unless customised otherwise, preserves all range concepts and is transparant (preserves iterator and
38+
* sentinel types).
39+
*
40+
* ### Single-pass adaptor
41+
*
42+
* Requirements:
43+
* * `std::ranges::input_range<URange>`
44+
*
45+
* Returns the range as-is.
46+
*/
47+
#ifndef RADR_ALL_NO_DEPRECATED
48+
[[deprecated(
49+
"radr::all is provided as a (mostly) NOOP adaptor. You probably want radr::borrow instead.\n"
50+
"You can silence this warning by defining RADR_ALL_NO_DEPRECATED.")]]
51+
#endif
52+
inline constexpr auto all = detail::pipe_without_args_fn<decltype(detail::to_single_pass_coro), decltype(borrow)>{};
53+
} // namespace cpo
54+
} // namespace radr

tests/unit/rad/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
radr_unit_test(all_)
12
radr_unit_test(as_const)
23
radr_unit_test(as_rvalue)
34
radr_unit_test(to_common)

tests/unit/rad/all_.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#include <deque>
2+
#include <forward_list>
3+
#include <list>
4+
#include <ranges>
5+
#include <span>
6+
#include <vector>
7+
8+
#include <gtest/gtest.h>
9+
#include <radr/test/adaptor_template.hpp>
10+
#include <radr/test/aux_ranges.hpp>
11+
#include <radr/test/gtest_helpers.hpp>
12+
13+
#define RADR_ALL_NO_DEPRECATED 1
14+
#include <radr/concepts.hpp>
15+
#include <radr/rad/all.hpp>
16+
#include <radr/range_access.hpp>
17+
18+
// --------------------------------------------------------------------------
19+
// test data
20+
// --------------------------------------------------------------------------
21+
22+
inline std::vector<size_t> const comp{1, 2, 3, 4, 5, 6};
23+
24+
// --------------------------------------------------------------------------
25+
// input test
26+
// --------------------------------------------------------------------------
27+
28+
#if !defined(_GLIBCXX_RELEASE) || (_GLIBCXX_RELEASE >= 12)
29+
TEST(all, input)
30+
{
31+
std::istringstream input("10 20 30 40");
32+
33+
auto rng = std::views::istream<int>(input) | radr::all;
34+
35+
EXPECT_SAME_TYPE(decltype(rng), (std::ranges::basic_istream_view<int, char>));
36+
}
37+
#endif
38+
39+
// --------------------------------------------------------------------------
40+
// forward tests
41+
// --------------------------------------------------------------------------
42+
43+
template <typename _container_t>
44+
struct all_forward : public testing::Test
45+
{
46+
/* data members */
47+
_container_t in{1, 2, 3, 4, 5, 6};
48+
49+
/* type foo */
50+
using container_t = _container_t;
51+
52+
using it_t = decltype(radr::begin(std::declval<container_t &>()));
53+
using sen_t = decltype(radr::end(std::declval<container_t &>()));
54+
using cit_t = decltype(radr::cbegin(std::declval<container_t const &>()));
55+
using csen_t = decltype(radr::cend(std::declval<container_t const &>()));
56+
57+
static constexpr radr::borrowing_rad_kind bk =
58+
std::ranges::sized_range<container_t> ? radr::borrowing_rad_kind::sized : radr::borrowing_rad_kind::unsized;
59+
using borrow_t = radr::borrowing_rad<it_t, sen_t, cit_t, csen_t, bk>;
60+
61+
template <typename in_t>
62+
static void type_checks_impl()
63+
{
64+
/* preserved for all all adaptors */
65+
EXPECT_EQ(std::ranges::sized_range<in_t>, std::ranges::sized_range<container_t>);
66+
EXPECT_EQ(std::ranges::common_range<in_t>, std::ranges::common_range<container_t>);
67+
EXPECT_EQ(std::ranges::bidirectional_range<in_t>, std::ranges::bidirectional_range<container_t>);
68+
EXPECT_EQ(std::ranges::random_access_range<in_t>, std::ranges::random_access_range<container_t>);
69+
EXPECT_EQ(std::ranges::contiguous_range<in_t>, std::ranges::contiguous_range<container_t>);
70+
71+
/* valid for all all adaptors */
72+
EXPECT_TRUE(radr::const_symmetric_range<in_t>);
73+
}
74+
75+
template <typename in_t>
76+
static void type_checks()
77+
{
78+
radr::test::generic_adaptor_checks<in_t, container_t>();
79+
80+
EXPECT_SAME_TYPE(radr::iterator_t<in_t>, it_t);
81+
EXPECT_SAME_TYPE(radr::sentinel_t<in_t>, sen_t);
82+
EXPECT_SAME_TYPE(radr::const_iterator_t<in_t>, cit_t);
83+
EXPECT_SAME_TYPE(radr::const_sentinel_t<in_t>, csen_t);
84+
}
85+
};
86+
87+
//TODO: add non-common, add non-ref referenct_t
88+
using container_types = ::testing::Types<std::forward_list<size_t>, // unsized
89+
std::list<size_t>, // sized without sized_sentinel
90+
std::deque<size_t>,
91+
std::vector<size_t>>;
92+
93+
TYPED_TEST_SUITE(all_forward, container_types);
94+
95+
TYPED_TEST(all_forward, rvalue)
96+
{
97+
using container_t = TestFixture::container_t;
98+
using borrow_t = TestFixture::borrow_t;
99+
100+
auto ra = std::move(this->in) | radr::all;
101+
102+
EXPECT_RANGE_EQ(ra, comp);
103+
EXPECT_SAME_TYPE(decltype(ra), (radr::owning_rad<container_t, borrow_t>));
104+
105+
TestFixture::template type_checks<decltype(ra)>();
106+
}
107+
108+
TYPED_TEST(all_forward, lvalue)
109+
{
110+
using borrow_t = TestFixture::borrow_t;
111+
112+
auto ra = std::ref(this->in) | radr::all;
113+
114+
EXPECT_RANGE_EQ(ra, comp);
115+
EXPECT_SAME_TYPE(decltype(ra), borrow_t);
116+
117+
TestFixture::template type_checks<decltype(ra)>();
118+
}
119+
120+
// --------------------------------------------------------------------------
121+
// owning copy test
122+
// --------------------------------------------------------------------------
123+
124+
TEST(all, owning_copy_test)
125+
{
126+
auto own = std::vector{1, 2, 3, 4, 5, 6} | radr::all;
127+
EXPECT_RANGE_EQ(own, comp);
128+
129+
auto cpy = own;
130+
EXPECT_RANGE_EQ(own, cpy);
131+
}
132+
133+
#undef RADR_ALL_NO_DEPRECATED

0 commit comments

Comments
 (0)