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_BUFFER_TRAITS_HPP 11 #define BOOST_BEAST_BUFFER_TRAITS_HPP 12 13 #include <boost/beast/core/detail/config.hpp> 14 #include <boost/beast/core/detail/buffer_traits.hpp> 15 #include <boost/beast/core/detail/static_const.hpp> 16 #include <boost/asio/buffer.hpp> 17 #include <boost/config/workaround.hpp> 18 #include <boost/mp11/function.hpp> 19 #include <type_traits> 20 21 namespace boost { 22 namespace beast { 23 24 /** Determine if a list of types satisfy the <em>ConstBufferSequence</em> requirements. 25 26 This metafunction is used to determine if all of the specified types 27 meet the requirements for constant buffer sequences. This type alias 28 will be `std::true_type` if each specified type meets the requirements, 29 otherwise, this type alias will be `std::false_type`. 30 31 @tparam BufferSequence A list of zero or more types to check. If this 32 list is empty, the resulting type alias will be `std::true_type`. 33 */ 34 template<class... BufferSequence> 35 #if BOOST_BEAST_DOXYGEN 36 using is_const_buffer_sequence = __see_below__; 37 #else 38 using is_const_buffer_sequence = mp11::mp_all< 39 net::is_const_buffer_sequence< 40 typename std::decay<BufferSequence>::type>...>; 41 #endif 42 43 /** Determine if a list of types satisfy the <em>MutableBufferSequence</em> requirements. 44 45 This metafunction is used to determine if all of the specified types 46 meet the requirements for mutable buffer sequences. This type alias 47 will be `std::true_type` if each specified type meets the requirements, 48 otherwise, this type alias will be `std::false_type`. 49 50 @tparam BufferSequence A list of zero or more types to check. If this 51 list is empty, the resulting type alias will be `std::true_type`. 52 */ 53 template<class... BufferSequence> 54 #if BOOST_BEAST_DOXYGEN 55 using is_mutable_buffer_sequence = __see_below__; 56 #else 57 using is_mutable_buffer_sequence = mp11::mp_all< 58 net::is_mutable_buffer_sequence< 59 typename std::decay<BufferSequence>::type>...>; 60 #endif 61 62 /** Type alias for the underlying buffer type of a list of buffer sequence types. 63 64 This metafunction is used to determine the underlying buffer type for 65 a list of buffer sequence. The equivalent type of the alias will vary 66 depending on the template type argument: 67 68 @li If every type in the list is a <em>MutableBufferSequence</em>, 69 the resulting type alias will be `net::mutable_buffer`, otherwise 70 71 @li The resulting type alias will be `net::const_buffer`. 72 73 @par Example 74 The following code returns the first buffer in a buffer sequence, 75 or generates a compilation error if the argument is not a buffer 76 sequence: 77 @code 78 template <class BufferSequence> 79 buffers_type <BufferSequence> 80 buffers_front (BufferSequence const& buffers) 81 { 82 static_assert( 83 net::is_const_buffer_sequence<BufferSequence>::value, 84 "BufferSequence type requirements not met"); 85 auto const first = net::buffer_sequence_begin (buffers); 86 if (first == net::buffer_sequence_end (buffers)) 87 return {}; 88 return *first; 89 } 90 @endcode 91 92 @tparam BufferSequence A list of zero or more types to check. If this 93 list is empty, the resulting type alias will be `net::mutable_buffer`. 94 */ 95 template<class... BufferSequence> 96 #if BOOST_BEAST_DOXYGEN 97 using buffers_type = __see_below__; 98 #else 99 using buffers_type = typename std::conditional< 100 is_mutable_buffer_sequence<BufferSequence...>::value, 101 net::mutable_buffer, net::const_buffer>::type; 102 #endif 103 104 /** Type alias for the iterator type of a buffer sequence type. 105 106 This metafunction is used to determine the type of iterator 107 used by a particular buffer sequence. 108 109 @tparam T The buffer sequence type to use. The resulting 110 type alias will be equal to the iterator type used by 111 the buffer sequence. 112 */ 113 template <class BufferSequence> 114 #if BOOST_BEAST_DOXYGEN 115 using buffers_iterator_type = __see_below__; 116 #elif BOOST_WORKAROUND(BOOST_MSVC, < 1910) 117 using buffers_iterator_type = typename 118 detail::buffers_iterator_type_helper< 119 typename std::decay<BufferSequence>::type>::type; 120 #else 121 using buffers_iterator_type = 122 decltype(net::buffer_sequence_begin( 123 std::declval<BufferSequence const&>())); 124 #endif 125 126 /** Return the total number of bytes in a buffer or buffer sequence 127 128 This function returns the total number of bytes in a buffer, 129 buffer sequence, or object convertible to a buffer. Specifically 130 it may be passed: 131 132 @li A <em>ConstBufferSequence</em> or <em>MutableBufferSequence</em> 133 134 @li A `net::const_buffer` or `net::mutable_buffer` 135 136 @li An object convertible to `net::const_buffer` 137 138 This function is designed as an easier-to-use replacement for 139 `net::buffer_size`. It recognizes customization points found through 140 argument-dependent lookup. The call `beast::buffer_bytes(b)` is 141 equivalent to performing: 142 @code 143 using net::buffer_size; 144 return buffer_size(b); 145 @endcode 146 In addition this handles types which are convertible to 147 `net::const_buffer`; these are not handled by `net::buffer_size`. 148 149 @param buffers The buffer or buffer sequence to calculate the size of. 150 151 @return The total number of bytes in the buffer or sequence. 152 */ 153 #if BOOST_BEAST_DOXYGEN 154 template<class BufferSequence> 155 std::size_t 156 buffer_bytes(BufferSequence const& buffers); 157 #else 158 BOOST_BEAST_INLINE_VARIABLE(buffer_bytes, detail::buffer_bytes_impl) 159 #endif 160 161 } // beast 162 } // boost 163 164 #endif 165