span.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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_CORE_SPAN_HPP
  10. #define BOOST_BEAST_CORE_SPAN_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/beast/core/detail/type_traits.hpp>
  13. #include <algorithm>
  14. #include <iterator>
  15. #include <string>
  16. #include <type_traits>
  17. namespace boost {
  18. namespace beast {
  19. /** A range of bytes expressed as a ContiguousContainer
  20. This class implements a non-owning reference to a storage
  21. area of a certain size and having an underlying integral
  22. type with size of 1.
  23. @tparam T The type pointed to by span iterators
  24. */
  25. template<class T>
  26. class span
  27. {
  28. T* data_ = nullptr;
  29. std::size_t size_ = 0;
  30. public:
  31. /// The type of value, including cv qualifiers
  32. using element_type = T;
  33. /// The type of value of each span element
  34. using value_type = typename std::remove_const<T>::type;
  35. /// The type of integer used to index the span
  36. using index_type = std::ptrdiff_t;
  37. /// A pointer to a span element
  38. using pointer = T*;
  39. /// A reference to a span element
  40. using reference = T&;
  41. /// The iterator used by the container
  42. using iterator = pointer;
  43. /// The const pointer used by the container
  44. using const_pointer = T const*;
  45. /// The const reference used by the container
  46. using const_reference = T const&;
  47. /// The const iterator used by the container
  48. using const_iterator = const_pointer;
  49. /// Constructor
  50. span() = default;
  51. /// Constructor
  52. span(span const&) = default;
  53. /// Assignment
  54. span& operator=(span const&) = default;
  55. /** Constructor
  56. @param data A pointer to the beginning of the range of elements
  57. @param size The number of elements pointed to by `data`
  58. */
  59. span(T* data, std::size_t size)
  60. : data_(data), size_(size)
  61. {
  62. }
  63. /** Constructor
  64. @param container The container to construct from
  65. */
  66. template<class ContiguousContainer
  67. #if ! BOOST_BEAST_DOXYGEN
  68. , class = typename std::enable_if<
  69. detail::is_contiguous_container<
  70. ContiguousContainer, T>::value>::type
  71. #endif
  72. >
  73. explicit
  74. span(ContiguousContainer&& container)
  75. : data_(container.data())
  76. , size_(container.size())
  77. {
  78. }
  79. #if ! BOOST_BEAST_DOXYGEN
  80. template<class CharT, class Traits, class Allocator>
  81. explicit
  82. span(std::basic_string<CharT, Traits, Allocator>& s)
  83. : data_(&s[0])
  84. , size_(s.size())
  85. {
  86. }
  87. template<class CharT, class Traits, class Allocator>
  88. explicit
  89. span(std::basic_string<CharT, Traits, Allocator> const& s)
  90. : data_(s.data())
  91. , size_(s.size())
  92. {
  93. }
  94. #endif
  95. /** Assignment
  96. @param container The container to assign from
  97. */
  98. template<class ContiguousContainer>
  99. #if BOOST_BEAST_DOXYGEN
  100. span&
  101. #else
  102. typename std::enable_if<detail::is_contiguous_container<
  103. ContiguousContainer, T>::value,
  104. span&>::type
  105. #endif
  106. operator=(ContiguousContainer&& container)
  107. {
  108. data_ = container.data();
  109. size_ = container.size();
  110. return *this;
  111. }
  112. #if ! BOOST_BEAST_DOXYGEN
  113. template<class CharT, class Traits, class Allocator>
  114. span&
  115. operator=(std::basic_string<
  116. CharT, Traits, Allocator>& s)
  117. {
  118. data_ = &s[0];
  119. size_ = s.size();
  120. return *this;
  121. }
  122. template<class CharT, class Traits, class Allocator>
  123. span&
  124. operator=(std::basic_string<
  125. CharT, Traits, Allocator> const& s)
  126. {
  127. data_ = s.data();
  128. size_ = s.size();
  129. return *this;
  130. }
  131. #endif
  132. /// Returns `true` if the span is empty
  133. bool
  134. empty() const
  135. {
  136. return size_ == 0;
  137. }
  138. /// Returns a pointer to the beginning of the span
  139. T*
  140. data() const
  141. {
  142. return data_;
  143. }
  144. /// Returns the number of elements in the span
  145. std::size_t
  146. size() const
  147. {
  148. return size_;
  149. }
  150. /// Returns an iterator to the beginning of the span
  151. const_iterator
  152. begin() const
  153. {
  154. return data_;
  155. }
  156. /// Returns an iterator to the beginning of the span
  157. const_iterator
  158. cbegin() const
  159. {
  160. return data_;
  161. }
  162. /// Returns an iterator to one past the end of the span
  163. const_iterator
  164. end() const
  165. {
  166. return data_ + size_;
  167. }
  168. /// Returns an iterator to one past the end of the span
  169. const_iterator
  170. cend() const
  171. {
  172. return data_ + size_;
  173. }
  174. };
  175. } // beast
  176. } // boost
  177. #endif