File indexing completed on 2025-01-18 09:30:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
0015 #define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
0016
0017 #ifndef BOOST_CONFIG_HPP
0018 # include <boost/config.hpp>
0019 #endif
0020
0021 #if defined(BOOST_HAS_PRAGMA_ONCE)
0022 # pragma once
0023 #endif
0024
0025 #include <boost/container/detail/config_begin.hpp>
0026 #include <boost/container/detail/workaround.hpp>
0027 #include <boost/container/detail/type_traits.hpp>
0028 #include <boost/container/detail/iterator.hpp>
0029
0030 namespace boost {
0031 namespace container {
0032
0033 template <class PseudoReference>
0034 struct operator_arrow_proxy
0035 {
0036 BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(const PseudoReference &px)
0037 : m_value(px)
0038 {}
0039
0040 typedef PseudoReference element_type;
0041
0042 BOOST_CONTAINER_FORCEINLINE PseudoReference* operator->() const { return &m_value; }
0043
0044 mutable PseudoReference m_value;
0045 };
0046
0047 template <class T>
0048 struct operator_arrow_proxy<T&>
0049 {
0050 BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(T &px)
0051 : m_value(px)
0052 {}
0053
0054 typedef T element_type;
0055
0056 BOOST_CONTAINER_FORCEINLINE T* operator->() const { return const_cast<T*>(&m_value); }
0057
0058 T &m_value;
0059 };
0060
0061 template <class Iterator, class UnaryFunction>
0062 class transform_iterator
0063 : public UnaryFunction
0064 , public boost::container::iterator
0065 < typename Iterator::iterator_category
0066 , typename dtl::remove_reference<typename UnaryFunction::result_type>::type
0067 , typename Iterator::difference_type
0068 , operator_arrow_proxy<typename UnaryFunction::result_type>
0069 , typename UnaryFunction::result_type>
0070 {
0071 public:
0072 BOOST_CONTAINER_FORCEINLINE explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
0073 : UnaryFunction(f), m_it(it)
0074 {}
0075
0076 BOOST_CONTAINER_FORCEINLINE explicit transform_iterator()
0077 : UnaryFunction(), m_it()
0078 {}
0079
0080
0081 BOOST_CONTAINER_FORCEINLINE transform_iterator& operator++()
0082 { increment(); return *this; }
0083
0084 BOOST_CONTAINER_FORCEINLINE transform_iterator operator++(int)
0085 {
0086 transform_iterator result (*this);
0087 increment();
0088 return result;
0089 }
0090
0091 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
0092 { return i.equal(i2); }
0093
0094 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
0095 { return !(i == i2); }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 BOOST_CONTAINER_FORCEINLINE friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
0108 { return i2.distance_to(i); }
0109
0110
0111 BOOST_CONTAINER_FORCEINLINE transform_iterator& operator+=(typename Iterator::difference_type off)
0112 { this->advance(off); return *this; }
0113
0114 BOOST_CONTAINER_FORCEINLINE transform_iterator operator+(typename Iterator::difference_type off) const
0115 {
0116 transform_iterator other(*this);
0117 other.advance(off);
0118 return other;
0119 }
0120
0121 BOOST_CONTAINER_FORCEINLINE friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
0122 { return right + off; }
0123
0124 BOOST_CONTAINER_FORCEINLINE transform_iterator& operator-=(typename Iterator::difference_type off)
0125 { this->advance(-off); return *this; }
0126
0127 BOOST_CONTAINER_FORCEINLINE transform_iterator operator-(typename Iterator::difference_type off) const
0128 { return *this + (-off); }
0129
0130 BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type operator*() const
0131 { return dereference(); }
0132
0133 BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy<typename UnaryFunction::result_type>
0134 operator->() const
0135 { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
0136
0137 BOOST_CONTAINER_FORCEINLINE Iterator & base()
0138 { return m_it; }
0139
0140 BOOST_CONTAINER_FORCEINLINE const Iterator & base() const
0141 { return m_it; }
0142
0143 private:
0144 Iterator m_it;
0145
0146 BOOST_CONTAINER_FORCEINLINE void increment()
0147 { ++m_it; }
0148
0149 BOOST_CONTAINER_FORCEINLINE void decrement()
0150 { --m_it; }
0151
0152 BOOST_CONTAINER_FORCEINLINE bool equal(const transform_iterator &other) const
0153 { return m_it == other.m_it; }
0154
0155 BOOST_CONTAINER_FORCEINLINE bool less(const transform_iterator &other) const
0156 { return other.m_it < m_it; }
0157
0158 BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type dereference() const
0159 { return UnaryFunction::operator()(*m_it); }
0160
0161 BOOST_CONTAINER_FORCEINLINE void advance(typename Iterator::difference_type n)
0162 { boost::container::iterator_advance(m_it, n); }
0163
0164 BOOST_CONTAINER_FORCEINLINE typename Iterator::difference_type distance_to(const transform_iterator &other)const
0165 { return boost::container::iterator_distance(other.m_it, m_it); }
0166 };
0167
0168 template <class Iterator, class UnaryFunc>
0169 BOOST_CONTAINER_FORCEINLINE transform_iterator<Iterator, UnaryFunc>
0170 make_transform_iterator(Iterator it, UnaryFunc fun)
0171 {
0172 return transform_iterator<Iterator, UnaryFunc>(it, fun);
0173 }
0174
0175 }
0176 }
0177
0178 #include <boost/container/detail/config_end.hpp>
0179
0180 #endif