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