Skip to content

Commit 3e0c139

Browse files
committed
Constrain the return type of begin and end for adapt
1 parent d26a0c9 commit 3e0c139

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

source/containers/adapt.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ module;
1111
export module containers.adapt;
1212

1313
import containers.begin_end;
14+
import containers.is_iterator;
15+
import containers.is_iterator_sentinel;
1416
import containers.iter_value_t;
1517
import containers.iterator_adapter;
1618
import containers.reference_wrapper;
@@ -34,43 +36,54 @@ concept statically_sized_adapted_range = sized_adapted_range<Range, Traits> and
3436

3537
export template<typename Range, typename Traits>
3638
struct adapt {
39+
private:
40+
using adapt_iterator_traits = std::conditional_t<
41+
std::is_empty_v<Traits> and std::is_copy_assignable_v<Traits>,
42+
Traits,
43+
decltype(std::reference_wrapper(bounded::declval<Traits const &>()))
44+
>;
45+
46+
[[no_unique_address]] Range m_range;
47+
[[no_unique_address]] Traits m_traits;
48+
49+
public:
3750
constexpr adapt(Range && range, Traits traits):
3851
m_range(OPERATORS_FORWARD(range)),
3952
m_traits(std::move(traits))
4053
{
4154
}
4255

43-
constexpr auto begin() const & {
56+
constexpr auto begin() const & -> iterator auto {
4457
return containers::adapt_iterator(
4558
::containers::unwrap(m_traits).get_begin(m_range),
4659
adapt_iterator_traits(m_traits)
4760
);
4861
}
49-
constexpr auto begin() & {
62+
constexpr auto begin() & -> iterator auto {
5063
return containers::adapt_iterator(
5164
::containers::unwrap(m_traits).get_begin(m_range),
5265
adapt_iterator_traits(m_traits)
5366
);
5467
}
55-
constexpr auto begin() && {
68+
constexpr auto begin() && -> iterator auto {
5669
return containers::adapt_iterator(
5770
::containers::unwrap(m_traits).get_begin(std::move(*this).m_range),
5871
adapt_iterator_traits(m_traits)
5972
);
6073
}
61-
constexpr auto end() const & {
74+
constexpr auto end() const & -> sentinel_for<decltype(begin())> auto {
6275
return containers::adapt_iterator(
6376
::containers::unwrap(m_traits).get_end(m_range),
6477
adapt_iterator_traits(m_traits)
6578
);
6679
}
67-
constexpr auto end() & {
80+
constexpr auto end() & -> sentinel_for<decltype(begin())> auto {
6881
return containers::adapt_iterator(
6982
::containers::unwrap(m_traits).get_end(m_range),
7083
adapt_iterator_traits(m_traits)
7184
);
7285
}
73-
constexpr auto end() && {
86+
constexpr auto end() && -> sentinel_for<decltype(begin())> auto {
7487
return containers::adapt_iterator(
7588
::containers::unwrap(m_traits).get_end(std::move(*this).m_range),
7689
adapt_iterator_traits(m_traits)
@@ -92,16 +105,6 @@ struct adapt {
92105
constexpr auto base() && -> Range && {
93106
return std::move(m_range);
94107
}
95-
96-
private:
97-
using adapt_iterator_traits = std::conditional_t<
98-
std::is_empty_v<Traits> and std::is_copy_assignable_v<Traits>,
99-
Traits,
100-
decltype(std::reference_wrapper(bounded::declval<Traits const &>()))
101-
>;
102-
103-
[[no_unique_address]] Range m_range;
104-
[[no_unique_address]] Traits m_traits;
105108
};
106109

107110
template<typename Range, typename Traits>

0 commit comments

Comments
 (0)