// Copyright (C) 2022 T. Zachary Laine // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include "ill_formed.hpp" #include "../example/all_view.hpp" #include "../example/reverse_view.hpp" #include "../example/take_view.hpp" #include #include #include namespace detail { template< typename R, bool ReverseView = is_reverse_view>::value> struct reverse_impl_impl { static constexpr auto call(R && r) { return ((R &&) r).base(); } }; template struct reverse_impl_impl { static constexpr auto call(R && r) { return reverse_view>(0, (R &&) r); } }; struct reverse_impl : boost::stl_interfaces::range_adaptor_closure { template constexpr auto operator()(R && r) const { return reverse_impl_impl::call((R &&) r); } }; struct take_impl { template constexpr auto operator()(R && r, int n) const { return take_view>((R &&) r, n); } constexpr auto operator()(int n) const { using closure_func_type = decltype(boost::stl_interfaces::bind_back(*this, n)); return boost::stl_interfaces::closure( boost::stl_interfaces::bind_back(*this, n)); } }; } #if defined(__cpp_inline_variables) inline constexpr detail::reverse_impl old_reverse; inline constexpr detail::take_impl old_take; #else namespace { constexpr detail::reverse_impl old_reverse; constexpr detail::take_impl old_take; } #endif int main() { // non-closures { std::vector vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : old_all(vec1) | old_reverse) { vec2.push_back(x); } std::reverse(vec2.begin(), vec2.end()); BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : old_all(vec1) | old_reverse) { vec2.push_back(x); } std::reverse(vec2.begin(), vec2.end()); BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : old_all(vec1) | old_reverse | old_reverse) { vec2.push_back(x); } BOOST_TEST(vec1 == vec2); } // Mismatched begin and end; only test this in C++17 and later. #if 201703L <= __cplusplus { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : old_all(vec1) | old_take(3)) { vec2.push_back(x); } BOOST_TEST(vec2 == (std::vector{0, 1, 2})); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : old_all(vec1) | old_reverse | old_take(3)) { vec2.push_back(x); } BOOST_TEST(vec2 == (std::vector{7, 6, 5})); } #endif #if 201703L <= __cplusplus // closures { std::vector vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | reverse) { vec2.push_back(x); } std::reverse(vec2.begin(), vec2.end()); BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | reverse) { vec2.push_back(x); } std::reverse(vec2.begin(), vec2.end()); BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | reverse | reverse) { vec2.push_back(x); } BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | take(3)) { vec2.push_back(x); } BOOST_TEST(vec2 == (std::vector{0, 1, 2})); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | reverse | take(3)) { vec2.push_back(x); } BOOST_TEST(vec2 == (std::vector{7, 6, 5})); } #endif // User views mixed with std views. #if BOOST_STL_INTERFACES_USE_CONCEPTS { std::vector vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | std::views::reverse | old_reverse | std::views::reverse) { vec2.push_back(x); } std::reverse(vec2.begin(), vec2.end()); BOOST_TEST(vec1 == vec2); } { std::vector const vec1 = {0, 1, 2, 3, 4, 5, 6, 7}; std::vector vec2; for (auto x : all(vec1) | reverse | std::views::take(3)) { vec2.push_back(x); } BOOST_TEST(vec2 == (std::vector{7, 6, 5})); } #endif return boost::report_errors(); }