| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /***************************************************************************
- * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
- * Copyright (c) QuantStack *
- * *
- * Distributed under the terms of the BSD 3-Clause License. *
- * *
- * The full license is in the file LICENSE, distributed with this software. *
- ****************************************************************************/
- #ifndef XTL_XITERATOR_BASE_HPP
- #define XTL_XITERATOR_BASE_HPP
- #include <cstddef>
- #include <iterator>
- namespace xtl
- {
- /**************************************
- * class xbidirectional_iterator_base *
- **************************************/
- template <class I, class T, class D = std::ptrdiff_t, class P = T*, class R = T&>
- class xbidirectional_iterator_base
- {
- public:
- using derived_type = I;
- using value_type = T;
- using reference = R;
- using pointer = P;
- using difference_type = D;
- using iterator_category = std::bidirectional_iterator_tag;
- inline friend derived_type operator++(derived_type& d, int)
- {
- derived_type tmp(d);
- ++d;
- return tmp;
- }
- inline friend derived_type operator--(derived_type& d, int)
- {
- derived_type tmp(d);
- --d;
- return tmp;
- }
- inline friend bool operator!=(const derived_type& lhs, const derived_type& rhs)
- {
- return !(lhs == rhs);
- }
- };
- template <class T>
- using xbidirectional_iterator_base2 = xbidirectional_iterator_base<typename T::iterator_type,
- typename T::value_type,
- typename T::difference_type,
- typename T::pointer,
- typename T::reference>;
- template <class I, class T>
- using xbidirectional_iterator_base3 = xbidirectional_iterator_base<I,
- typename T::value_type,
- typename T::difference_type,
- typename T::pointer,
- typename T::reference>;
- /********************************
- * xrandom_access_iterator_base *
- ********************************/
- template <class I, class T, class D = std::ptrdiff_t, class P = T*, class R = T&>
- class xrandom_access_iterator_base : public xbidirectional_iterator_base<I, T, D, P, R>
- {
- public:
- using derived_type = I;
- using value_type = T;
- using reference = R;
- using pointer = P;
- using difference_type = D;
- using iterator_category = std::random_access_iterator_tag;
- inline reference operator[](difference_type n) const
- {
- return *(*static_cast<const derived_type*>(this) + n);
- }
- inline friend derived_type operator+(const derived_type& it, difference_type n)
- {
- derived_type tmp(it);
- return tmp += n;
- }
- inline friend derived_type operator+(difference_type n, const derived_type& it)
- {
- derived_type tmp(it);
- return tmp += n;
- }
- inline friend derived_type operator-(const derived_type& it, difference_type n)
- {
- derived_type tmp(it);
- return tmp -= n;
- }
- inline friend bool operator<=(const derived_type& lhs, const derived_type& rhs)
- {
- return !(rhs < lhs);
- }
- inline friend bool operator>=(const derived_type& lhs, const derived_type& rhs)
- {
- return !(lhs < rhs);
- }
- inline friend bool operator>(const derived_type& lhs, const derived_type& rhs)
- {
- return rhs < lhs;
- }
-
- };
- template <class T>
- using xrandom_access_iterator_base2 = xrandom_access_iterator_base<typename T::iterator_type,
- typename T::value_type,
- typename T::difference_type,
- typename T::pointer,
- typename T::reference>;
- template <class I, class T>
- using xrandom_access_iterator_base3 = xrandom_access_iterator_base<I,
- typename T::value_type,
- typename T::difference_type,
- typename T::pointer,
- typename T::reference>;
- /*******************************
- * xrandom_access_iterator_ext *
- *******************************/
- // Extension for random access iterators defining operator[] and operator+ overloads
- // accepting size_t arguments.
- template <class I, class R>
- class xrandom_access_iterator_ext
- {
- public:
- using derived_type = I;
- using reference = R;
- using size_type = std::size_t;
- inline reference operator[](size_type n) const
- {
- return *(*static_cast<const derived_type*>(this) + n);
- }
- inline friend derived_type operator+(const derived_type& it, size_type n)
- {
- derived_type tmp(it);
- return tmp += n;
- }
- inline friend derived_type operator+(size_type n, const derived_type& it)
- {
- derived_type tmp(it);
- return tmp += n;
- }
- inline friend derived_type operator-(const derived_type& it, size_type n)
- {
- derived_type tmp(it);
- return tmp -= n;
- }
- };
- /*****************
- * xkey_iterator *
- *****************/
- template <class M>
- class xkey_iterator : public xbidirectional_iterator_base<xkey_iterator<M>, const typename M::key_type>
- {
- public:
- using self_type = xkey_iterator;
- using base_type = xbidirectional_iterator_base<self_type, const typename M::key_type>;
- using value_type = typename base_type::value_type;
- using reference = typename base_type::reference;
- using pointer = typename base_type::pointer;
- using difference_type = typename base_type::difference_type;
- using iterator_category = typename base_type::iterator_category;
- using subiterator = typename M::const_iterator;
- inline xkey_iterator(subiterator it) noexcept
- : m_it(it)
- {
- }
- inline self_type& operator++()
- {
- ++m_it;
- return *this;
- }
- inline self_type& operator--()
- {
- --m_it;
- return *this;
- }
- inline reference operator*() const
- {
- return m_it->first;
- }
- inline pointer operator->() const
- {
- return&(m_it->first);
- }
- inline bool operator==(const self_type& rhs) const
- {
- return m_it == rhs.m_it;
- }
- private:
- subiterator m_it;
- };
- /*******************
- * xvalue_iterator *
- *******************/
- namespace detail
- {
- template <class M>
- struct xvalue_iterator_types
- {
- using subiterator = typename M::iterator;
- using value_type = typename M::mapped_type;
- using reference = value_type&;
- using pointer = value_type*;
- using difference_type = typename subiterator::difference_type;
- };
- template <class M>
- struct xvalue_iterator_types<const M>
- {
- using subiterator = typename M::const_iterator;
- using value_type = typename M::mapped_type;
- using reference = const value_type&;
- using pointer = const value_type*;
- using difference_type = typename subiterator::difference_type;
- };
- }
- template <class M>
- class xvalue_iterator : xbidirectional_iterator_base3<xvalue_iterator<M>,
- detail::xvalue_iterator_types<M>>
- {
- public:
- using self_type = xvalue_iterator<M>;
- using base_type = xbidirectional_iterator_base3<self_type, detail::xvalue_iterator_types<M>>;
- using value_type = typename base_type::value_type;
- using reference = typename base_type::reference;
- using pointer = typename base_type::pointer;
- using difference_type = typename base_type::difference_type;
- using subiterator = typename detail::xvalue_iterator_types<M>::subiterator;
- inline xvalue_iterator(subiterator it) noexcept
- : m_it(it)
- {
- }
- inline self_type& operator++()
- {
- ++m_it;
- return *this;
- }
- inline self_type& operator--()
- {
- --m_it;
- return *this;
- }
- inline reference operator*() const
- {
- return m_it->second;
- }
- inline pointer operator->() const
- {
- return&(m_it->second);
- }
- inline bool operator==(const self_type& rhs) const
- {
- return m_it == rhs.m_it;
- }
- private:
- subiterator m_it;
- };
- /**********************
- * xstepping_iterator *
- **********************/
- template <class It>
- class xstepping_iterator : public xrandom_access_iterator_base3<xstepping_iterator<It>,
- std::iterator_traits<It>>
- {
- public:
- using self_type = xstepping_iterator;
- using base_type = xrandom_access_iterator_base3<self_type, std::iterator_traits<It>>;
- using value_type = typename base_type::value_type;
- using reference = typename base_type::reference;
- using pointer = typename base_type::pointer;
- using difference_type = typename base_type::difference_type;
- using iterator_category = typename base_type::iterator_category;
- using subiterator = It;
- xstepping_iterator() = default;
- inline xstepping_iterator(subiterator it, difference_type step) noexcept
- : m_it(it), m_step(step)
- {
- }
- inline self_type& operator++()
- {
- std::advance(m_it, m_step);
- return *this;
- }
- inline self_type& operator--()
- {
- std::advance(m_it, -m_step);
- return *this;
- }
- inline self_type& operator+=(difference_type n)
- {
- std::advance(m_it, n*m_step);
- return *this;
- }
- inline self_type& operator-=(difference_type n)
- {
- std::advance(m_it, -n*m_step);
- return *this;
- }
- inline difference_type operator-(const self_type& rhs) const
- {
- return std::distance(rhs.m_it, m_it) / m_step;
- }
- inline reference operator*() const
- {
- return *m_it;
- }
- inline pointer operator->() const
- {
- return m_it;
- }
- inline bool equal(const self_type& rhs) const
- {
- return m_it == rhs.m_it && m_step == rhs.m_step;
- }
- inline bool less_than(const self_type& rhs) const
- {
- return m_it < rhs.m_it && m_step == rhs.m_step;
- }
- private:
- subiterator m_it;
- difference_type m_step;
- };
- template <class It>
- inline bool operator==(const xstepping_iterator<It>& lhs, const xstepping_iterator<It>& rhs)
- {
- return lhs.equal(rhs);
- }
- template <class It>
- inline bool operator<(const xstepping_iterator<It>& lhs, const xstepping_iterator<It>& rhs)
- {
- return lhs.less_than(rhs);
- }
- template <class It>
- inline xstepping_iterator<It> make_stepping_iterator(It it, typename std::iterator_traits<It>::difference_type step)
- {
- return xstepping_iterator<It>(it, step);
- }
- /***********************
- * common_iterator_tag *
- ***********************/
- template <class... Its>
- struct common_iterator_tag : std::common_type<typename std::iterator_traits<Its>::iterator_category...>
- {
- };
- template <class... Its>
- using common_iterator_tag_t = typename common_iterator_tag<Its...>::type;
- }
- #endif
|