transform_iterator.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2013
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
  14. #include <boost/intrusive/detail/config_begin.hpp>
  15. #include <iterator>
  16. #include <boost/intrusive/detail/mpl.hpp>
  17. namespace boost {
  18. namespace intrusive {
  19. namespace detail {
  20. template <class PseudoReference>
  21. struct operator_arrow_proxy
  22. {
  23. operator_arrow_proxy(const PseudoReference &px)
  24. : m_value(px)
  25. {}
  26. PseudoReference* operator->() const { return &m_value; }
  27. // This function is needed for MWCW and BCC, which won't call operator->
  28. // again automatically per 13.3.1.2 para 8
  29. // operator T*() const { return &m_value; }
  30. mutable PseudoReference m_value;
  31. };
  32. template <class T>
  33. struct operator_arrow_proxy<T&>
  34. {
  35. operator_arrow_proxy(T &px)
  36. : m_value(px)
  37. {}
  38. T* operator->() const { return &m_value; }
  39. // This function is needed for MWCW and BCC, which won't call operator->
  40. // again automatically per 13.3.1.2 para 8
  41. // operator T*() const { return &m_value; }
  42. T &m_value;
  43. };
  44. template <class Iterator, class UnaryFunction>
  45. class transform_iterator
  46. : public std::iterator
  47. < typename Iterator::iterator_category
  48. , typename detail::remove_reference<typename UnaryFunction::result_type>::type
  49. , typename Iterator::difference_type
  50. , operator_arrow_proxy<typename UnaryFunction::result_type>
  51. , typename UnaryFunction::result_type>
  52. {
  53. public:
  54. explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
  55. : members_(it, f)
  56. {}
  57. explicit transform_iterator()
  58. : members_()
  59. {}
  60. Iterator get_it() const
  61. { return members_.m_it; }
  62. //Constructors
  63. transform_iterator& operator++()
  64. { increment(); return *this; }
  65. transform_iterator operator++(int)
  66. {
  67. transform_iterator result (*this);
  68. increment();
  69. return result;
  70. }
  71. friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
  72. { return i.equal(i2); }
  73. friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
  74. { return !(i == i2); }
  75. /*
  76. friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
  77. { return i2 < i; }
  78. friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
  79. { return !(i > i2); }
  80. friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
  81. { return !(i < i2); }
  82. */
  83. friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
  84. { return i2.distance_to(i); }
  85. //Arithmetic
  86. transform_iterator& operator+=(typename Iterator::difference_type off)
  87. { this->advance(off); return *this; }
  88. transform_iterator operator+(typename Iterator::difference_type off) const
  89. {
  90. transform_iterator other(*this);
  91. other.advance(off);
  92. return other;
  93. }
  94. friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
  95. { return right + off; }
  96. transform_iterator& operator-=(typename Iterator::difference_type off)
  97. { this->advance(-off); return *this; }
  98. transform_iterator operator-(typename Iterator::difference_type off) const
  99. { return *this + (-off); }
  100. typename UnaryFunction::result_type operator*() const
  101. { return dereference(); }
  102. operator_arrow_proxy<typename UnaryFunction::result_type>
  103. operator->() const
  104. { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
  105. private:
  106. struct members
  107. : UnaryFunction
  108. {
  109. members(const Iterator &it, const UnaryFunction &f)
  110. : UnaryFunction(f), m_it(it)
  111. {}
  112. members()
  113. {}
  114. Iterator m_it;
  115. } members_;
  116. void increment()
  117. { ++members_.m_it; }
  118. void decrement()
  119. { --members_.m_it; }
  120. bool equal(const transform_iterator &other) const
  121. { return members_.m_it == other.members_.m_it; }
  122. bool less(const transform_iterator &other) const
  123. { return other.members_.m_it < members_.m_it; }
  124. typename UnaryFunction::result_type dereference() const
  125. { return members_(*members_.m_it); }
  126. void advance(typename Iterator::difference_type n)
  127. { std::advance(members_.m_it, n); }
  128. typename Iterator::difference_type distance_to(const transform_iterator &other)const
  129. { return std::distance(other.members_.m_it, members_.m_it); }
  130. };
  131. } //namespace detail
  132. } //namespace intrusive
  133. } //namespace boost
  134. #include <boost/intrusive/detail/config_end.hpp>
  135. #endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP