// Range v3 library // // Copyright Eric Niebler 2015-present // Copyright Casey Carter 2016 // // 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 "../simple_test.hpp" #include "../test_iterators.hpp" RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER namespace { struct silly_arrow_cursor { int read() const { return 0; } void next() {} int arrow() const { return 42; } }; int forty_two = 42; struct lvalue_iterator { using difference_type = int; using value_type = int; int& operator*() const { return forty_two; } lvalue_iterator& operator++() & { return *this; } lvalue_iterator operator++(int) & { return *this; } }; struct xvalue_iterator : lvalue_iterator { int&& operator*() const { return std::move(forty_two); } xvalue_iterator& operator++() & { return *this; } xvalue_iterator operator++(int) & { return *this; } }; struct proxy_cursor { int read() const { return 42; } void next() {} }; void test_operator_arrow() { // I is a pointer type { int i = 42; auto ci = ranges::common_iterator{&i}; CPP_assert(ranges::same_as())>); CHECK(ci.operator->() == &i); } // the expression i.operator->() is well-formed { using I = ranges::basic_iterator; auto ci = ranges::common_iterator{}; CPP_assert(ranges::same_as())>); CHECK(ci.operator->().operator->() == 42); } // the expression *i is a glvalue [lvalue case] { auto ci = ranges::common_iterator{}; CPP_assert(ranges::same_as())>); CHECK(ci.operator->() == &forty_two); } // the expression *i is a glvalue [xvalue case] { auto ci = ranges::common_iterator{}; CPP_assert(ranges::same_as())>); CHECK(ci.operator->() == &forty_two); } // Otherwise, returns a proxy object { using I = ranges::basic_iterator; auto ci = ranges::common_iterator{}; using A = decltype(ci.operator->()); CPP_assert(std::is_class::value); CPP_assert(!std::is_same::value); CHECK(*ci.operator->().operator->() == 42); } } } int main() { { CPP_assert( ranges::forward_iterator< ranges::common_iterator< BidirectionalIterator, Sentinel>>); CPP_assert( !ranges::bidirectional_iterator< ranges::common_iterator< BidirectionalIterator, Sentinel>>); CPP_assert( std::is_same< ranges::common_reference< ranges::common_iterator< BidirectionalIterator, Sentinel >&, ranges::common_iterator< BidirectionalIterator, Sentinel > >::type, ranges::common_iterator< BidirectionalIterator, Sentinel > >::value); // Sized iterator range tests CPP_assert( !ranges::sized_sentinel_for< ranges::common_iterator< ForwardIterator, Sentinel >, ranges::common_iterator< ForwardIterator, Sentinel > >); CPP_assert( ranges::sized_sentinel_for< ranges::common_iterator< RandomAccessIterator, Sentinel >, ranges::common_iterator< RandomAccessIterator, Sentinel > >); CPP_assert( !ranges::sized_sentinel_for< ranges::common_iterator< RandomAccessIterator, Sentinel >, ranges::common_iterator< RandomAccessIterator, Sentinel > >); } { int rgi[] {0,1,2,3,4,5,6,7,8,9}; using CI = ranges::common_iterator< RandomAccessIterator, Sentinel>; CI first{RandomAccessIterator{rgi}}; CI last{Sentinel{rgi+10}}; CHECK(std::accumulate(first, last, 0, std::plus{}) == 45); } test_operator_arrow(); return test_result(); }