buffers_suffix.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_IMPL_BUFFERS_SUFFIX_HPP
  10. #define BOOST_BEAST_IMPL_BUFFERS_SUFFIX_HPP
  11. #include <boost/beast/core/buffer_traits.hpp>
  12. #include <boost/beast/core/buffer_traits.hpp>
  13. #include <boost/type_traits.hpp>
  14. #include <algorithm>
  15. #include <cstdint>
  16. #include <iterator>
  17. #include <type_traits>
  18. #include <utility>
  19. namespace boost {
  20. namespace beast {
  21. template<class Buffers>
  22. class buffers_suffix<Buffers>::const_iterator
  23. {
  24. friend class buffers_suffix<Buffers>;
  25. using iter_type = buffers_iterator_type<Buffers>;
  26. iter_type it_{};
  27. buffers_suffix const* b_ = nullptr;
  28. public:
  29. #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
  30. using value_type = typename std::conditional<
  31. boost::is_convertible<typename
  32. std::iterator_traits<iter_type>::value_type,
  33. net::mutable_buffer>::value,
  34. net::mutable_buffer,
  35. net::const_buffer>::type;
  36. #else
  37. using value_type = buffers_type<Buffers>;
  38. #endif
  39. using pointer = value_type const*;
  40. using reference = value_type;
  41. using difference_type = std::ptrdiff_t;
  42. using iterator_category =
  43. std::bidirectional_iterator_tag;
  44. const_iterator() = default;
  45. const_iterator(
  46. const_iterator const& other) = default;
  47. const_iterator& operator=(
  48. const_iterator const& other) = default;
  49. bool
  50. operator==(const_iterator const& other) const
  51. {
  52. return b_ == other.b_ && it_ == other.it_;
  53. }
  54. bool
  55. operator!=(const_iterator const& other) const
  56. {
  57. return !(*this == other);
  58. }
  59. reference
  60. operator*() const
  61. {
  62. if(it_ == b_->begin_)
  63. return value_type(*it_) + b_->skip_;
  64. return value_type(*it_);
  65. }
  66. pointer
  67. operator->() const = delete;
  68. const_iterator&
  69. operator++()
  70. {
  71. ++it_;
  72. return *this;
  73. }
  74. const_iterator
  75. operator++(int)
  76. {
  77. auto temp = *this;
  78. ++(*this);
  79. return temp;
  80. }
  81. const_iterator&
  82. operator--()
  83. {
  84. --it_;
  85. return *this;
  86. }
  87. const_iterator
  88. operator--(int)
  89. {
  90. auto temp = *this;
  91. --(*this);
  92. return temp;
  93. }
  94. private:
  95. const_iterator(
  96. buffers_suffix const& b,
  97. iter_type it)
  98. : it_(it)
  99. , b_(&b)
  100. {
  101. }
  102. };
  103. //------------------------------------------------------------------------------
  104. template<class Buffers>
  105. buffers_suffix<Buffers>::
  106. buffers_suffix()
  107. : begin_(net::buffer_sequence_begin(bs_))
  108. {
  109. }
  110. template<class Buffers>
  111. buffers_suffix<Buffers>::
  112. buffers_suffix(buffers_suffix const& other)
  113. : buffers_suffix(other,
  114. std::distance<iter_type>(
  115. net::buffer_sequence_begin(
  116. other.bs_), other.begin_))
  117. {
  118. }
  119. template<class Buffers>
  120. buffers_suffix<Buffers>::
  121. buffers_suffix(Buffers const& bs)
  122. : bs_(bs)
  123. , begin_(net::buffer_sequence_begin(bs_))
  124. {
  125. static_assert(
  126. net::is_const_buffer_sequence<Buffers>::value ||
  127. net::is_mutable_buffer_sequence<Buffers>::value,
  128. "BufferSequence type requirements not met");
  129. }
  130. template<class Buffers>
  131. template<class... Args>
  132. buffers_suffix<Buffers>::
  133. buffers_suffix(boost::in_place_init_t, Args&&... args)
  134. : bs_(std::forward<Args>(args)...)
  135. , begin_(net::buffer_sequence_begin(bs_))
  136. {
  137. static_assert(sizeof...(Args) > 0,
  138. "Missing constructor arguments");
  139. static_assert(
  140. std::is_constructible<Buffers, Args...>::value,
  141. "Buffers not constructible from arguments");
  142. }
  143. template<class Buffers>
  144. auto
  145. buffers_suffix<Buffers>::
  146. operator=(buffers_suffix const& other) ->
  147. buffers_suffix&
  148. {
  149. auto const dist = std::distance<iter_type>(
  150. net::buffer_sequence_begin(other.bs_),
  151. other.begin_);
  152. bs_ = other.bs_;
  153. begin_ = std::next(
  154. net::buffer_sequence_begin(bs_), dist);
  155. skip_ = other.skip_;
  156. return *this;
  157. }
  158. template<class Buffers>
  159. auto
  160. buffers_suffix<Buffers>::
  161. begin() const ->
  162. const_iterator
  163. {
  164. return const_iterator{*this, begin_};
  165. }
  166. template<class Buffers>
  167. auto
  168. buffers_suffix<Buffers>::
  169. end() const ->
  170. const_iterator
  171. {
  172. return const_iterator{*this,
  173. net::buffer_sequence_end(bs_)};
  174. }
  175. template<class Buffers>
  176. void
  177. buffers_suffix<Buffers>::
  178. consume(std::size_t amount)
  179. {
  180. auto const end =
  181. net::buffer_sequence_end(bs_);
  182. for(;amount > 0 && begin_ != end; ++begin_)
  183. {
  184. auto const len =
  185. buffer_bytes(*begin_) - skip_;
  186. if(amount < len)
  187. {
  188. skip_ += amount;
  189. break;
  190. }
  191. amount -= len;
  192. skip_ = 0;
  193. }
  194. }
  195. } // beast
  196. } // boost
  197. #endif