/// \file // Range v3 library // // Copyright Andrey Diduh 2019 // // Use, modification and distribution is subject to 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) // // Project home: https://github.com/ericniebler/range-v3 // #include "../simple_test.hpp" #include "../test_utils.hpp" #include #include #include #include #include #include #include #include using namespace ranges; template struct view_non_const_only : view_adaptor, Rng> { private: friend range_access; adaptor_base begin_adaptor() { return {}; } adaptor_base end_adaptor() { return {}; } public: using view_non_const_only::view_adaptor::view_adaptor; CPP_auto_member auto CPP_fun(size)() ( requires sized_range) { return ranges::size(this->base()); } }; template view_non_const_only> non_const_only(Rng &&rng) { return view_non_const_only>{views::all(static_cast(rng))}; } template void test_range(Rng&& src) { // additional src copy for InputStream { auto src_ = src; ::check_equal(src_, {1,2,3,4}); } { auto src_ = src; auto list = src_ | views::drop_last(2); ::check_equal(list, {1,2}); } { auto src_ = src; auto list = src_ | views::drop_last(0); ::check_equal(list, {1,2,3,4}); } { auto src_ = src; auto list = src_ | views::drop_last(4); CHECK(list.empty()); } { auto src_ = src; auto list = src_ | views::drop_last(5); CHECK(list.empty()); } } template void test_size(Rng&& src) { CHECK( (src | views::drop_last(0)).size() == std::size_t(4) ); CHECK( (src | views::drop_last(2)).size() == std::size_t(2) ); CHECK( (src | views::drop_last(4)).size() == std::size_t(0) ); CHECK( (src | views::drop_last(5)).size() == std::size_t(0) ); } template void test_non_convert_range(Rng&& src) { // test non-convertible const<=>non-const range test_range(src | views::transform([](const int& i) -> const int& {return i;})); } void random_acccess_test() { using Src = std::vector; static_assert( ranges::random_access_range , "Must be exactly RA."); static_assert( std::is_same< drop_last_view>, drop_last_view, detail::drop_last_view::mode_bidi> >::value , "Must have correct view."); Src src = {1,2,3,4}; test_range(src); test_range(non_const_only(src)); test_size(src); test_non_convert_range(src); } void bidirectional_test() { using Src = std::list; static_assert( !ranges::random_access_range && ranges::bidirectional_range , "Must be exactly bidirectional."); static_assert( std::is_same< /* mode_sized for max_performance profile. * mode_bidi for compatible profile. * See aux::drop_last::get_mode */ drop_last_view>, drop_last_view, detail::drop_last_view::mode_bidi> >::value , "Must have correct view."); Src src = {1,2,3,4}; test_range(src); test_range(non_const_only(src)); test_size(src); test_non_convert_range(src); } void forward_test() { using Src = std::forward_list; static_assert( !ranges::bidirectional_range && ranges::forward_range , "Must be exactly forward."); static_assert( std::is_same< drop_last_view>, drop_last_view, detail::drop_last_view::mode_forward> >::value , "Must have correct view."); Src src = {1,2,3,4}; test_range(src); test_range(non_const_only(src)); test_size(src | views::take_exactly(4)); test_non_convert_range(src); } void sized_test() { int i = 0; auto src = views::generate_n([i]() mutable -> int { return ++i;}, 4); using Src = decltype(src); static_assert( !ranges::forward_range && ranges::input_range , "Must be exactly input."); static_assert( std::is_same< drop_last_view>, drop_last_view, detail::drop_last_view::mode_sized> >::value , "Must have correct view."); { // always non-const auto src_ = src; test_range(src_); } { auto src_ = src; test_size(src_); } { auto src_ = src; test_range(non_const_only(std::move(src_))); } { auto src_ = src; test_non_convert_range(src_); } } int main() { random_acccess_test(); bidirectional_test(); forward_test(); sized_test(); return test_result(); }