Skip to content

Commit

Permalink
Speculatively implement the PR of ericniebler/stl2#623
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyCarter committed Apr 26, 2019
1 parent 4ce0f17 commit 43bd82d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
6 changes: 5 additions & 1 deletion include/stl2/detail/range/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,12 @@ STL2_OPEN_NAMESPACE {

template<class Rng>
META_CONCEPT ViewableRange =
#if 1 // This is the PR of https://github.com/ericniebler/stl2/issues/623
View<__uncvref<Rng>> || _ForwardingRange<Rng>;
#else
Range<Rng> &&
(_RangeImpl<Rng> || View<Rng>);
(_RangeImpl<Rng> || View<std::decay_t<Rng>>);
#endif

namespace ext {
template<Range R>
Expand Down
35 changes: 21 additions & 14 deletions include/stl2/view/all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,29 @@
STL2_OPEN_NAMESPACE {
namespace view {
struct __all_fn : detail::__pipeable<__all_fn> {
template<Range R>
requires View<__f<R>>
constexpr auto operator()(R&& r) const
noexcept(std::is_nothrow_constructible_v<__f<R>, R>) {
return static_cast<R&&>(r);
}
private:
enum : unsigned { __throws = 1, __decay = 2, __ref = 4, __subrange = 6 };

template<_ForwardingRange R>
requires (!View<__uncvref<R>>)
constexpr auto operator()(R&& r) const
noexcept(std::is_reference_v<R>)
{
if constexpr (std::is_reference_v<R>) {
return ref_view{r};
template<ViewableRange _Range>
static constexpr unsigned __choose() noexcept {
if constexpr (View<__uncvref<_Range>>) {
return __decay | std::is_nothrow_constructible_v<__uncvref<_Range>, _Range>;
} else if constexpr (std::is_lvalue_reference_v<_Range>) {
return __ref | noexcept(ref_view{std::declval<_Range>()});
} else {
return __subrange | noexcept(subrange{std::declval<_Range>()});
}
}
public:
template<ViewableRange _Range, unsigned _Choice = __choose<_Range>()>
constexpr auto operator()(_Range&& __r) const noexcept(_Choice & __throws) {
constexpr auto __strategy = _Choice & ~__throws;
if constexpr (__strategy == __decay) {
return static_cast<_Range&&>(__r);
} else if constexpr (__strategy == __ref) {
return ref_view{__r};
} else {
return subrange{static_cast<R&&>(r)};
return subrange{static_cast<_Range&&>(__r)};
}
}
};
Expand Down
8 changes: 7 additions & 1 deletion test/view/filter_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,15 @@ int main() {
}

{
auto yes = [](int){ return true; };
auto yes = [](int) { return true; };
(void) (view::iota(0) | view::filter(yes));
}

{
auto yes = [](int) { return true; };
auto const rng = view::iota(0) | view::filter(yes);
view::all(rng);
}

return test_result();
}

0 comments on commit 43bd82d

Please sign in to comment.