// Copyright (C) 2019 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 <boost/stl_interfaces/iterator_interface.hpp> #include <boost/stl_interfaces/reverse_iterator.hpp> #include <boost/core/lightweight_test.hpp> #include <algorithm> #include <array> #include <list> #include <tuple> #include <vector> struct zip_iter : boost::stl_interfaces::proxy_iterator_interface< zip_iter, std::random_access_iterator_tag, std::tuple<int, int>, std::tuple<int &, int &>> { zip_iter() : it1_(nullptr), it2_(nullptr) {} zip_iter(int * it1, int * it2) : it1_(it1), it2_(it2) {} std::tuple<int &, int &> operator*() const { return std::tuple<int &, int &>{*it1_, *it2_}; } zip_iter & operator+=(std::ptrdiff_t i) { it1_ += i; it2_ += i; return *this; } friend std::ptrdiff_t operator-(zip_iter lhs, zip_iter rhs) noexcept { return lhs.it1_ - rhs.it1_; } private: int * it1_; int * it2_; }; int main() { { std::list<int> ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; auto first = boost::stl_interfaces::make_reverse_iterator(ints.end()); auto last = boost::stl_interfaces::make_reverse_iterator(ints.begin()); { auto cfirst = boost::stl_interfaces::reverse_iterator< std::list<int>::const_iterator>(first); auto clast = boost::stl_interfaces::reverse_iterator< std::list<int>::const_iterator>(last); BOOST_TEST(std::equal(first, last, cfirst, clast)); } { auto ints_copy = ints; std::reverse(ints_copy.begin(), ints_copy.end()); BOOST_TEST( std::equal(first, last, ints_copy.begin(), ints_copy.end())); } { std::list<int> ints_copy; std::reverse_copy(first, last, std::back_inserter(ints_copy)); BOOST_TEST(ints_copy == ints); } { std::size_t count = 0; for (auto it = first; it != last; ++it) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = first; it != last; it++) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = last; it != first; --it) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = last; it != first; it--) { ++count; } BOOST_TEST(count == ints.size()); } } { std::vector<int> ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; auto first = boost::stl_interfaces::make_reverse_iterator(ints.end()); auto last = boost::stl_interfaces::make_reverse_iterator(ints.begin()); { auto cfirst = boost::stl_interfaces::reverse_iterator< std::vector<int>::const_iterator>(first); auto clast = boost::stl_interfaces::reverse_iterator< std::vector<int>::const_iterator>(last); BOOST_TEST(std::equal(first, last, cfirst, clast)); } { auto ints_copy = ints; std::reverse(ints_copy.begin(), ints_copy.end()); BOOST_TEST(first - last == ints_copy.begin() - ints_copy.end()); BOOST_TEST( std::equal(first, last, ints_copy.begin(), ints_copy.end())); } { std::vector<int> ints_copy; std::reverse_copy(first, last, std::back_inserter(ints_copy)); BOOST_TEST(ints_copy == ints); } { std::size_t count = 0; for (auto it = first; it != last; ++it) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = first; it != last; it++) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = last; it != first; --it) { ++count; } BOOST_TEST(count == ints.size()); } { std::size_t count = 0; for (auto it = last; it != first; it--) { ++count; } BOOST_TEST(count == ints.size()); } } { std::array<int, 10> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; std::array<int, 10> ones = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}; std::array<std::tuple<int, int>, 10> tuples = {{ {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, }}; auto first = boost::stl_interfaces::make_reverse_iterator( zip_iter(ints.data() + ints.size(), ones.data() + ones.size())); auto last = boost::stl_interfaces::make_reverse_iterator( zip_iter(ints.data(), ones.data())); { auto tuples_copy = tuples; std::reverse(tuples_copy.begin(), tuples_copy.end()); BOOST_TEST(first - last == tuples_copy.begin() - tuples_copy.end()); BOOST_TEST( std::equal(first, last, tuples_copy.begin(), tuples_copy.end())); } { std::array<std::tuple<int, int>, 10> tuples_copy; std::reverse_copy(first, last, tuples_copy.begin()); BOOST_TEST(tuples_copy == tuples); } { std::size_t count = 0; for (auto it = first; it != last; ++it) { ++count; } BOOST_TEST(count == tuples.size()); } { std::size_t count = 0; for (auto it = first; it != last; it++) { ++count; } BOOST_TEST(count == tuples.size()); } { std::size_t count = 0; for (auto it = last; it != first; --it) { ++count; } BOOST_TEST(count == tuples.size()); } { std::size_t count = 0; for (auto it = last; it != first; it--) { ++count; } BOOST_TEST(count == tuples.size()); } } return boost::report_errors(); }