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