// Range v3 library // // Copyright Eric Niebler 2014-present // // 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 #include #include #include #include #include #include #include #include #include #include #include #include "../simple_test.hpp" #include "../test_utils.hpp" template struct vector_like { private: std::vector data_; public: using size_type = std::size_t; using allocator_type = std::allocator; vector_like() = default; template vector_like(I first, I last) : data_(first, last) {} template void assign(I first, I last) { data_.assign(first, last); } auto begin() { return data_.begin(); } auto end() { return data_.end(); } auto begin() const { return data_.begin(); } auto end() const { return data_.end(); } size_type size() const { return data_.size(); } size_type capacity() const { return data_.capacity(); } size_type max_size() const { return data_.max_size(); } auto& operator[](size_type n) { return data_[n]; } auto& operator[](size_type n) const { return data_[n]; } size_type last_reservation{}; size_type reservation_count{}; void reserve(size_type n) { data_.reserve(n); last_reservation = n; ++reservation_count; } }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template vector_like(I, I) -> vector_like>; template, typename = decltype(std::map{CI{}, CI{}})> void test_zip_to_map(Rng && rng, int) { using namespace ranges; #ifdef RANGES_WORKAROUND_MSVC_779708 auto m = static_cast(rng) | to(); #else // ^^^ workaround / no workaround vvv auto m = static_cast(rng) | to; #endif // RANGES_WORKAROUND_MSVC_779708 CPP_assert(same_as>); } #endif template void test_zip_to_map(Rng &&, long) {} template struct map_like : std::map { template map_like(Iter f, Iter l) : std::map(f, l) {} }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template map_like(Iter, Iter) -> map_like::first_type, typename ranges::iter_value_t::second_type>; #endif int main() { using namespace ranges; { auto lst0 = views::ints | views::transform([](int i) { return i * i; }) | views::take(10) | to(); CPP_assert(same_as>); ::check_equal(lst0, {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}); } #ifndef RANGES_WORKAROUND_MSVC_779708 // "workaround" is a misnomer; there's no // workaround. { auto lst1 = views::ints | views::transform([](int i) { return i * i; }) | views::take(10) | to; CPP_assert(same_as>); ::check_equal(lst1, {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}); } #endif // RANGES_WORKAROUND_MSVC_779708 { auto vec0 = views::ints | views::transform([](int i) { return i * i; }) | views::take(10) | to_vector | actions::sort(std::greater{}); CPP_assert(same_as>); ::check_equal(vec0, {81, 64, 49, 36, 25, 16, 9, 4, 1, 0}); } { auto vec1 = views::ints | views::transform([](int i) { return i * i; }) | views::take(10) | to>() | actions::sort(std::greater{}); CPP_assert(same_as>); ::check_equal(vec1, {81, 64, 49, 36, 25, 16, 9, 4, 1, 0}); } #ifndef RANGES_WORKAROUND_MSVC_779708 { auto vec2 = views::ints | views::transform([](int i) { return i * i; }) | views::take(10) | to> | actions::sort(std::greater{}); CPP_assert(same_as>); ::check_equal(vec2, {81, 64, 49, 36, 25, 16, 9, 4, 1, 0}); } #endif // RANGES_WORKAROUND_MSVC_779708 { const std::size_t N = 4096; auto vl = views::iota(0, int{N}) | to>(); CPP_assert(same_as>); CHECK(vl.reservation_count == std::size_t{1}); CHECK(vl.last_reservation == N); } // https://github.com/ericniebler/range-v3/issues/1145 { auto r1 = views::indices(std::uintmax_t{100}); auto r2 = views::zip(r1, r1); #ifdef RANGES_WORKAROUND_MSVC_779708 auto m = r2 | ranges::to>(); #else // ^^^ workaround / no workaround vvv auto m = r2 | ranges::to>; #endif // RANGES_WORKAROUND_MSVC_779708 CPP_assert(same_as>); } // Transform a range-of-ranges into a container of containers { auto r = views::ints(1, 4) | views::transform([](int i) { return views::ints(i, i + 3); }); auto m = r | ranges::to>>(); CPP_assert(same_as>>); CHECK(m.size() == 3u); check_equal(m[0], {1, 2, 3}); check_equal(m[1], {2, 3, 4}); check_equal(m[2], {3, 4, 5}); } // Use ranges::to in a closure with an action { #ifdef RANGES_WORKAROUND_MSVC_779708 auto closure = ranges::to() | actions::sort; #else // ^^^ workaround / no workaround vvv auto closure = ranges::to | actions::sort; #endif // RANGES_WORKAROUND_MSVC_779708 auto r = views::ints(1, 4) | views::reverse; auto m = r | closure; CPP_assert(same_as>); CHECK(m.size() == 3u); check_equal(m, {1, 2, 3}); } test_zip_to_map(views::zip(views::ints, views::iota(0, 10)), 0); // https://github.com/ericniebler/range-v3/issues/1544 { std::vector> d; auto m = views::transform(d, views::all); auto v = ranges::to>>(m); check_equal(d, v); } { std::vector> v = {{1, 2}, {3, 4}}; auto m1 = ranges::to>(v); auto m2 = v | ranges::to>(); CPP_assert(same_as>); CPP_assert(same_as>); check_equal(m1, std::map{{1, 2}, {3, 4}}); check_equal(m1, m2); #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 auto m3 = ranges::to(v); auto m4 = v | ranges::to(); CPP_assert(same_as>); CPP_assert(same_as>); check_equal(m1, m3); check_equal(m1, m4); #endif } return ::test_result(); }