transform_iterator.hpp 5.6 KB

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