//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef RANGES_TEST_ITERATORS_HPP #define RANGES_TEST_ITERATORS_HPP #include #include template class Sentinel; template class OutputIterator; template class InputIterator; template class ForwardIterator; template class BidirectionalIterator; template class RandomAccessIterator; template constexpr /*c++14*/ Iter base(Sentinel i) { return i.base(); } template constexpr /*c++14*/ Iter base(OutputIterator i) { return i.base(); } template constexpr /*c++14*/ Iter base(InputIterator i) { return i.base(); } template constexpr /*c++14*/ Iter base(ForwardIterator i) { return i.base(); } template constexpr /*c++14*/ Iter base(BidirectionalIterator i) { return i.base(); } template constexpr /*c++14*/ Iter base(RandomAccessIterator i) { return i.base(); } template // everything else constexpr /*c++14*/ Iter base(Iter i) { return i; } template class Sentinel { It it_; public: constexpr /*c++14*/ Sentinel() : it_() {} constexpr /*c++14*/ explicit Sentinel(It it) : it_(it) {} constexpr /*c++14*/ It base() const { return it_; } constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const Sentinel& y) { RANGES_ENSURE(x.it_ == y.it_); return true; } constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const Sentinel& y) { RANGES_ENSURE(x.it_ == y.it_); return false; } template constexpr /*c++14*/ friend bool operator==(const I& x, const Sentinel& y) { using ::base; return base(x) == y.it_; } template constexpr /*c++14*/ friend bool operator!=(const I& x, const Sentinel& y) { return !(x == y); } template constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const I& y) { using ::base; return x.it_ == base(y); } template constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const I& y) { return !(x == y); } }; // For making sized iterator ranges: template class I, typename It> constexpr /*c++14*/ auto CPP_auto_fun(operator-)(Sentinel last, I first) ( return base(last) - base(first) ) template class I, typename It> constexpr /*c++14*/ auto CPP_auto_fun(operator-)(I first, Sentinel last) ( return base(first) - base(last) ) template class OutputIterator { It it_; template friend class OutputIterator; public: typedef std::output_iterator_tag iterator_category; typedef void value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; constexpr /*c++14*/ It base() const {return it_;} constexpr /*c++14*/ OutputIterator () {} constexpr /*c++14*/ explicit OutputIterator(It it) : it_(it) {} template{}>::type> constexpr /*c++14*/ OutputIterator(const OutputIterator& u) :it_(u.it_) {} constexpr /*c++14*/ reference operator*() const {return *it_;} constexpr /*c++14*/ OutputIterator& operator++() {++it_; return *this;} constexpr /*c++14*/ OutputIterator operator++(int) {OutputIterator tmp(*this); ++(*this); return tmp;} }; template class InputIterator { It it_; template friend class InputIterator; public: typedef std::input_iterator_tag iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; constexpr /*c++14*/ It base() const {return it_;} constexpr /*c++14*/ InputIterator() : it_() {} constexpr /*c++14*/ explicit InputIterator(It it) : it_(it) {} template constexpr /*c++14*/ CPP_ctor(InputIterator)(const InputIterator& u)( requires (std::is_convertible::value)) :it_(u.it_) {} constexpr /*c++14*/ reference operator*() const {return *it_;} constexpr /*c++14*/ pointer operator->() const {return it_;} constexpr /*c++14*/ InputIterator& operator++() {++it_; return *this;} constexpr /*c++14*/ InputIterator operator++(int) {InputIterator tmp(*this); ++(*this); return tmp;} constexpr /*c++14*/ friend bool operator==(const InputIterator& x, const InputIterator& y) {return x.it_ == y.it_;} constexpr /*c++14*/ friend bool operator!=(const InputIterator& x, const InputIterator& y) {return !(x == y);} template = 42> constexpr /*c++14*/ friend difference_type operator-(const InputIterator& x, const InputIterator& y) {return x.it_ - y.it_;} }; template constexpr /*c++14*/ bool operator==(const InputIterator& x, const InputIterator& y) { return x.base() == y.base(); } template constexpr /*c++14*/ bool operator!=(const InputIterator& x, const InputIterator& y) { return !(x == y); } template class ForwardIterator { It it_; template friend class ForwardIterator; public: typedef std::forward_iterator_tag iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; constexpr /*c++14*/ It base() const {return it_;} constexpr /*c++14*/ ForwardIterator() : it_() {} constexpr /*c++14*/ explicit ForwardIterator(It it) : it_(it) {} template constexpr /*c++14*/ CPP_ctor(ForwardIterator)(const ForwardIterator& u)( requires (std::is_convertible::value)) :it_(u.it_) {} constexpr /*c++14*/ reference operator*() const {return *it_;} constexpr /*c++14*/ pointer operator->() const {return it_;} constexpr /*c++14*/ ForwardIterator& operator++() {++it_; return *this;} constexpr /*c++14*/ ForwardIterator operator++(int) {ForwardIterator tmp(*this); ++(*this); return tmp;} constexpr /*c++14*/ friend bool operator==(const ForwardIterator& x, const ForwardIterator& y) {return x.it_ == y.it_;} constexpr /*c++14*/ friend bool operator!=(const ForwardIterator& x, const ForwardIterator& y) {return !(x == y);} }; template constexpr /*c++14*/ bool operator==(const ForwardIterator& x, const ForwardIterator& y) { return x.base() == y.base(); } template constexpr /*c++14*/ bool operator!=(const ForwardIterator& x, const ForwardIterator& y) { return !(x == y); } template class BidirectionalIterator { It it_; template friend class BidirectionalIterator; public: typedef std::bidirectional_iterator_tag iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; constexpr /*c++14*/ It base() const {return it_;} constexpr /*c++14*/ BidirectionalIterator() : it_() {} constexpr /*c++14*/ explicit BidirectionalIterator(It it) : it_(it) {} template constexpr /*c++14*/ CPP_ctor(BidirectionalIterator)(const BidirectionalIterator& u)( requires (std::is_convertible::value)) :it_(u.it_) {} constexpr /*c++14*/ reference operator*() const {return *it_;} constexpr /*c++14*/ pointer operator->() const {return it_;} constexpr /*c++14*/ BidirectionalIterator& operator++() {++it_; return *this;} constexpr /*c++14*/ BidirectionalIterator operator++(int) {BidirectionalIterator tmp(*this); ++(*this); return tmp;} constexpr /*c++14*/ BidirectionalIterator& operator--() {--it_; return *this;} constexpr /*c++14*/ BidirectionalIterator operator--(int) {BidirectionalIterator tmp(*this); --(*this); return tmp;} }; template constexpr /*c++14*/ bool operator==(const BidirectionalIterator& x, const BidirectionalIterator& y) { return x.base() == y.base(); } template constexpr /*c++14*/ bool operator!=(const BidirectionalIterator& x, const BidirectionalIterator& y) { return !(x == y); } template class RandomAccessIterator { It it_; template friend class RandomAccessIterator; public: typedef std::random_access_iterator_tag iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; constexpr /*c++14*/ It base() const {return it_;} constexpr /*c++14*/ RandomAccessIterator() : it_() {} constexpr /*c++14*/ explicit RandomAccessIterator(It it) : it_(it) {} template constexpr /*c++14*/ CPP_ctor(RandomAccessIterator)(const RandomAccessIterator& u)( requires (std::is_convertible::value)) :it_(u.it_) {} constexpr /*c++14*/ reference operator*() const {return *it_;} constexpr /*c++14*/ pointer operator->() const {return it_;} constexpr /*c++14*/ RandomAccessIterator& operator++() {++it_; return *this;} constexpr /*c++14*/ RandomAccessIterator operator++(int) {RandomAccessIterator tmp(*this); ++(*this); return tmp;} constexpr /*c++14*/ RandomAccessIterator& operator--() {--it_; return *this;} constexpr /*c++14*/ RandomAccessIterator operator--(int) {RandomAccessIterator tmp(*this); --(*this); return tmp;} constexpr /*c++14*/ RandomAccessIterator& operator+=(difference_type n) {it_ += n; return *this;} constexpr /*c++14*/ RandomAccessIterator operator+(difference_type n) const {RandomAccessIterator tmp(*this); tmp += n; return tmp;} constexpr /*c++14*/ friend RandomAccessIterator operator+(difference_type n, RandomAccessIterator x) {x += n; return x;} constexpr /*c++14*/ RandomAccessIterator& operator-=(difference_type n) {return *this += -n;} constexpr /*c++14*/ RandomAccessIterator operator-(difference_type n) const {RandomAccessIterator tmp(*this); tmp -= n; return tmp;} constexpr /*c++14*/ reference operator[](difference_type n) const {return it_[n];} }; template constexpr /*c++14*/ bool operator==(const RandomAccessIterator& x, const RandomAccessIterator& y) { return x.base() == y.base(); } template constexpr /*c++14*/ bool operator!=(const RandomAccessIterator& x, const RandomAccessIterator& y) { return !(x == y); } template constexpr /*c++14*/ bool operator<(const RandomAccessIterator& x, const RandomAccessIterator& y) { return x.base() < y.base(); } template constexpr /*c++14*/ bool operator<=(const RandomAccessIterator& x, const RandomAccessIterator& y) { return !(y < x); } template constexpr /*c++14*/ bool operator>(const RandomAccessIterator& x, const RandomAccessIterator& y) { return y < x; } template constexpr /*c++14*/ bool operator>=(const RandomAccessIterator& x, const RandomAccessIterator& y) { return !(x < y); } template constexpr /*c++14*/ auto CPP_auto_fun(operator-)(const RandomAccessIterator& x, const RandomAccessIterator& y) ( return x.base() - y.base() ) template struct sentinel_type { using type = It; }; template struct sentinel_type { using type = Sentinel; }; template class I, typename It, bool Sized> struct sentinel_type, Sized> { using type = Sentinel; }; template struct TestRange { I first; S second; constexpr I begin() const { return first; } constexpr S end() const { return second; } }; template TestRange MakeTestRange(I i, S s) { return {i, s}; } template constexpr bool is_dangling(T) { return false; } constexpr bool is_dangling(::ranges::dangling) { return true; } #endif // RANGES_TEST_ITERATORS_HPP