Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-08 08:26:33

0001 //
0002 // read_until.hpp
0003 // ~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_READ_UNTIL_HPP
0012 #define BOOST_ASIO_READ_UNTIL_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <string>
0021 #include <boost/asio/async_result.hpp>
0022 #include <boost/asio/buffer.hpp>
0023 #include <boost/asio/detail/regex_fwd.hpp>
0024 #include <boost/asio/detail/string_view.hpp>
0025 #include <boost/asio/detail/type_traits.hpp>
0026 #include <boost/asio/error.hpp>
0027 
0028 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0029 # include <boost/asio/basic_streambuf_fwd.hpp>
0030 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
0031 
0032 #include <boost/asio/detail/push_options.hpp>
0033 
0034 namespace boost {
0035 namespace asio {
0036 namespace detail {
0037 
0038 char (&has_result_type_helper(...))[2];
0039 
0040 template <typename T>
0041 char has_result_type_helper(T*, typename T::result_type* = 0);
0042 
0043 template <typename T>
0044 struct has_result_type
0045 {
0046   enum { value = (sizeof((has_result_type_helper)((T*)(0))) == 1) };
0047 };
0048 
0049 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0050 template <typename> class initiate_async_read_until_delim_v1;
0051 template <typename> class initiate_async_read_until_delim_string_v1;
0052 #if defined(BOOST_ASIO_HAS_BOOST_REGEX)
0053 template <typename> class initiate_async_read_until_expr_v1;
0054 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
0055 template <typename> class initiate_async_read_until_match_v1;
0056 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0057 template <typename> class initiate_async_read_until_delim_v2;
0058 template <typename> class initiate_async_read_until_delim_string_v2;
0059 #if defined(BOOST_ASIO_HAS_BOOST_REGEX)
0060 template <typename> class initiate_async_read_until_expr_v2;
0061 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
0062 template <typename> class initiate_async_read_until_match_v2;
0063 
0064 } // namespace detail
0065 
0066 /// Type trait used to determine whether a type can be used as a match condition
0067 /// function with read_until and async_read_until.
0068 template <typename T>
0069 struct is_match_condition
0070 {
0071 #if defined(GENERATING_DOCUMENTATION)
0072   /// The value member is true if the type may be used as a match condition.
0073   static const bool value;
0074 #else
0075   enum
0076   {
0077     value = boost::asio::is_function<remove_pointer_t<T>>::value
0078       || detail::has_result_type<T>::value
0079   };
0080 #endif
0081 };
0082 
0083 /**
0084  * @defgroup read_until boost::asio::read_until
0085  *
0086  * @brief The @c read_until function is a composed operation that reads data
0087  * into a dynamic buffer sequence, or into a streambuf, until it contains a
0088  * delimiter, matches a regular expression, or a function object indicates a
0089  * match.
0090  */
0091 /*@{*/
0092 
0093 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0094 
0095 /// Read data into a dynamic buffer sequence until it contains a specified
0096 /// delimiter.
0097 /**
0098  * This function is used to read data into the specified dynamic buffer
0099  * sequence until the dynamic buffer sequence's get area contains the specified
0100  * delimiter. The call will block until one of the following conditions is
0101  * true:
0102  *
0103  * @li The get area of the dynamic buffer sequence contains the specified
0104  * delimiter.
0105  *
0106  * @li An error occurred.
0107  *
0108  * This operation is implemented in terms of zero or more calls to the stream's
0109  * read_some function. If the dynamic buffer sequence's get area already
0110  * contains the delimiter, the function returns immediately.
0111  *
0112  * @param s The stream from which the data is to be read. The type must support
0113  * the SyncReadStream concept.
0114  *
0115  * @param buffers The dynamic buffer sequence into which the data will be read.
0116  *
0117  * @param delim The delimiter character.
0118  *
0119  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0120  * and including the delimiter.
0121  *
0122  * @throws boost::system::system_error Thrown on failure.
0123  *
0124  * @note After a successful read_until operation, the dynamic buffer sequence
0125  * may contain additional data beyond the delimiter. An application will
0126  * typically leave that data in the dynamic buffer sequence for a subsequent
0127  * read_until operation to examine.
0128  *
0129  * @par Example
0130  * To read data into a @c std::string until a newline is encountered:
0131  * @code std::string data;
0132  * std::size_t n = boost::asio::read_until(s,
0133  *     boost::asio::dynamic_buffer(data), '\n');
0134  * std::string line = data.substr(0, n);
0135  * data.erase(0, n); @endcode
0136  * After the @c read_until operation completes successfully, the string @c data
0137  * contains the delimiter:
0138  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
0139  * The call to @c substr then extracts the data up to and including the
0140  * delimiter, so that the string @c line contains:
0141  * @code { 'a', 'b', ..., 'c', '\n' } @endcode
0142  * After the call to @c erase, the remaining data is left in the buffer @c b as
0143  * follows:
0144  * @code { 'd', 'e', ... } @endcode
0145  * This data may be the start of a new line, to be extracted by a subsequent
0146  * @c read_until operation.
0147  */
0148 template <typename SyncReadStream, typename DynamicBuffer_v1>
0149 std::size_t read_until(SyncReadStream& s,
0150     DynamicBuffer_v1&& buffers, char delim,
0151     constraint_t<
0152       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0153     > = 0,
0154     constraint_t<
0155       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0156     > = 0);
0157 
0158 /// Read data into a dynamic buffer sequence until it contains a specified
0159 /// delimiter.
0160 /**
0161  * This function is used to read data into the specified dynamic buffer
0162  * sequence until the dynamic buffer sequence's get area contains the specified
0163  * delimiter. The call will block until one of the following conditions is
0164  * true:
0165  *
0166  * @li The get area of the dynamic buffer sequence contains the specified
0167  * delimiter.
0168  *
0169  * @li An error occurred.
0170  *
0171  * This operation is implemented in terms of zero or more calls to the stream's
0172  * read_some function. If the dynamic buffer sequence's get area already
0173  * contains the delimiter, the function returns immediately.
0174  *
0175  * @param s The stream from which the data is to be read. The type must support
0176  * the SyncReadStream concept.
0177  *
0178  * @param buffers The dynamic buffer sequence into which the data will be read.
0179  *
0180  * @param delim The delimiter character.
0181  *
0182  * @param ec Set to indicate what error occurred, if any.
0183  *
0184  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0185  * and including the delimiter. Returns 0 if an error occurred.
0186  *
0187  * @note After a successful read_until operation, the dynamic buffer sequence
0188  * may contain additional data beyond the delimiter. An application will
0189  * typically leave that data in the dynamic buffer sequence for a subsequent
0190  * read_until operation to examine.
0191  */
0192 template <typename SyncReadStream, typename DynamicBuffer_v1>
0193 std::size_t read_until(SyncReadStream& s,
0194     DynamicBuffer_v1&& buffers,
0195     char delim, boost::system::error_code& ec,
0196     constraint_t<
0197       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0198     > = 0,
0199     constraint_t<
0200       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0201     > = 0);
0202 
0203 /// Read data into a dynamic buffer sequence until it contains a specified
0204 /// delimiter.
0205 /**
0206  * This function is used to read data into the specified dynamic buffer
0207  * sequence until the dynamic buffer sequence's get area contains the specified
0208  * delimiter. The call will block until one of the following conditions is
0209  * true:
0210  *
0211  * @li The get area of the dynamic buffer sequence contains the specified
0212  * delimiter.
0213  *
0214  * @li An error occurred.
0215  *
0216  * This operation is implemented in terms of zero or more calls to the stream's
0217  * read_some function. If the dynamic buffer sequence's get area already
0218  * contains the delimiter, the function returns immediately.
0219  *
0220  * @param s The stream from which the data is to be read. The type must support
0221  * the SyncReadStream concept.
0222  *
0223  * @param buffers The dynamic buffer sequence into which the data will be read.
0224  *
0225  * @param delim The delimiter string.
0226  *
0227  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0228  * and including the delimiter.
0229  *
0230  * @note After a successful read_until operation, the dynamic buffer sequence
0231  * may contain additional data beyond the delimiter. An application will
0232  * typically leave that data in the dynamic buffer sequence for a subsequent
0233  * read_until operation to examine.
0234  *
0235  * @par Example
0236  * To read data into a @c std::string until a CR-LF sequence is encountered:
0237  * @code std::string data;
0238  * std::size_t n = boost::asio::read_until(s,
0239  *     boost::asio::dynamic_buffer(data), "\r\n");
0240  * std::string line = data.substr(0, n);
0241  * data.erase(0, n); @endcode
0242  * After the @c read_until operation completes successfully, the string @c data
0243  * contains the delimiter:
0244  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
0245  * The call to @c substr then extracts the data up to and including the
0246  * delimiter, so that the string @c line contains:
0247  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
0248  * After the call to @c erase, the remaining data is left in the buffer @c b as
0249  * follows:
0250  * @code { 'd', 'e', ... } @endcode
0251  * This data may be the start of a new line, to be extracted by a subsequent
0252  * @c read_until operation.
0253  */
0254 template <typename SyncReadStream, typename DynamicBuffer_v1>
0255 std::size_t read_until(SyncReadStream& s,
0256     DynamicBuffer_v1&& buffers,
0257     BOOST_ASIO_STRING_VIEW_PARAM delim,
0258     constraint_t<
0259       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0260     > = 0,
0261     constraint_t<
0262       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0263     > = 0);
0264 
0265 /// Read data into a dynamic buffer sequence until it contains a specified
0266 /// delimiter.
0267 /**
0268  * This function is used to read data into the specified dynamic buffer
0269  * sequence until the dynamic buffer sequence's get area contains the specified
0270  * delimiter. The call will block until one of the following conditions is
0271  * true:
0272  *
0273  * @li The get area of the dynamic buffer sequence contains the specified
0274  * delimiter.
0275  *
0276  * @li An error occurred.
0277  *
0278  * This operation is implemented in terms of zero or more calls to the stream's
0279  * read_some function. If the dynamic buffer sequence's get area already
0280  * contains the delimiter, the function returns immediately.
0281  *
0282  * @param s The stream from which the data is to be read. The type must support
0283  * the SyncReadStream concept.
0284  *
0285  * @param buffers The dynamic buffer sequence into which the data will be read.
0286  *
0287  * @param delim The delimiter string.
0288  *
0289  * @param ec Set to indicate what error occurred, if any.
0290  *
0291  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0292  * and including the delimiter. Returns 0 if an error occurred.
0293  *
0294  * @note After a successful read_until operation, the dynamic buffer sequence
0295  * may contain additional data beyond the delimiter. An application will
0296  * typically leave that data in the dynamic buffer sequence for a subsequent
0297  * read_until operation to examine.
0298  */
0299 template <typename SyncReadStream, typename DynamicBuffer_v1>
0300 std::size_t read_until(SyncReadStream& s,
0301     DynamicBuffer_v1&& buffers,
0302     BOOST_ASIO_STRING_VIEW_PARAM delim,
0303     boost::system::error_code& ec,
0304     constraint_t<
0305       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0306     > = 0,
0307     constraint_t<
0308       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0309     > = 0);
0310 
0311 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0312 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
0313   || defined(GENERATING_DOCUMENTATION)
0314 
0315 /// Read data into a dynamic buffer sequence until some part of the data it
0316 /// contains matches a regular expression.
0317 /**
0318  * This function is used to read data into the specified dynamic buffer
0319  * sequence until the dynamic buffer sequence's get area contains some data
0320  * that matches a regular expression. The call will block until one of the
0321  * following conditions is true:
0322  *
0323  * @li A substring of the dynamic buffer sequence's get area matches the
0324  * regular expression.
0325  *
0326  * @li An error occurred.
0327  *
0328  * This operation is implemented in terms of zero or more calls to the stream's
0329  * read_some function. If the dynamic buffer sequence's get area already
0330  * contains data that matches the regular expression, the function returns
0331  * immediately.
0332  *
0333  * @param s The stream from which the data is to be read. The type must support
0334  * the SyncReadStream concept.
0335  *
0336  * @param buffers A dynamic buffer sequence into which the data will be read.
0337  *
0338  * @param expr The regular expression.
0339  *
0340  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0341  * and including the substring that matches the regular expression.
0342  *
0343  * @throws boost::system::system_error Thrown on failure.
0344  *
0345  * @note After a successful read_until operation, the dynamic buffer sequence
0346  * may contain additional data beyond that which matched the regular
0347  * expression. An application will typically leave that data in the dynamic
0348  * buffer sequence for a subsequent read_until operation to examine.
0349  *
0350  * @par Example
0351  * To read data into a @c std::string until a CR-LF sequence is encountered:
0352  * @code std::string data;
0353  * std::size_t n = boost::asio::read_until(s,
0354  *     boost::asio::dynamic_buffer(data), boost::regex("\r\n"));
0355  * std::string line = data.substr(0, n);
0356  * data.erase(0, n); @endcode
0357  * After the @c read_until operation completes successfully, the string @c data
0358  * contains the delimiter:
0359  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
0360  * The call to @c substr then extracts the data up to and including the
0361  * delimiter, so that the string @c line contains:
0362  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
0363  * After the call to @c erase, the remaining data is left in the buffer @c b as
0364  * follows:
0365  * @code { 'd', 'e', ... } @endcode
0366  * This data may be the start of a new line, to be extracted by a subsequent
0367  * @c read_until operation.
0368  */
0369 template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>
0370 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,
0371     const boost::basic_regex<char, Traits>& expr,
0372     constraint_t<
0373       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0374     > = 0,
0375     constraint_t<
0376       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0377     > = 0);
0378 
0379 /// Read data into a dynamic buffer sequence until some part of the data it
0380 /// contains matches a regular expression.
0381 /**
0382  * This function is used to read data into the specified dynamic buffer
0383  * sequence until the dynamic buffer sequence's get area contains some data
0384  * that matches a regular expression. The call will block until one of the
0385  * following conditions is true:
0386  *
0387  * @li A substring of the dynamic buffer sequence's get area matches the
0388  * regular expression.
0389  *
0390  * @li An error occurred.
0391  *
0392  * This operation is implemented in terms of zero or more calls to the stream's
0393  * read_some function. If the dynamic buffer sequence's get area already
0394  * contains data that matches the regular expression, the function returns
0395  * immediately.
0396  *
0397  * @param s The stream from which the data is to be read. The type must support
0398  * the SyncReadStream concept.
0399  *
0400  * @param buffers A dynamic buffer sequence into which the data will be read.
0401  *
0402  * @param expr The regular expression.
0403  *
0404  * @param ec Set to indicate what error occurred, if any.
0405  *
0406  * @returns The number of bytes in the dynamic buffer sequence's get area up to
0407  * and including the substring that matches the regular expression. Returns 0
0408  * if an error occurred.
0409  *
0410  * @note After a successful read_until operation, the dynamic buffer sequence
0411  * may contain additional data beyond that which matched the regular
0412  * expression. An application will typically leave that data in the dynamic
0413  * buffer sequence for a subsequent read_until operation to examine.
0414  */
0415 template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>
0416 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,
0417     const boost::basic_regex<char, Traits>& expr, boost::system::error_code& ec,
0418     constraint_t<
0419       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0420     > = 0,
0421     constraint_t<
0422       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0423     > = 0);
0424 
0425 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
0426        // || defined(GENERATING_DOCUMENTATION)
0427 
0428 /// Read data into a dynamic buffer sequence until a function object indicates a
0429 /// match.
0430 
0431 /**
0432  * This function is used to read data into the specified dynamic buffer
0433  * sequence until a user-defined match condition function object, when applied
0434  * to the data contained in the dynamic buffer sequence, indicates a successful
0435  * match. The call will block until one of the following conditions is true:
0436  *
0437  * @li The match condition function object returns a std::pair where the second
0438  * element evaluates to true.
0439  *
0440  * @li An error occurred.
0441  *
0442  * This operation is implemented in terms of zero or more calls to the stream's
0443  * read_some function. If the match condition function object already indicates
0444  * a match, the function returns immediately.
0445  *
0446  * @param s The stream from which the data is to be read. The type must support
0447  * the SyncReadStream concept.
0448  *
0449  * @param buffers A dynamic buffer sequence into which the data will be read.
0450  *
0451  * @param match_condition The function object to be called to determine whether
0452  * a match exists. The signature of the function object must be:
0453  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
0454  * @endcode
0455  * where @c iterator represents the type:
0456  * @code buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
0457  * @endcode
0458  * The iterator parameters @c begin and @c end define the range of bytes to be
0459  * scanned to determine whether there is a match. The @c first member of the
0460  * return value is an iterator marking one-past-the-end of the bytes that have
0461  * been consumed by the match function. This iterator is used to calculate the
0462  * @c begin parameter for any subsequent invocation of the match condition. The
0463  * @c second member of the return value is true if a match has been found, false
0464  * otherwise.
0465  *
0466  * @returns The number of bytes in the dynamic_buffer's get area that
0467  * have been fully consumed by the match function.
0468  *
0469  * @throws boost::system::system_error Thrown on failure.
0470  *
0471  * @note After a successful read_until operation, the dynamic buffer sequence
0472  * may contain additional data beyond that which matched the function object.
0473  * An application will typically leave that data in the dynamic buffer sequence
0474  * for a subsequent read_until operation to examine.
0475 
0476  * @note The default implementation of the @c is_match_condition type trait
0477  * evaluates to true for function pointers and function objects with a
0478  * @c result_type typedef. It must be specialised for other user-defined
0479  * function objects.
0480  *
0481  * @par Examples
0482  * To read data into a dynamic buffer sequence until whitespace is encountered:
0483  * @code typedef boost::asio::buffers_iterator<
0484  *     boost::asio::const_buffers_1> iterator;
0485  *
0486  * std::pair<iterator, bool>
0487  * match_whitespace(iterator begin, iterator end)
0488  * {
0489  *   iterator i = begin;
0490  *   while (i != end)
0491  *     if (std::isspace(*i++))
0492  *       return std::make_pair(i, true);
0493  *   return std::make_pair(i, false);
0494  * }
0495  * ...
0496  * std::string data;
0497  * boost::asio::read_until(s, data, match_whitespace);
0498  * @endcode
0499  *
0500  * To read data into a @c std::string until a matching character is found:
0501  * @code class match_char
0502  * {
0503  * public:
0504  *   explicit match_char(char c) : c_(c) {}
0505  *
0506  *   template <typename Iterator>
0507  *   std::pair<Iterator, bool> operator()(
0508  *       Iterator begin, Iterator end) const
0509  *   {
0510  *     Iterator i = begin;
0511  *     while (i != end)
0512  *       if (c_ == *i++)
0513  *         return std::make_pair(i, true);
0514  *     return std::make_pair(i, false);
0515  *   }
0516  *
0517  * private:
0518  *   char c_;
0519  * };
0520  *
0521  * namespace asio {
0522  *   template <> struct is_match_condition<match_char>
0523  *     : public boost::true_type {};
0524  * } // namespace asio
0525  * ...
0526  * std::string data;
0527  * boost::asio::read_until(s, data, match_char('a'));
0528  * @endcode
0529  */
0530 template <typename SyncReadStream,
0531     typename DynamicBuffer_v1, typename MatchCondition>
0532 std::size_t read_until(SyncReadStream& s,
0533     DynamicBuffer_v1&& buffers,
0534     MatchCondition match_condition,
0535     constraint_t<
0536       is_match_condition<MatchCondition>::value
0537     > = 0,
0538     constraint_t<
0539       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0540     > = 0,
0541     constraint_t<
0542       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0543     > = 0);
0544 
0545 /// Read data into a dynamic buffer sequence until a function object indicates a
0546 /// match.
0547 /**
0548  * This function is used to read data into the specified dynamic buffer
0549  * sequence until a user-defined match condition function object, when applied
0550  * to the data contained in the dynamic buffer sequence, indicates a successful
0551  * match. The call will block until one of the following conditions is true:
0552  *
0553  * @li The match condition function object returns a std::pair where the second
0554  * element evaluates to true.
0555  *
0556  * @li An error occurred.
0557  *
0558  * This operation is implemented in terms of zero or more calls to the stream's
0559  * read_some function. If the match condition function object already indicates
0560  * a match, the function returns immediately.
0561  *
0562  * @param s The stream from which the data is to be read. The type must support
0563  * the SyncReadStream concept.
0564  *
0565  * @param buffers A dynamic buffer sequence into which the data will be read.
0566  *
0567  * @param match_condition The function object to be called to determine whether
0568  * a match exists. The signature of the function object must be:
0569  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
0570  * @endcode
0571  * where @c iterator represents the type:
0572  * @code buffers_iterator<DynamicBuffer_v1::const_buffers_type>
0573  * @endcode
0574  * The iterator parameters @c begin and @c end define the range of bytes to be
0575  * scanned to determine whether there is a match. The @c first member of the
0576  * return value is an iterator marking one-past-the-end of the bytes that have
0577  * been consumed by the match function. This iterator is used to calculate the
0578  * @c begin parameter for any subsequent invocation of the match condition. The
0579  * @c second member of the return value is true if a match has been found, false
0580  * otherwise.
0581  *
0582  * @param ec Set to indicate what error occurred, if any.
0583  *
0584  * @returns The number of bytes in the dynamic buffer sequence's get area that
0585  * have been fully consumed by the match function. Returns 0 if an error
0586  * occurred.
0587  *
0588  * @note After a successful read_until operation, the dynamic buffer sequence
0589  * may contain additional data beyond that which matched the function object.
0590  * An application will typically leave that data in the dynamic buffer sequence
0591  * for a subsequent read_until operation to examine.
0592  *
0593  * @note The default implementation of the @c is_match_condition type trait
0594  * evaluates to true for function pointers and function objects with a
0595  * @c result_type typedef. It must be specialised for other user-defined
0596  * function objects.
0597  */
0598 template <typename SyncReadStream,
0599     typename DynamicBuffer_v1, typename MatchCondition>
0600 std::size_t read_until(SyncReadStream& s,
0601     DynamicBuffer_v1&& buffers,
0602     MatchCondition match_condition, boost::system::error_code& ec,
0603     constraint_t<
0604       is_match_condition<MatchCondition>::value
0605     > = 0,
0606     constraint_t<
0607       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0608     > = 0,
0609     constraint_t<
0610       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0611     > = 0);
0612 
0613 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0614 
0615 /// Read data into a streambuf until it contains a specified delimiter.
0616 /**
0617  * This function is used to read data into the specified streambuf until the
0618  * streambuf's get area contains the specified delimiter. The call will block
0619  * until one of the following conditions is true:
0620  *
0621  * @li The get area of the streambuf contains the specified delimiter.
0622  *
0623  * @li An error occurred.
0624  *
0625  * This operation is implemented in terms of zero or more calls to the stream's
0626  * read_some function. If the streambuf's get area already contains the
0627  * delimiter, the function returns immediately.
0628  *
0629  * @param s The stream from which the data is to be read. The type must support
0630  * the SyncReadStream concept.
0631  *
0632  * @param b A streambuf object into which the data will be read.
0633  *
0634  * @param delim The delimiter character.
0635  *
0636  * @returns The number of bytes in the streambuf's get area up to and including
0637  * the delimiter.
0638  *
0639  * @throws boost::system::system_error Thrown on failure.
0640  *
0641  * @note After a successful read_until operation, the streambuf may contain
0642  * additional data beyond the delimiter. An application will typically leave
0643  * that data in the streambuf for a subsequent read_until operation to examine.
0644  *
0645  * @par Example
0646  * To read data into a streambuf until a newline is encountered:
0647  * @code boost::asio::streambuf b;
0648  * boost::asio::read_until(s, b, '\n');
0649  * std::istream is(&b);
0650  * std::string line;
0651  * std::getline(is, line); @endcode
0652  * After the @c read_until operation completes successfully, the buffer @c b
0653  * contains the delimiter:
0654  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
0655  * The call to @c std::getline then extracts the data up to and including the
0656  * newline (which is discarded), so that the string @c line contains:
0657  * @code { 'a', 'b', ..., 'c' } @endcode
0658  * The remaining data is left in the buffer @c b as follows:
0659  * @code { 'd', 'e', ... } @endcode
0660  * This data may be the start of a new line, to be extracted by a subsequent
0661  * @c read_until operation.
0662  */
0663 template <typename SyncReadStream, typename Allocator>
0664 std::size_t read_until(SyncReadStream& s,
0665     boost::asio::basic_streambuf<Allocator>& b, char delim);
0666 
0667 /// Read data into a streambuf until it contains a specified delimiter.
0668 /**
0669  * This function is used to read data into the specified streambuf until the
0670  * streambuf's get area contains the specified delimiter. The call will block
0671  * until one of the following conditions is true:
0672  *
0673  * @li The get area of the streambuf contains the specified delimiter.
0674  *
0675  * @li An error occurred.
0676  *
0677  * This operation is implemented in terms of zero or more calls to the stream's
0678  * read_some function. If the streambuf's get area already contains the
0679  * delimiter, the function returns immediately.
0680  *
0681  * @param s The stream from which the data is to be read. The type must support
0682  * the SyncReadStream concept.
0683  *
0684  * @param b A streambuf object into which the data will be read.
0685  *
0686  * @param delim The delimiter character.
0687  *
0688  * @param ec Set to indicate what error occurred, if any.
0689  *
0690  * @returns The number of bytes in the streambuf's get area up to and including
0691  * the delimiter. Returns 0 if an error occurred.
0692  *
0693  * @note After a successful read_until operation, the streambuf may contain
0694  * additional data beyond the delimiter. An application will typically leave
0695  * that data in the streambuf for a subsequent read_until operation to examine.
0696  */
0697 template <typename SyncReadStream, typename Allocator>
0698 std::size_t read_until(SyncReadStream& s,
0699     boost::asio::basic_streambuf<Allocator>& b, char delim,
0700     boost::system::error_code& ec);
0701 
0702 /// Read data into a streambuf until it contains a specified delimiter.
0703 /**
0704  * This function is used to read data into the specified streambuf until the
0705  * streambuf's get area contains the specified delimiter. The call will block
0706  * until one of the following conditions is true:
0707  *
0708  * @li The get area of the streambuf contains the specified delimiter.
0709  *
0710  * @li An error occurred.
0711  *
0712  * This operation is implemented in terms of zero or more calls to the stream's
0713  * read_some function. If the streambuf's get area already contains the
0714  * delimiter, the function returns immediately.
0715  *
0716  * @param s The stream from which the data is to be read. The type must support
0717  * the SyncReadStream concept.
0718  *
0719  * @param b A streambuf object into which the data will be read.
0720  *
0721  * @param delim The delimiter string.
0722  *
0723  * @returns The number of bytes in the streambuf's get area up to and including
0724  * the delimiter.
0725  *
0726  * @throws boost::system::system_error Thrown on failure.
0727  *
0728  * @note After a successful read_until operation, the streambuf may contain
0729  * additional data beyond the delimiter. An application will typically leave
0730  * that data in the streambuf for a subsequent read_until operation to examine.
0731  *
0732  * @par Example
0733  * To read data into a streambuf until a newline is encountered:
0734  * @code boost::asio::streambuf b;
0735  * boost::asio::read_until(s, b, "\r\n");
0736  * std::istream is(&b);
0737  * std::string line;
0738  * std::getline(is, line); @endcode
0739  * After the @c read_until operation completes successfully, the buffer @c b
0740  * contains the delimiter:
0741  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
0742  * The call to @c std::getline then extracts the data up to and including the
0743  * newline (which is discarded), so that the string @c line contains:
0744  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
0745  * The remaining data is left in the buffer @c b as follows:
0746  * @code { 'd', 'e', ... } @endcode
0747  * This data may be the start of a new line, to be extracted by a subsequent
0748  * @c read_until operation.
0749  */
0750 template <typename SyncReadStream, typename Allocator>
0751 std::size_t read_until(SyncReadStream& s,
0752     boost::asio::basic_streambuf<Allocator>& b,
0753     BOOST_ASIO_STRING_VIEW_PARAM delim);
0754 
0755 /// Read data into a streambuf until it contains a specified delimiter.
0756 /**
0757  * This function is used to read data into the specified streambuf until the
0758  * streambuf's get area contains the specified delimiter. The call will block
0759  * until one of the following conditions is true:
0760  *
0761  * @li The get area of the streambuf contains the specified delimiter.
0762  *
0763  * @li An error occurred.
0764  *
0765  * This operation is implemented in terms of zero or more calls to the stream's
0766  * read_some function. If the streambuf's get area already contains the
0767  * delimiter, the function returns immediately.
0768  *
0769  * @param s The stream from which the data is to be read. The type must support
0770  * the SyncReadStream concept.
0771  *
0772  * @param b A streambuf object into which the data will be read.
0773  *
0774  * @param delim The delimiter string.
0775  *
0776  * @param ec Set to indicate what error occurred, if any.
0777  *
0778  * @returns The number of bytes in the streambuf's get area up to and including
0779  * the delimiter. Returns 0 if an error occurred.
0780  *
0781  * @note After a successful read_until operation, the streambuf may contain
0782  * additional data beyond the delimiter. An application will typically leave
0783  * that data in the streambuf for a subsequent read_until operation to examine.
0784  */
0785 template <typename SyncReadStream, typename Allocator>
0786 std::size_t read_until(SyncReadStream& s,
0787     boost::asio::basic_streambuf<Allocator>& b,
0788     BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec);
0789 
0790 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
0791   || defined(GENERATING_DOCUMENTATION)
0792 
0793 /// Read data into a streambuf until some part of the data it contains matches
0794 /// a regular expression.
0795 /**
0796  * This function is used to read data into the specified streambuf until the
0797  * streambuf's get area contains some data that matches a regular expression.
0798  * The call will block until one of the following conditions is true:
0799  *
0800  * @li A substring of the streambuf's get area matches the regular expression.
0801  *
0802  * @li An error occurred.
0803  *
0804  * This operation is implemented in terms of zero or more calls to the stream's
0805  * read_some function. If the streambuf's get area already contains data that
0806  * matches the regular expression, the function returns immediately.
0807  *
0808  * @param s The stream from which the data is to be read. The type must support
0809  * the SyncReadStream concept.
0810  *
0811  * @param b A streambuf object into which the data will be read.
0812  *
0813  * @param expr The regular expression.
0814  *
0815  * @returns The number of bytes in the streambuf's get area up to and including
0816  * the substring that matches the regular expression.
0817  *
0818  * @throws boost::system::system_error Thrown on failure.
0819  *
0820  * @note After a successful read_until operation, the streambuf may contain
0821  * additional data beyond that which matched the regular expression. An
0822  * application will typically leave that data in the streambuf for a subsequent
0823  * read_until operation to examine.
0824  *
0825  * @par Example
0826  * To read data into a streambuf until a CR-LF sequence is encountered:
0827  * @code boost::asio::streambuf b;
0828  * boost::asio::read_until(s, b, boost::regex("\r\n"));
0829  * std::istream is(&b);
0830  * std::string line;
0831  * std::getline(is, line); @endcode
0832  * After the @c read_until operation completes successfully, the buffer @c b
0833  * contains the data which matched the regular expression:
0834  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
0835  * The call to @c std::getline then extracts the data up to and including the
0836  * newline (which is discarded), so that the string @c line contains:
0837  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
0838  * The remaining data is left in the buffer @c b as follows:
0839  * @code { 'd', 'e', ... } @endcode
0840  * This data may be the start of a new line, to be extracted by a subsequent
0841  * @c read_until operation.
0842  */
0843 template <typename SyncReadStream, typename Allocator, typename Traits>
0844 std::size_t read_until(SyncReadStream& s,
0845     boost::asio::basic_streambuf<Allocator>& b,
0846     const boost::basic_regex<char, Traits>& expr);
0847 
0848 /// Read data into a streambuf until some part of the data it contains matches
0849 /// a regular expression.
0850 /**
0851  * This function is used to read data into the specified streambuf until the
0852  * streambuf's get area contains some data that matches a regular expression.
0853  * The call will block until one of the following conditions is true:
0854  *
0855  * @li A substring of the streambuf's get area matches the regular expression.
0856  *
0857  * @li An error occurred.
0858  *
0859  * This operation is implemented in terms of zero or more calls to the stream's
0860  * read_some function. If the streambuf's get area already contains data that
0861  * matches the regular expression, the function returns immediately.
0862  *
0863  * @param s The stream from which the data is to be read. The type must support
0864  * the SyncReadStream concept.
0865  *
0866  * @param b A streambuf object into which the data will be read.
0867  *
0868  * @param expr The regular expression.
0869  *
0870  * @param ec Set to indicate what error occurred, if any.
0871  *
0872  * @returns The number of bytes in the streambuf's get area up to and including
0873  * the substring that matches the regular expression. Returns 0 if an error
0874  * occurred.
0875  *
0876  * @note After a successful read_until operation, the streambuf may contain
0877  * additional data beyond that which matched the regular expression. An
0878  * application will typically leave that data in the streambuf for a subsequent
0879  * read_until operation to examine.
0880  */
0881 template <typename SyncReadStream, typename Allocator, typename Traits>
0882 std::size_t read_until(SyncReadStream& s,
0883     boost::asio::basic_streambuf<Allocator>& b,
0884     const boost::basic_regex<char, Traits>& expr,
0885     boost::system::error_code& ec);
0886 
0887 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
0888        // || defined(GENERATING_DOCUMENTATION)
0889 
0890 /// Read data into a streambuf until a function object indicates a match.
0891 /**
0892  * This function is used to read data into the specified streambuf until a
0893  * user-defined match condition function object, when applied to the data
0894  * contained in the streambuf, indicates a successful match. The call will
0895  * block until one of the following conditions is true:
0896  *
0897  * @li The match condition function object returns a std::pair where the second
0898  * element evaluates to true.
0899  *
0900  * @li An error occurred.
0901  *
0902  * This operation is implemented in terms of zero or more calls to the stream's
0903  * read_some function. If the match condition function object already indicates
0904  * a match, the function returns immediately.
0905  *
0906  * @param s The stream from which the data is to be read. The type must support
0907  * the SyncReadStream concept.
0908  *
0909  * @param b A streambuf object into which the data will be read.
0910  *
0911  * @param match_condition The function object to be called to determine whether
0912  * a match exists. The signature of the function object must be:
0913  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
0914  * @endcode
0915  * where @c iterator represents the type:
0916  * @code buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
0917  * @endcode
0918  * The iterator parameters @c begin and @c end define the range of bytes to be
0919  * scanned to determine whether there is a match. The @c first member of the
0920  * return value is an iterator marking one-past-the-end of the bytes that have
0921  * been consumed by the match function. This iterator is used to calculate the
0922  * @c begin parameter for any subsequent invocation of the match condition. The
0923  * @c second member of the return value is true if a match has been found, false
0924  * otherwise.
0925  *
0926  * @returns The number of bytes in the streambuf's get area that have been fully
0927  * consumed by the match function.
0928  *
0929  * @throws boost::system::system_error Thrown on failure.
0930  *
0931  * @note After a successful read_until operation, the streambuf may contain
0932  * additional data beyond that which matched the function object. An application
0933  * will typically leave that data in the streambuf for a subsequent read_until
0934  * operation to examine.
0935  *
0936  * @note The default implementation of the @c is_match_condition type trait
0937  * evaluates to true for function pointers and function objects with a
0938  * @c result_type typedef. It must be specialised for other user-defined
0939  * function objects.
0940  *
0941  * @par Examples
0942  * To read data into a streambuf until whitespace is encountered:
0943  * @code typedef boost::asio::buffers_iterator<
0944  *     boost::asio::streambuf::const_buffers_type> iterator;
0945  *
0946  * std::pair<iterator, bool>
0947  * match_whitespace(iterator begin, iterator end)
0948  * {
0949  *   iterator i = begin;
0950  *   while (i != end)
0951  *     if (std::isspace(*i++))
0952  *       return std::make_pair(i, true);
0953  *   return std::make_pair(i, false);
0954  * }
0955  * ...
0956  * boost::asio::streambuf b;
0957  * boost::asio::read_until(s, b, match_whitespace);
0958  * @endcode
0959  *
0960  * To read data into a streambuf until a matching character is found:
0961  * @code class match_char
0962  * {
0963  * public:
0964  *   explicit match_char(char c) : c_(c) {}
0965  *
0966  *   template <typename Iterator>
0967  *   std::pair<Iterator, bool> operator()(
0968  *       Iterator begin, Iterator end) const
0969  *   {
0970  *     Iterator i = begin;
0971  *     while (i != end)
0972  *       if (c_ == *i++)
0973  *         return std::make_pair(i, true);
0974  *     return std::make_pair(i, false);
0975  *   }
0976  *
0977  * private:
0978  *   char c_;
0979  * };
0980  *
0981  * namespace asio {
0982  *   template <> struct is_match_condition<match_char>
0983  *     : public boost::true_type {};
0984  * } // namespace asio
0985  * ...
0986  * boost::asio::streambuf b;
0987  * boost::asio::read_until(s, b, match_char('a'));
0988  * @endcode
0989  */
0990 template <typename SyncReadStream, typename Allocator, typename MatchCondition>
0991 std::size_t read_until(SyncReadStream& s,
0992     boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,
0993     constraint_t<is_match_condition<MatchCondition>::value> = 0);
0994 
0995 /// Read data into a streambuf until a function object indicates a match.
0996 /**
0997  * This function is used to read data into the specified streambuf until a
0998  * user-defined match condition function object, when applied to the data
0999  * contained in the streambuf, indicates a successful match. The call will
1000  * block until one of the following conditions is true:
1001  *
1002  * @li The match condition function object returns a std::pair where the second
1003  * element evaluates to true.
1004  *
1005  * @li An error occurred.
1006  *
1007  * This operation is implemented in terms of zero or more calls to the stream's
1008  * read_some function. If the match condition function object already indicates
1009  * a match, the function returns immediately.
1010  *
1011  * @param s The stream from which the data is to be read. The type must support
1012  * the SyncReadStream concept.
1013  *
1014  * @param b A streambuf object into which the data will be read.
1015  *
1016  * @param match_condition The function object to be called to determine whether
1017  * a match exists. The signature of the function object must be:
1018  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
1019  * @endcode
1020  * where @c iterator represents the type:
1021  * @code buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
1022  * @endcode
1023  * The iterator parameters @c begin and @c end define the range of bytes to be
1024  * scanned to determine whether there is a match. The @c first member of the
1025  * return value is an iterator marking one-past-the-end of the bytes that have
1026  * been consumed by the match function. This iterator is used to calculate the
1027  * @c begin parameter for any subsequent invocation of the match condition. The
1028  * @c second member of the return value is true if a match has been found, false
1029  * otherwise.
1030  *
1031  * @param ec Set to indicate what error occurred, if any.
1032  *
1033  * @returns The number of bytes in the streambuf's get area that have been fully
1034  * consumed by the match function. Returns 0 if an error occurred.
1035  *
1036  * @note After a successful read_until operation, the streambuf may contain
1037  * additional data beyond that which matched the function object. An application
1038  * will typically leave that data in the streambuf for a subsequent read_until
1039  * operation to examine.
1040  *
1041  * @note The default implementation of the @c is_match_condition type trait
1042  * evaluates to true for function pointers and function objects with a
1043  * @c result_type typedef. It must be specialised for other user-defined
1044  * function objects.
1045  */
1046 template <typename SyncReadStream, typename Allocator, typename MatchCondition>
1047 std::size_t read_until(SyncReadStream& s,
1048     boost::asio::basic_streambuf<Allocator>& b,
1049     MatchCondition match_condition, boost::system::error_code& ec,
1050     constraint_t<is_match_condition<MatchCondition>::value> = 0);
1051 
1052 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
1053 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
1054 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1055 
1056 /// Read data into a dynamic buffer sequence until it contains a specified
1057 /// delimiter.
1058 /**
1059  * This function is used to read data into the specified dynamic buffer
1060  * sequence until the dynamic buffer sequence's get area contains the specified
1061  * delimiter. The call will block until one of the following conditions is
1062  * true:
1063  *
1064  * @li The get area of the dynamic buffer sequence contains the specified
1065  * delimiter.
1066  *
1067  * @li An error occurred.
1068  *
1069  * This operation is implemented in terms of zero or more calls to the stream's
1070  * read_some function. If the dynamic buffer sequence's get area already
1071  * contains the delimiter, the function returns immediately.
1072  *
1073  * @param s The stream from which the data is to be read. The type must support
1074  * the SyncReadStream concept.
1075  *
1076  * @param buffers The dynamic buffer sequence into which the data will be read.
1077  *
1078  * @param delim The delimiter character.
1079  *
1080  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1081  * and including the delimiter.
1082  *
1083  * @throws boost::system::system_error Thrown on failure.
1084  *
1085  * @note After a successful read_until operation, the dynamic buffer sequence
1086  * may contain additional data beyond the delimiter. An application will
1087  * typically leave that data in the dynamic buffer sequence for a subsequent
1088  * read_until operation to examine.
1089  *
1090  * @par Example
1091  * To read data into a @c std::string until a newline is encountered:
1092  * @code std::string data;
1093  * std::size_t n = boost::asio::read_until(s,
1094  *     boost::asio::dynamic_buffer(data), '\n');
1095  * std::string line = data.substr(0, n);
1096  * data.erase(0, n); @endcode
1097  * After the @c read_until operation completes successfully, the string @c data
1098  * contains the delimiter:
1099  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
1100  * The call to @c substr then extracts the data up to and including the
1101  * delimiter, so that the string @c line contains:
1102  * @code { 'a', 'b', ..., 'c', '\n' } @endcode
1103  * After the call to @c erase, the remaining data is left in the buffer @c b as
1104  * follows:
1105  * @code { 'd', 'e', ... } @endcode
1106  * This data may be the start of a new line, to be extracted by a subsequent
1107  * @c read_until operation.
1108  */
1109 template <typename SyncReadStream, typename DynamicBuffer_v2>
1110 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim,
1111     constraint_t<
1112       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1113     > = 0);
1114 
1115 /// Read data into a dynamic buffer sequence until it contains a specified
1116 /// delimiter.
1117 /**
1118  * This function is used to read data into the specified dynamic buffer
1119  * sequence until the dynamic buffer sequence's get area contains the specified
1120  * delimiter. The call will block until one of the following conditions is
1121  * true:
1122  *
1123  * @li The get area of the dynamic buffer sequence contains the specified
1124  * delimiter.
1125  *
1126  * @li An error occurred.
1127  *
1128  * This operation is implemented in terms of zero or more calls to the stream's
1129  * read_some function. If the dynamic buffer sequence's get area already
1130  * contains the delimiter, the function returns immediately.
1131  *
1132  * @param s The stream from which the data is to be read. The type must support
1133  * the SyncReadStream concept.
1134  *
1135  * @param buffers The dynamic buffer sequence into which the data will be read.
1136  *
1137  * @param delim The delimiter character.
1138  *
1139  * @param ec Set to indicate what error occurred, if any.
1140  *
1141  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1142  * and including the delimiter. Returns 0 if an error occurred.
1143  *
1144  * @note After a successful read_until operation, the dynamic buffer sequence
1145  * may contain additional data beyond the delimiter. An application will
1146  * typically leave that data in the dynamic buffer sequence for a subsequent
1147  * read_until operation to examine.
1148  */
1149 template <typename SyncReadStream, typename DynamicBuffer_v2>
1150 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1151     char delim, boost::system::error_code& ec,
1152     constraint_t<
1153       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1154     > = 0);
1155 
1156 /// Read data into a dynamic buffer sequence until it contains a specified
1157 /// delimiter.
1158 /**
1159  * This function is used to read data into the specified dynamic buffer
1160  * sequence until the dynamic buffer sequence's get area contains the specified
1161  * delimiter. The call will block until one of the following conditions is
1162  * true:
1163  *
1164  * @li The get area of the dynamic buffer sequence contains the specified
1165  * delimiter.
1166  *
1167  * @li An error occurred.
1168  *
1169  * This operation is implemented in terms of zero or more calls to the stream's
1170  * read_some function. If the dynamic buffer sequence's get area already
1171  * contains the delimiter, the function returns immediately.
1172  *
1173  * @param s The stream from which the data is to be read. The type must support
1174  * the SyncReadStream concept.
1175  *
1176  * @param buffers The dynamic buffer sequence into which the data will be read.
1177  *
1178  * @param delim The delimiter string.
1179  *
1180  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1181  * and including the delimiter.
1182  *
1183  * @note After a successful read_until operation, the dynamic buffer sequence
1184  * may contain additional data beyond the delimiter. An application will
1185  * typically leave that data in the dynamic buffer sequence for a subsequent
1186  * read_until operation to examine.
1187  *
1188  * @par Example
1189  * To read data into a @c std::string until a CR-LF sequence is encountered:
1190  * @code std::string data;
1191  * std::size_t n = boost::asio::read_until(s,
1192  *     boost::asio::dynamic_buffer(data), "\r\n");
1193  * std::string line = data.substr(0, n);
1194  * data.erase(0, n); @endcode
1195  * After the @c read_until operation completes successfully, the string @c data
1196  * contains the delimiter:
1197  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1198  * The call to @c substr then extracts the data up to and including the
1199  * delimiter, so that the string @c line contains:
1200  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1201  * After the call to @c erase, the remaining data is left in the buffer @c b as
1202  * follows:
1203  * @code { 'd', 'e', ... } @endcode
1204  * This data may be the start of a new line, to be extracted by a subsequent
1205  * @c read_until operation.
1206  */
1207 template <typename SyncReadStream, typename DynamicBuffer_v2>
1208 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1209     BOOST_ASIO_STRING_VIEW_PARAM delim,
1210     constraint_t<
1211       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1212     > = 0);
1213 
1214 /// Read data into a dynamic buffer sequence until it contains a specified
1215 /// delimiter.
1216 /**
1217  * This function is used to read data into the specified dynamic buffer
1218  * sequence until the dynamic buffer sequence's get area contains the specified
1219  * delimiter. The call will block until one of the following conditions is
1220  * true:
1221  *
1222  * @li The get area of the dynamic buffer sequence contains the specified
1223  * delimiter.
1224  *
1225  * @li An error occurred.
1226  *
1227  * This operation is implemented in terms of zero or more calls to the stream's
1228  * read_some function. If the dynamic buffer sequence's get area already
1229  * contains the delimiter, the function returns immediately.
1230  *
1231  * @param s The stream from which the data is to be read. The type must support
1232  * the SyncReadStream concept.
1233  *
1234  * @param buffers The dynamic buffer sequence into which the data will be read.
1235  *
1236  * @param delim The delimiter string.
1237  *
1238  * @param ec Set to indicate what error occurred, if any.
1239  *
1240  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1241  * and including the delimiter. Returns 0 if an error occurred.
1242  *
1243  * @note After a successful read_until operation, the dynamic buffer sequence
1244  * may contain additional data beyond the delimiter. An application will
1245  * typically leave that data in the dynamic buffer sequence for a subsequent
1246  * read_until operation to examine.
1247  */
1248 template <typename SyncReadStream, typename DynamicBuffer_v2>
1249 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1250     BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec,
1251     constraint_t<
1252       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1253     > = 0);
1254 
1255 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
1256 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
1257   || defined(GENERATING_DOCUMENTATION)
1258 
1259 /// Read data into a dynamic buffer sequence until some part of the data it
1260 /// contains matches a regular expression.
1261 /**
1262  * This function is used to read data into the specified dynamic buffer
1263  * sequence until the dynamic buffer sequence's get area contains some data
1264  * that matches a regular expression. The call will block until one of the
1265  * following conditions is true:
1266  *
1267  * @li A substring of the dynamic buffer sequence's get area matches the
1268  * regular expression.
1269  *
1270  * @li An error occurred.
1271  *
1272  * This operation is implemented in terms of zero or more calls to the stream's
1273  * read_some function. If the dynamic buffer sequence's get area already
1274  * contains data that matches the regular expression, the function returns
1275  * immediately.
1276  *
1277  * @param s The stream from which the data is to be read. The type must support
1278  * the SyncReadStream concept.
1279  *
1280  * @param buffers A dynamic buffer sequence into which the data will be read.
1281  *
1282  * @param expr The regular expression.
1283  *
1284  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1285  * and including the substring that matches the regular expression.
1286  *
1287  * @throws boost::system::system_error Thrown on failure.
1288  *
1289  * @note After a successful read_until operation, the dynamic buffer sequence
1290  * may contain additional data beyond that which matched the regular
1291  * expression. An application will typically leave that data in the dynamic
1292  * buffer sequence for a subsequent read_until operation to examine.
1293  *
1294  * @par Example
1295  * To read data into a @c std::string until a CR-LF sequence is encountered:
1296  * @code std::string data;
1297  * std::size_t n = boost::asio::read_until(s,
1298  *     boost::asio::dynamic_buffer(data), boost::regex("\r\n"));
1299  * std::string line = data.substr(0, n);
1300  * data.erase(0, n); @endcode
1301  * After the @c read_until operation completes successfully, the string @c data
1302  * contains the delimiter:
1303  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1304  * The call to @c substr then extracts the data up to and including the
1305  * delimiter, so that the string @c line contains:
1306  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1307  * After the call to @c erase, the remaining data is left in the buffer @c b as
1308  * follows:
1309  * @code { 'd', 'e', ... } @endcode
1310  * This data may be the start of a new line, to be extracted by a subsequent
1311  * @c read_until operation.
1312  */
1313 template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>
1314 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1315     const boost::basic_regex<char, Traits>& expr,
1316     constraint_t<
1317       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1318     > = 0);
1319 
1320 /// Read data into a dynamic buffer sequence until some part of the data it
1321 /// contains matches a regular expression.
1322 /**
1323  * This function is used to read data into the specified dynamic buffer
1324  * sequence until the dynamic buffer sequence's get area contains some data
1325  * that matches a regular expression. The call will block until one of the
1326  * following conditions is true:
1327  *
1328  * @li A substring of the dynamic buffer sequence's get area matches the
1329  * regular expression.
1330  *
1331  * @li An error occurred.
1332  *
1333  * This operation is implemented in terms of zero or more calls to the stream's
1334  * read_some function. If the dynamic buffer sequence's get area already
1335  * contains data that matches the regular expression, the function returns
1336  * immediately.
1337  *
1338  * @param s The stream from which the data is to be read. The type must support
1339  * the SyncReadStream concept.
1340  *
1341  * @param buffers A dynamic buffer sequence into which the data will be read.
1342  *
1343  * @param expr The regular expression.
1344  *
1345  * @param ec Set to indicate what error occurred, if any.
1346  *
1347  * @returns The number of bytes in the dynamic buffer sequence's get area up to
1348  * and including the substring that matches the regular expression. Returns 0
1349  * if an error occurred.
1350  *
1351  * @note After a successful read_until operation, the dynamic buffer sequence
1352  * may contain additional data beyond that which matched the regular
1353  * expression. An application will typically leave that data in the dynamic
1354  * buffer sequence for a subsequent read_until operation to examine.
1355  */
1356 template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>
1357 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1358     const boost::basic_regex<char, Traits>& expr, boost::system::error_code& ec,
1359     constraint_t<
1360         is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1361     > = 0);
1362 
1363 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
1364        // || defined(GENERATING_DOCUMENTATION)
1365 
1366 /// Read data into a dynamic buffer sequence until a function object indicates a
1367 /// match.
1368 
1369 /**
1370  * This function is used to read data into the specified dynamic buffer
1371  * sequence until a user-defined match condition function object, when applied
1372  * to the data contained in the dynamic buffer sequence, indicates a successful
1373  * match. The call will block until one of the following conditions is true:
1374  *
1375  * @li The match condition function object returns a std::pair where the second
1376  * element evaluates to true.
1377  *
1378  * @li An error occurred.
1379  *
1380  * This operation is implemented in terms of zero or more calls to the stream's
1381  * read_some function. If the match condition function object already indicates
1382  * a match, the function returns immediately.
1383  *
1384  * @param s The stream from which the data is to be read. The type must support
1385  * the SyncReadStream concept.
1386  *
1387  * @param buffers A dynamic buffer sequence into which the data will be read.
1388  *
1389  * @param match_condition The function object to be called to determine whether
1390  * a match exists. The signature of the function object must be:
1391  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
1392  * @endcode
1393  * where @c iterator represents the type:
1394  * @code buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>
1395  * @endcode
1396  * The iterator parameters @c begin and @c end define the range of bytes to be
1397  * scanned to determine whether there is a match. The @c first member of the
1398  * return value is an iterator marking one-past-the-end of the bytes that have
1399  * been consumed by the match function. This iterator is used to calculate the
1400  * @c begin parameter for any subsequent invocation of the match condition. The
1401  * @c second member of the return value is true if a match has been found, false
1402  * otherwise.
1403  *
1404  * @returns The number of bytes in the dynamic_buffer's get area that
1405  * have been fully consumed by the match function.
1406  *
1407  * @throws boost::system::system_error Thrown on failure.
1408  *
1409  * @note After a successful read_until operation, the dynamic buffer sequence
1410  * may contain additional data beyond that which matched the function object.
1411  * An application will typically leave that data in the dynamic buffer sequence
1412  * for a subsequent read_until operation to examine.
1413 
1414  * @note The default implementation of the @c is_match_condition type trait
1415  * evaluates to true for function pointers and function objects with a
1416  * @c result_type typedef. It must be specialised for other user-defined
1417  * function objects.
1418  *
1419  * @par Examples
1420  * To read data into a dynamic buffer sequence until whitespace is encountered:
1421  * @code typedef boost::asio::buffers_iterator<
1422  *     boost::asio::const_buffers_1> iterator;
1423  *
1424  * std::pair<iterator, bool>
1425  * match_whitespace(iterator begin, iterator end)
1426  * {
1427  *   iterator i = begin;
1428  *   while (i != end)
1429  *     if (std::isspace(*i++))
1430  *       return std::make_pair(i, true);
1431  *   return std::make_pair(i, false);
1432  * }
1433  * ...
1434  * std::string data;
1435  * boost::asio::read_until(s, data, match_whitespace);
1436  * @endcode
1437  *
1438  * To read data into a @c std::string until a matching character is found:
1439  * @code class match_char
1440  * {
1441  * public:
1442  *   explicit match_char(char c) : c_(c) {}
1443  *
1444  *   template <typename Iterator>
1445  *   std::pair<Iterator, bool> operator()(
1446  *       Iterator begin, Iterator end) const
1447  *   {
1448  *     Iterator i = begin;
1449  *     while (i != end)
1450  *       if (c_ == *i++)
1451  *         return std::make_pair(i, true);
1452  *     return std::make_pair(i, false);
1453  *   }
1454  *
1455  * private:
1456  *   char c_;
1457  * };
1458  *
1459  * namespace asio {
1460  *   template <> struct is_match_condition<match_char>
1461  *     : public boost::true_type {};
1462  * } // namespace asio
1463  * ...
1464  * std::string data;
1465  * boost::asio::read_until(s, data, match_char('a'));
1466  * @endcode
1467  */
1468 template <typename SyncReadStream,
1469     typename DynamicBuffer_v2, typename MatchCondition>
1470 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1471     MatchCondition match_condition,
1472     constraint_t<
1473       is_match_condition<MatchCondition>::value
1474     > = 0,
1475     constraint_t<
1476       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1477     > = 0);
1478 
1479 /// Read data into a dynamic buffer sequence until a function object indicates a
1480 /// match.
1481 /**
1482  * This function is used to read data into the specified dynamic buffer
1483  * sequence until a user-defined match condition function object, when applied
1484  * to the data contained in the dynamic buffer sequence, indicates a successful
1485  * match. The call will block until one of the following conditions is true:
1486  *
1487  * @li The match condition function object returns a std::pair where the second
1488  * element evaluates to true.
1489  *
1490  * @li An error occurred.
1491  *
1492  * This operation is implemented in terms of zero or more calls to the stream's
1493  * read_some function. If the match condition function object already indicates
1494  * a match, the function returns immediately.
1495  *
1496  * @param s The stream from which the data is to be read. The type must support
1497  * the SyncReadStream concept.
1498  *
1499  * @param buffers A dynamic buffer sequence into which the data will be read.
1500  *
1501  * @param match_condition The function object to be called to determine whether
1502  * a match exists. The signature of the function object must be:
1503  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
1504  * @endcode
1505  * where @c iterator represents the type:
1506  * @code buffers_iterator<DynamicBuffer_v2::const_buffers_type>
1507  * @endcode
1508  * The iterator parameters @c begin and @c end define the range of bytes to be
1509  * scanned to determine whether there is a match. The @c first member of the
1510  * return value is an iterator marking one-past-the-end of the bytes that have
1511  * been consumed by the match function. This iterator is used to calculate the
1512  * @c begin parameter for any subsequent invocation of the match condition. The
1513  * @c second member of the return value is true if a match has been found, false
1514  * otherwise.
1515  *
1516  * @param ec Set to indicate what error occurred, if any.
1517  *
1518  * @returns The number of bytes in the dynamic buffer sequence's get area that
1519  * have been fully consumed by the match function. Returns 0 if an error
1520  * occurred.
1521  *
1522  * @note After a successful read_until operation, the dynamic buffer sequence
1523  * may contain additional data beyond that which matched the function object.
1524  * An application will typically leave that data in the dynamic buffer sequence
1525  * for a subsequent read_until operation to examine.
1526  *
1527  * @note The default implementation of the @c is_match_condition type trait
1528  * evaluates to true for function pointers and function objects with a
1529  * @c result_type typedef. It must be specialised for other user-defined
1530  * function objects.
1531  */
1532 template <typename SyncReadStream,
1533     typename DynamicBuffer_v2, typename MatchCondition>
1534 std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
1535     MatchCondition match_condition, boost::system::error_code& ec,
1536     constraint_t<
1537       is_match_condition<MatchCondition>::value
1538     > = 0,
1539     constraint_t<
1540       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1541     > = 0);
1542 
1543 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
1544 
1545 /*@}*/
1546 /**
1547  * @defgroup async_read_until boost::asio::async_read_until
1548  *
1549  * @brief The @c async_read_until function is a composed asynchronous operation
1550  * that reads data into a dynamic buffer sequence, or into a streambuf, until
1551  * it contains a delimiter, matches a regular expression, or a function object
1552  * indicates a match.
1553  */
1554 /*@{*/
1555 
1556 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1557 
1558 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1559 /// until it contains a specified delimiter.
1560 /**
1561  * This function is used to asynchronously read data into the specified dynamic
1562  * buffer sequence until the dynamic buffer sequence's get area contains the
1563  * specified delimiter. It is an initiating function for an @ref
1564  * asynchronous_operation, and always returns immediately. The asynchronous
1565  * operation will continue until one of the following conditions is true:
1566  *
1567  * @li The get area of the dynamic buffer sequence contains the specified
1568  * delimiter.
1569  *
1570  * @li An error occurred.
1571  *
1572  * This operation is implemented in terms of zero or more calls to the stream's
1573  * async_read_some function, and is known as a <em>composed operation</em>. If
1574  * the dynamic buffer sequence's get area already contains the delimiter, this
1575  * asynchronous operation completes immediately. The program must ensure that
1576  * the stream performs no other read operations (such as async_read,
1577  * async_read_until, the stream's async_read_some function, or any other
1578  * composed operations that perform reads) until this operation completes.
1579  *
1580  * @param s The stream from which the data is to be read. The type must support
1581  * the AsyncReadStream concept.
1582  *
1583  * @param buffers The dynamic buffer sequence into which the data will be read.
1584  * Although the buffers object may be copied as necessary, ownership of the
1585  * underlying memory blocks is retained by the caller, which must guarantee
1586  * that they remain valid until the completion handler is called.
1587  *
1588  * @param delim The delimiter character.
1589  *
1590  * @param token The @ref completion_token that will be used to produce a
1591  * completion handler, which will be called when the read completes.
1592  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1593  * @ref yield_context, or a function object with the correct completion
1594  * signature. The function signature of the completion handler must be:
1595  * @code void handler(
1596  *   // Result of operation.
1597  *   const boost::system::error_code& error,
1598  *
1599  *   // The number of bytes in the dynamic buffer sequence's
1600  *   // get area up to and including the delimiter.
1601  *   std::size_t bytes_transferred
1602  * ); @endcode
1603  * Regardless of whether the asynchronous operation completes immediately or
1604  * not, the completion handler will not be invoked from within this function.
1605  * On immediate completion, invocation of the handler will be performed in a
1606  * manner equivalent to using boost::asio::async_immediate().
1607  *
1608  * @par Completion Signature
1609  * @code void(boost::system::error_code, std::size_t) @endcode
1610  *
1611  * @note After a successful async_read_until operation, the dynamic buffer
1612  * sequence may contain additional data beyond the delimiter. An application
1613  * will typically leave that data in the dynamic buffer sequence for a
1614  * subsequent async_read_until operation to examine.
1615  *
1616  * @par Example
1617  * To asynchronously read data into a @c std::string until a newline is
1618  * encountered:
1619  * @code std::string data;
1620  * ...
1621  * void handler(const boost::system::error_code& e, std::size_t size)
1622  * {
1623  *   if (!e)
1624  *   {
1625  *     std::string line = data.substr(0, n);
1626  *     data.erase(0, n);
1627  *     ...
1628  *   }
1629  * }
1630  * ...
1631  * boost::asio::async_read_until(s, data, '\n', handler); @endcode
1632  * After the @c async_read_until operation completes successfully, the buffer
1633  * @c data contains the delimiter:
1634  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
1635  * The call to @c substr then extracts the data up to and including the
1636  * delimiter, so that the string @c line contains:
1637  * @code { 'a', 'b', ..., 'c', '\n' } @endcode
1638  * After the call to @c erase, the remaining data is left in the buffer @c data
1639  * as follows:
1640  * @code { 'd', 'e', ... } @endcode
1641  * This data may be the start of a new line, to be extracted by a subsequent
1642  * @c async_read_until operation.
1643  *
1644  * @par Per-Operation Cancellation
1645  * This asynchronous operation supports cancellation for the following
1646  * boost::asio::cancellation_type values:
1647  *
1648  * @li @c cancellation_type::terminal
1649  *
1650  * @li @c cancellation_type::partial
1651  *
1652  * if they are also supported by the @c AsyncReadStream type's
1653  * @c async_read_some operation.
1654  */
1655 template <typename AsyncReadStream, typename DynamicBuffer_v1,
1656     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1657       std::size_t)) ReadToken = default_completion_token_t<
1658         typename AsyncReadStream::executor_type>>
1659 inline auto async_read_until(AsyncReadStream& s,
1660     DynamicBuffer_v1&& buffers, char delim,
1661     ReadToken&& token = default_completion_token_t<
1662       typename AsyncReadStream::executor_type>(),
1663     constraint_t<
1664       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
1665     > = 0,
1666     constraint_t<
1667       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
1668     > = 0)
1669   -> decltype(
1670     async_initiate<ReadToken,
1671       void (boost::system::error_code, std::size_t)>(
1672         declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),
1673         token, static_cast<DynamicBuffer_v1&&>(buffers), delim))
1674 {
1675   return async_initiate<ReadToken,
1676     void (boost::system::error_code, std::size_t)>(
1677       detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),
1678       token, static_cast<DynamicBuffer_v1&&>(buffers), delim);
1679 }
1680 
1681 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1682 /// until it contains a specified delimiter.
1683 /**
1684  * This function is used to asynchronously read data into the specified dynamic
1685  * buffer sequence until the dynamic buffer sequence's get area contains the
1686  * specified delimiter. It is an initiating function for an @ref
1687  * asynchronous_operation, and always returns immediately. The asynchronous
1688  * operation will continue until one of the following conditions is true:
1689  *
1690  * @li The get area of the dynamic buffer sequence contains the specified
1691  * delimiter.
1692  *
1693  * @li An error occurred.
1694  *
1695  * This operation is implemented in terms of zero or more calls to the stream's
1696  * async_read_some function, and is known as a <em>composed operation</em>. If
1697  * the dynamic buffer sequence's get area already contains the delimiter, this
1698  * asynchronous operation completes immediately. The program must ensure that
1699  * the stream performs no other read operations (such as async_read,
1700  * async_read_until, the stream's async_read_some function, or any other
1701  * composed operations that perform reads) until this operation completes.
1702  *
1703  * @param s The stream from which the data is to be read. The type must support
1704  * the AsyncReadStream concept.
1705  *
1706  * @param buffers The dynamic buffer sequence into which the data will be read.
1707  * Although the buffers object may be copied as necessary, ownership of the
1708  * underlying memory blocks is retained by the caller, which must guarantee
1709  * that they remain valid until the completion handler is called.
1710  *
1711  * @param delim The delimiter string.
1712  *
1713  * @param token The @ref completion_token that will be used to produce a
1714  * completion handler, which will be called when the read completes.
1715  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1716  * @ref yield_context, or a function object with the correct completion
1717  * signature. The function signature of the completion handler must be:
1718  * @code void handler(
1719  *   // Result of operation.
1720  *   const boost::system::error_code& error,
1721  *
1722  *   // The number of bytes in the dynamic buffer sequence's
1723  *   // get area up to and including the delimiter.
1724  *   std::size_t bytes_transferred
1725  * ); @endcode
1726  * Regardless of whether the asynchronous operation completes immediately or
1727  * not, the completion handler will not be invoked from within this function.
1728  * On immediate completion, invocation of the handler will be performed in a
1729  * manner equivalent to using boost::asio::async_immediate().
1730  *
1731  * @par Completion Signature
1732  * @code void(boost::system::error_code, std::size_t) @endcode
1733  *
1734  * @note After a successful async_read_until operation, the dynamic buffer
1735  * sequence may contain additional data beyond the delimiter. An application
1736  * will typically leave that data in the dynamic buffer sequence for a
1737  * subsequent async_read_until operation to examine.
1738  *
1739  * @par Example
1740  * To asynchronously read data into a @c std::string until a CR-LF sequence is
1741  * encountered:
1742  * @code std::string data;
1743  * ...
1744  * void handler(const boost::system::error_code& e, std::size_t size)
1745  * {
1746  *   if (!e)
1747  *   {
1748  *     std::string line = data.substr(0, n);
1749  *     data.erase(0, n);
1750  *     ...
1751  *   }
1752  * }
1753  * ...
1754  * boost::asio::async_read_until(s, data, "\r\n", handler); @endcode
1755  * After the @c async_read_until operation completes successfully, the string
1756  * @c data contains the delimiter:
1757  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1758  * The call to @c substr then extracts the data up to and including the
1759  * delimiter, so that the string @c line contains:
1760  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1761  * After the call to @c erase, the remaining data is left in the string @c data
1762  * as follows:
1763  * @code { 'd', 'e', ... } @endcode
1764  * This data may be the start of a new line, to be extracted by a subsequent
1765  * @c async_read_until operation.
1766  *
1767  * @par Per-Operation Cancellation
1768  * This asynchronous operation supports cancellation for the following
1769  * boost::asio::cancellation_type values:
1770  *
1771  * @li @c cancellation_type::terminal
1772  *
1773  * @li @c cancellation_type::partial
1774  *
1775  * if they are also supported by the @c AsyncReadStream type's
1776  * @c async_read_some operation.
1777  */
1778 template <typename AsyncReadStream, typename DynamicBuffer_v1,
1779     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1780       std::size_t)) ReadToken = default_completion_token_t<
1781         typename AsyncReadStream::executor_type>>
1782 inline auto async_read_until(AsyncReadStream& s,
1783     DynamicBuffer_v1&& buffers,
1784     BOOST_ASIO_STRING_VIEW_PARAM delim,
1785     ReadToken&& token = default_completion_token_t<
1786       typename AsyncReadStream::executor_type>(),
1787     constraint_t<
1788       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
1789     > = 0,
1790     constraint_t<
1791       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
1792     > = 0)
1793   -> decltype(
1794     async_initiate<ReadToken,
1795       void (boost::system::error_code, std::size_t)>(
1796         declval<detail::initiate_async_read_until_delim_string_v1<
1797           AsyncReadStream>>(),
1798         token, static_cast<DynamicBuffer_v1&&>(buffers),
1799         static_cast<std::string>(delim)))
1800 {
1801   return async_initiate<ReadToken,
1802     void (boost::system::error_code, std::size_t)>(
1803       detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),
1804       token, static_cast<DynamicBuffer_v1&&>(buffers),
1805       static_cast<std::string>(delim));
1806 }
1807 
1808 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
1809 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
1810   || defined(GENERATING_DOCUMENTATION)
1811 
1812 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1813 /// until some part of its data matches a regular expression.
1814 /**
1815  * This function is used to asynchronously read data into the specified dynamic
1816  * buffer sequence until the dynamic buffer sequence's get area contains some
1817  * data that matches a regular expression. It is an initiating function for an
1818  * @ref asynchronous_operation, and always returns immediately. The
1819  * asynchronous operation will continue until one of the following conditions
1820  * is true:
1821  *
1822  * @li A substring of the dynamic buffer sequence's get area matches the regular
1823  * expression.
1824  *
1825  * @li An error occurred.
1826  *
1827  * This operation is implemented in terms of zero or more calls to the stream's
1828  * async_read_some function, and is known as a <em>composed operation</em>. If
1829  * the dynamic buffer sequence's get area already contains data that matches
1830  * the regular expression, this asynchronous operation completes immediately.
1831  * The program must ensure that the stream performs no other read operations
1832  * (such as async_read, async_read_until, the stream's async_read_some
1833  * function, or any other composed operations that perform reads) until this
1834  * operation completes.
1835  *
1836  * @param s The stream from which the data is to be read. The type must support
1837  * the AsyncReadStream concept.
1838  *
1839  * @param buffers The dynamic buffer sequence into which the data will be read.
1840  * Although the buffers object may be copied as necessary, ownership of the
1841  * underlying memory blocks is retained by the caller, which must guarantee
1842  * that they remain valid until the completion handler is called.
1843  *
1844  * @param expr The regular expression.
1845  *
1846  * @param token The @ref completion_token that will be used to produce a
1847  * completion handler, which will be called when the read completes.
1848  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1849  * @ref yield_context, or a function object with the correct completion
1850  * signature. The function signature of the completion handler must be:
1851  * @code void handler(
1852  *   // Result of operation.
1853  *   const boost::system::error_code& error,
1854  *
1855  *   // The number of bytes in the dynamic buffer
1856  *   // sequence's get area up to and including the
1857  *   // substring that matches the regular expression.
1858  *   // 0 if an error occurred.
1859  *   std::size_t bytes_transferred
1860  * ); @endcode
1861  * Regardless of whether the asynchronous operation completes immediately or
1862  * not, the completion handler will not be invoked from within this function.
1863  * On immediate completion, invocation of the handler will be performed in a
1864  * manner equivalent to using boost::asio::async_immediate().
1865  *
1866  * @par Completion Signature
1867  * @code void(boost::system::error_code, std::size_t) @endcode
1868  *
1869  * @note After a successful async_read_until operation, the dynamic buffer
1870  * sequence may contain additional data beyond that which matched the regular
1871  * expression. An application will typically leave that data in the dynamic
1872  * buffer sequence for a subsequent async_read_until operation to examine.
1873  *
1874  * @par Example
1875  * To asynchronously read data into a @c std::string until a CR-LF sequence is
1876  * encountered:
1877  * @code std::string data;
1878  * ...
1879  * void handler(const boost::system::error_code& e, std::size_t size)
1880  * {
1881  *   if (!e)
1882  *   {
1883  *     std::string line = data.substr(0, n);
1884  *     data.erase(0, n);
1885  *     ...
1886  *   }
1887  * }
1888  * ...
1889  * boost::asio::async_read_until(s, data,
1890  *     boost::regex("\r\n"), handler); @endcode
1891  * After the @c async_read_until operation completes successfully, the string
1892  * @c data contains the data which matched the regular expression:
1893  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1894  * The call to @c substr then extracts the data up to and including the match,
1895  * so that the string @c line contains:
1896  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1897  * After the call to @c erase, the remaining data is left in the string @c data
1898  * as follows:
1899  * @code { 'd', 'e', ... } @endcode
1900  * This data may be the start of a new line, to be extracted by a subsequent
1901  * @c async_read_until operation.
1902  *
1903  * @par Per-Operation Cancellation
1904  * This asynchronous operation supports cancellation for the following
1905  * boost::asio::cancellation_type values:
1906  *
1907  * @li @c cancellation_type::terminal
1908  *
1909  * @li @c cancellation_type::partial
1910  *
1911  * if they are also supported by the @c AsyncReadStream type's
1912  * @c async_read_some operation.
1913  */
1914 template <typename AsyncReadStream, typename DynamicBuffer_v1, typename Traits,
1915     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1916       std::size_t)) ReadToken = default_completion_token_t<
1917         typename AsyncReadStream::executor_type>>
1918 inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v1&& buffers,
1919     const boost::basic_regex<char, Traits>& expr,
1920     ReadToken&& token = default_completion_token_t<
1921       typename AsyncReadStream::executor_type>(),
1922     constraint_t<
1923       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
1924     > = 0,
1925     constraint_t<
1926       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
1927     > = 0)
1928   -> decltype(
1929     async_initiate<ReadToken,
1930       void (boost::system::error_code, std::size_t)>(
1931         declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),
1932         token, static_cast<DynamicBuffer_v1&&>(buffers), expr))
1933 {
1934   return async_initiate<ReadToken,
1935     void (boost::system::error_code, std::size_t)>(
1936       detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),
1937       token, static_cast<DynamicBuffer_v1&&>(buffers), expr);
1938 }
1939 
1940 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
1941        // || defined(GENERATING_DOCUMENTATION)
1942 
1943 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1944 /// until a function object indicates a match.
1945 /**
1946  * This function is used to asynchronously read data into the specified dynamic
1947  * buffer sequence until a user-defined match condition function object, when
1948  * applied to the data contained in the dynamic buffer sequence, indicates a
1949  * successful match. It is an initiating function for an @ref
1950  * asynchronous_operation, and always returns immediately. The asynchronous
1951  * operation will continue until one of the following conditions is true:
1952  *
1953  * @li The match condition function object returns a std::pair where the second
1954  * element evaluates to true.
1955  *
1956  * @li An error occurred.
1957  *
1958  * This operation is implemented in terms of zero or more calls to the stream's
1959  * async_read_some function, and is known as a <em>composed operation</em>. If
1960  * the match condition function object already indicates a match, this
1961  * asynchronous operation completes immediately. The program must ensure that
1962  * the stream performs no other read operations (such as async_read,
1963  * async_read_until, the stream's async_read_some function, or any other
1964  * composed operations that perform reads) until this operation completes.
1965  *
1966  * @param s The stream from which the data is to be read. The type must support
1967  * the AsyncReadStream concept.
1968  *
1969  * @param buffers The dynamic buffer sequence into which the data will be read.
1970  * Although the buffers object may be copied as necessary, ownership of the
1971  * underlying memory blocks is retained by the caller, which must guarantee
1972  * that they remain valid until the completion handler is called.
1973  *
1974  * @param match_condition The function object to be called to determine whether
1975  * a match exists. The signature of the function object must be:
1976  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
1977  * @endcode
1978  * where @c iterator represents the type:
1979  * @code buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
1980  * @endcode
1981  * The iterator parameters @c begin and @c end define the range of bytes to be
1982  * scanned to determine whether there is a match. The @c first member of the
1983  * return value is an iterator marking one-past-the-end of the bytes that have
1984  * been consumed by the match function. This iterator is used to calculate the
1985  * @c begin parameter for any subsequent invocation of the match condition. The
1986  * @c second member of the return value is true if a match has been found, false
1987  * otherwise.
1988  *
1989  * @param token The @ref completion_token that will be used to produce a
1990  * completion handler, which will be called when the read completes.
1991  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1992  * @ref yield_context, or a function object with the correct completion
1993  * signature. The function signature of the completion handler must be:
1994  * @code void handler(
1995  *   // Result of operation.
1996  *   const boost::system::error_code& error,
1997  *
1998  *   // The number of bytes in the dynamic buffer sequence's
1999  *   // get area that have been fully consumed by the match
2000  *   // function. O if an error occurred.
2001  *   std::size_t bytes_transferred
2002  * ); @endcode
2003  * Regardless of whether the asynchronous operation completes immediately or
2004  * not, the completion handler will not be invoked from within this function.
2005  * On immediate completion, invocation of the handler will be performed in a
2006  * manner equivalent to using boost::asio::async_immediate().
2007  *
2008  * @note After a successful async_read_until operation, the dynamic buffer
2009  * sequence may contain additional data beyond that which matched the function
2010  * object. An application will typically leave that data in the dynamic buffer
2011  * sequence for a subsequent async_read_until operation to examine.
2012  *
2013  * @par Completion Signature
2014  * @code void(boost::system::error_code, std::size_t) @endcode
2015  *
2016  * @note The default implementation of the @c is_match_condition type trait
2017  * evaluates to true for function pointers and function objects with a
2018  * @c result_type typedef. It must be specialised for other user-defined
2019  * function objects.
2020  *
2021  * @par Examples
2022  * To asynchronously read data into a @c std::string until whitespace is
2023  * encountered:
2024  * @code typedef boost::asio::buffers_iterator<
2025  *     boost::asio::const_buffers_1> iterator;
2026  *
2027  * std::pair<iterator, bool>
2028  * match_whitespace(iterator begin, iterator end)
2029  * {
2030  *   iterator i = begin;
2031  *   while (i != end)
2032  *     if (std::isspace(*i++))
2033  *       return std::make_pair(i, true);
2034  *   return std::make_pair(i, false);
2035  * }
2036  * ...
2037  * void handler(const boost::system::error_code& e, std::size_t size);
2038  * ...
2039  * std::string data;
2040  * boost::asio::async_read_until(s, data, match_whitespace, handler);
2041  * @endcode
2042  *
2043  * To asynchronously read data into a @c std::string until a matching character
2044  * is found:
2045  * @code class match_char
2046  * {
2047  * public:
2048  *   explicit match_char(char c) : c_(c) {}
2049  *
2050  *   template <typename Iterator>
2051  *   std::pair<Iterator, bool> operator()(
2052  *       Iterator begin, Iterator end) const
2053  *   {
2054  *     Iterator i = begin;
2055  *     while (i != end)
2056  *       if (c_ == *i++)
2057  *         return std::make_pair(i, true);
2058  *     return std::make_pair(i, false);
2059  *   }
2060  *
2061  * private:
2062  *   char c_;
2063  * };
2064  *
2065  * namespace asio {
2066  *   template <> struct is_match_condition<match_char>
2067  *     : public boost::true_type {};
2068  * } // namespace asio
2069  * ...
2070  * void handler(const boost::system::error_code& e, std::size_t size);
2071  * ...
2072  * std::string data;
2073  * boost::asio::async_read_until(s, data, match_char('a'), handler);
2074  * @endcode
2075  *
2076  * @par Per-Operation Cancellation
2077  * This asynchronous operation supports cancellation for the following
2078  * boost::asio::cancellation_type values:
2079  *
2080  * @li @c cancellation_type::terminal
2081  *
2082  * @li @c cancellation_type::partial
2083  *
2084  * if they are also supported by the @c AsyncReadStream type's
2085  * @c async_read_some operation.
2086  */
2087 template <typename AsyncReadStream,
2088     typename DynamicBuffer_v1, typename MatchCondition,
2089     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2090       std::size_t)) ReadToken = default_completion_token_t<
2091         typename AsyncReadStream::executor_type>>
2092 inline auto async_read_until(AsyncReadStream& s,
2093     DynamicBuffer_v1&& buffers, MatchCondition match_condition,
2094     ReadToken&& token = default_completion_token_t<
2095       typename AsyncReadStream::executor_type>(),
2096     constraint_t<
2097       is_match_condition<MatchCondition>::value
2098     > = 0,
2099     constraint_t<
2100       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
2101     > = 0,
2102     constraint_t<
2103       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
2104     > = 0)
2105   -> decltype(
2106     async_initiate<ReadToken,
2107       void (boost::system::error_code, std::size_t)>(
2108         declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),
2109         token, static_cast<DynamicBuffer_v1&&>(buffers),
2110         match_condition))
2111 {
2112   return async_initiate<ReadToken,
2113     void (boost::system::error_code, std::size_t)>(
2114       detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),
2115       token, static_cast<DynamicBuffer_v1&&>(buffers),
2116       match_condition);
2117 }
2118 
2119 #if !defined(BOOST_ASIO_NO_IOSTREAM)
2120 
2121 /// Start an asynchronous operation to read data into a streambuf until it
2122 /// contains a specified delimiter.
2123 /**
2124  * This function is used to asynchronously read data into the specified
2125  * streambuf until the streambuf's get area contains the specified delimiter.
2126  * It is an initiating function for an @ref asynchronous_operation, and always
2127  * returns immediately. The asynchronous operation will continue until one of
2128  * the following conditions is true:
2129  *
2130  * @li The get area of the streambuf contains the specified delimiter.
2131  *
2132  * @li An error occurred.
2133  *
2134  * This operation is implemented in terms of zero or more calls to the stream's
2135  * async_read_some function, and is known as a <em>composed operation</em>. If
2136  * the streambuf's get area already contains the delimiter, this asynchronous
2137  * operation completes immediately. The program must ensure that the stream
2138  * performs no other read operations (such as async_read, async_read_until, the
2139  * stream's async_read_some function, or any other composed operations that
2140  * perform reads) until this operation completes.
2141  *
2142  * @param s The stream from which the data is to be read. The type must support
2143  * the AsyncReadStream concept.
2144  *
2145  * @param b A streambuf object into which the data will be read. Ownership of
2146  * the streambuf is retained by the caller, which must guarantee that it remains
2147  * valid until the completion handler is called.
2148  *
2149  * @param delim The delimiter character.
2150  *
2151  * @param token The @ref completion_token that will be used to produce a
2152  * completion handler, which will be called when the read completes.
2153  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2154  * @ref yield_context, or a function object with the correct completion
2155  * signature. The function signature of the completion handler must be:
2156  * @code void handler(
2157  *   // Result of operation.
2158  *   const boost::system::error_code& error,
2159  *
2160  *   // The number of bytes in the streambuf's get
2161  *   // area up to and including the delimiter.
2162  *   // 0 if an error occurred.
2163  *   std::size_t bytes_transferred
2164  * ); @endcode
2165  * Regardless of whether the asynchronous operation completes immediately or
2166  * not, the completion handler will not be invoked from within this function.
2167  * On immediate completion, invocation of the handler will be performed in a
2168  * manner equivalent to using boost::asio::async_immediate().
2169  *
2170  * @par Completion Signature
2171  * @code void(boost::system::error_code, std::size_t) @endcode
2172  *
2173  * @note After a successful async_read_until operation, the streambuf may
2174  * contain additional data beyond the delimiter. An application will typically
2175  * leave that data in the streambuf for a subsequent async_read_until operation
2176  * to examine.
2177  *
2178  * @par Example
2179  * To asynchronously read data into a streambuf until a newline is encountered:
2180  * @code boost::asio::streambuf b;
2181  * ...
2182  * void handler(const boost::system::error_code& e, std::size_t size)
2183  * {
2184  *   if (!e)
2185  *   {
2186  *     std::istream is(&b);
2187  *     std::string line;
2188  *     std::getline(is, line);
2189  *     ...
2190  *   }
2191  * }
2192  * ...
2193  * boost::asio::async_read_until(s, b, '\n', handler); @endcode
2194  * After the @c async_read_until operation completes successfully, the buffer
2195  * @c b contains the delimiter:
2196  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
2197  * The call to @c std::getline then extracts the data up to and including the
2198  * newline (which is discarded), so that the string @c line contains:
2199  * @code { 'a', 'b', ..., 'c' } @endcode
2200  * The remaining data is left in the buffer @c b as follows:
2201  * @code { 'd', 'e', ... } @endcode
2202  * This data may be the start of a new line, to be extracted by a subsequent
2203  * @c async_read_until operation.
2204  *
2205  * @par Per-Operation Cancellation
2206  * This asynchronous operation supports cancellation for the following
2207  * boost::asio::cancellation_type values:
2208  *
2209  * @li @c cancellation_type::terminal
2210  *
2211  * @li @c cancellation_type::partial
2212  *
2213  * if they are also supported by the @c AsyncReadStream type's
2214  * @c async_read_some operation.
2215  */
2216 template <typename AsyncReadStream, typename Allocator,
2217     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2218       std::size_t)) ReadToken = default_completion_token_t<
2219         typename AsyncReadStream::executor_type>>
2220 inline auto async_read_until(AsyncReadStream& s,
2221     boost::asio::basic_streambuf<Allocator>& b, char delim,
2222     ReadToken&& token = default_completion_token_t<
2223       typename AsyncReadStream::executor_type>())
2224   -> decltype(
2225     async_initiate<ReadToken,
2226       void (boost::system::error_code, std::size_t)>(
2227         declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),
2228         token, basic_streambuf_ref<Allocator>(b), delim))
2229 {
2230   return async_initiate<ReadToken,
2231     void (boost::system::error_code, std::size_t)>(
2232       detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),
2233       token, basic_streambuf_ref<Allocator>(b), delim);
2234 }
2235 
2236 /// Start an asynchronous operation to read data into a streambuf until it
2237 /// contains a specified delimiter.
2238 /**
2239  * This function is used to asynchronously read data into the specified
2240  * streambuf until the streambuf's get area contains the specified delimiter.
2241  * It is an initiating function for an @ref asynchronous_operation, and always
2242  * returns immediately. The asynchronous operation will continue until one of
2243  * the following conditions is true:
2244  *
2245  * @li The get area of the streambuf contains the specified delimiter.
2246  *
2247  * @li An error occurred.
2248  *
2249  * This operation is implemented in terms of zero or more calls to the stream's
2250  * async_read_some function, and is known as a <em>composed operation</em>. If
2251  * the streambuf's get area already contains the delimiter, this asynchronous
2252  * operation completes immediately. The program must ensure that the stream
2253  * performs no other read operations (such as async_read, async_read_until, the
2254  * stream's async_read_some function, or any other composed operations that
2255  * perform reads) until this operation completes.
2256  *
2257  * @param s The stream from which the data is to be read. The type must support
2258  * the AsyncReadStream concept.
2259  *
2260  * @param b A streambuf object into which the data will be read. Ownership of
2261  * the streambuf is retained by the caller, which must guarantee that it remains
2262  * valid until the completion handler is called.
2263  *
2264  * @param delim The delimiter string.
2265  *
2266  * @param token The @ref completion_token that will be used to produce a
2267  * completion handler, which will be called when the read completes.
2268  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2269  * @ref yield_context, or a function object with the correct completion
2270  * signature. The function signature of the completion handler must be:
2271  * @code void handler(
2272  *   // Result of operation.
2273  *   const boost::system::error_code& error,
2274  *
2275  *   // The number of bytes in the streambuf's get
2276  *   // area up to and including the delimiter.
2277  *   // 0 if an error occurred.
2278  *   std::size_t bytes_transferred
2279  * ); @endcode
2280  * Regardless of whether the asynchronous operation completes immediately or
2281  * not, the completion handler will not be invoked from within this function.
2282  * On immediate completion, invocation of the handler will be performed in a
2283  * manner equivalent to using boost::asio::async_immediate().
2284  *
2285  * @par Completion Signature
2286  * @code void(boost::system::error_code, std::size_t) @endcode
2287  *
2288  * @note After a successful async_read_until operation, the streambuf may
2289  * contain additional data beyond the delimiter. An application will typically
2290  * leave that data in the streambuf for a subsequent async_read_until operation
2291  * to examine.
2292  *
2293  * @par Example
2294  * To asynchronously read data into a streambuf until a newline is encountered:
2295  * @code boost::asio::streambuf b;
2296  * ...
2297  * void handler(const boost::system::error_code& e, std::size_t size)
2298  * {
2299  *   if (!e)
2300  *   {
2301  *     std::istream is(&b);
2302  *     std::string line;
2303  *     std::getline(is, line);
2304  *     ...
2305  *   }
2306  * }
2307  * ...
2308  * boost::asio::async_read_until(s, b, "\r\n", handler); @endcode
2309  * After the @c async_read_until operation completes successfully, the buffer
2310  * @c b contains the delimiter:
2311  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2312  * The call to @c std::getline then extracts the data up to and including the
2313  * newline (which is discarded), so that the string @c line contains:
2314  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
2315  * The remaining data is left in the buffer @c b as follows:
2316  * @code { 'd', 'e', ... } @endcode
2317  * This data may be the start of a new line, to be extracted by a subsequent
2318  * @c async_read_until operation.
2319  *
2320  * @par Per-Operation Cancellation
2321  * This asynchronous operation supports cancellation for the following
2322  * boost::asio::cancellation_type values:
2323  *
2324  * @li @c cancellation_type::terminal
2325  *
2326  * @li @c cancellation_type::partial
2327  *
2328  * if they are also supported by the @c AsyncReadStream type's
2329  * @c async_read_some operation.
2330  */
2331 template <typename AsyncReadStream, typename Allocator,
2332     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2333       std::size_t)) ReadToken = default_completion_token_t<
2334         typename AsyncReadStream::executor_type>>
2335 inline auto async_read_until(AsyncReadStream& s,
2336     boost::asio::basic_streambuf<Allocator>& b,
2337     BOOST_ASIO_STRING_VIEW_PARAM delim,
2338     ReadToken&& token = default_completion_token_t<
2339       typename AsyncReadStream::executor_type>())
2340   -> decltype(
2341     async_initiate<ReadToken,
2342       void (boost::system::error_code, std::size_t)>(
2343         declval<detail::initiate_async_read_until_delim_string_v1<
2344           AsyncReadStream>>(),
2345         token, basic_streambuf_ref<Allocator>(b),
2346         static_cast<std::string>(delim)))
2347 {
2348   return async_initiate<ReadToken,
2349     void (boost::system::error_code, std::size_t)>(
2350       detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),
2351       token, basic_streambuf_ref<Allocator>(b),
2352       static_cast<std::string>(delim));
2353 }
2354 
2355 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
2356   || defined(GENERATING_DOCUMENTATION)
2357 
2358 /// Start an asynchronous operation to read data into a streambuf until some
2359 /// part of its data matches a regular expression.
2360 /**
2361  * This function is used to asynchronously read data into the specified
2362  * streambuf until the streambuf's get area contains some data that matches a
2363  * regular expression. It is an initiating function for an @ref
2364  * asynchronous_operation, and always returns immediately. The asynchronous
2365  * operation will continue until one of the following conditions is true:
2366  *
2367  * @li A substring of the streambuf's get area matches the regular expression.
2368  *
2369  * @li An error occurred.
2370  *
2371  * This operation is implemented in terms of zero or more calls to the stream's
2372  * async_read_some function, and is known as a <em>composed operation</em>. If
2373  * the streambuf's get area already contains data that matches the regular
2374  * expression, this asynchronous operation completes immediately. The program
2375  * must ensure that the stream performs no other read operations (such as
2376  * async_read, async_read_until, the stream's async_read_some function, or any
2377  * other composed operations that perform reads) until this operation
2378  * completes.
2379  *
2380  * @param s The stream from which the data is to be read. The type must support
2381  * the AsyncReadStream concept.
2382  *
2383  * @param b A streambuf object into which the data will be read. Ownership of
2384  * the streambuf is retained by the caller, which must guarantee that it remains
2385  * valid until the completion handler is called.
2386  *
2387  * @param expr The regular expression.
2388  *
2389  * @param token The @ref completion_token that will be used to produce a
2390  * completion handler, which will be called when the read completes.
2391  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2392  * @ref yield_context, or a function object with the correct completion
2393  * signature. The function signature of the completion handler must be:
2394  * @code void handler(
2395  *   // Result of operation.
2396  *   const boost::system::error_code& error,
2397  *
2398  *   // The number of bytes in the streambuf's get
2399  *   // area up to and including the substring
2400  *   // that matches the regular. expression.
2401  *   // 0 if an error occurred.
2402  *   std::size_t bytes_transferred
2403  * ); @endcode
2404  * Regardless of whether the asynchronous operation completes immediately or
2405  * not, the completion handler will not be invoked from within this function.
2406  * On immediate completion, invocation of the handler will be performed in a
2407  * manner equivalent to using boost::asio::async_immediate().
2408  *
2409  * @par Completion Signature
2410  * @code void(boost::system::error_code, std::size_t) @endcode
2411  *
2412  * @note After a successful async_read_until operation, the streambuf may
2413  * contain additional data beyond that which matched the regular expression. An
2414  * application will typically leave that data in the streambuf for a subsequent
2415  * async_read_until operation to examine.
2416  *
2417  * @par Example
2418  * To asynchronously read data into a streambuf until a CR-LF sequence is
2419  * encountered:
2420  * @code boost::asio::streambuf b;
2421  * ...
2422  * void handler(const boost::system::error_code& e, std::size_t size)
2423  * {
2424  *   if (!e)
2425  *   {
2426  *     std::istream is(&b);
2427  *     std::string line;
2428  *     std::getline(is, line);
2429  *     ...
2430  *   }
2431  * }
2432  * ...
2433  * boost::asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode
2434  * After the @c async_read_until operation completes successfully, the buffer
2435  * @c b contains the data which matched the regular expression:
2436  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2437  * The call to @c std::getline then extracts the data up to and including the
2438  * newline (which is discarded), so that the string @c line contains:
2439  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
2440  * The remaining data is left in the buffer @c b as follows:
2441  * @code { 'd', 'e', ... } @endcode
2442  * This data may be the start of a new line, to be extracted by a subsequent
2443  * @c async_read_until operation.
2444  *
2445  * @par Per-Operation Cancellation
2446  * This asynchronous operation supports cancellation for the following
2447  * boost::asio::cancellation_type values:
2448  *
2449  * @li @c cancellation_type::terminal
2450  *
2451  * @li @c cancellation_type::partial
2452  *
2453  * if they are also supported by the @c AsyncReadStream type's
2454  * @c async_read_some operation.
2455  */
2456 template <typename AsyncReadStream, typename Allocator, typename Traits,
2457     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2458       std::size_t)) ReadToken = default_completion_token_t<
2459         typename AsyncReadStream::executor_type>>
2460 inline auto async_read_until(AsyncReadStream& s,
2461     boost::asio::basic_streambuf<Allocator>& b,
2462     const boost::basic_regex<char, Traits>& expr,
2463     ReadToken&& token = default_completion_token_t<
2464       typename AsyncReadStream::executor_type>())
2465   -> decltype(
2466     async_initiate<ReadToken,
2467       void (boost::system::error_code, std::size_t)>(
2468         declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),
2469         token, basic_streambuf_ref<Allocator>(b), expr))
2470 {
2471   return async_initiate<ReadToken,
2472     void (boost::system::error_code, std::size_t)>(
2473       detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),
2474       token, basic_streambuf_ref<Allocator>(b), expr);
2475 }
2476 
2477 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
2478        // || defined(GENERATING_DOCUMENTATION)
2479 
2480 /// Start an asynchronous operation to read data into a streambuf until a
2481 /// function object indicates a match.
2482 /**
2483  * This function is used to asynchronously read data into the specified
2484  * streambuf until a user-defined match condition function object, when applied
2485  * to the data contained in the streambuf, indicates a successful match. It is
2486  * an initiating function for an @ref asynchronous_operation, and always
2487  * returns immediately. The asynchronous operation will continue until one of
2488  * the following conditions is true:
2489  *
2490  * @li The match condition function object returns a std::pair where the second
2491  * element evaluates to true.
2492  *
2493  * @li An error occurred.
2494  *
2495  * This operation is implemented in terms of zero or more calls to the stream's
2496  * async_read_some function, and is known as a <em>composed operation</em>. If
2497  * the match condition function object already indicates a match, this
2498  * asynchronous operation completes immediately. The program must ensure that
2499  * the stream performs no other read operations (such as async_read,
2500  * async_read_until, the stream's async_read_some function, or any other
2501  * composed operations that perform reads) until this operation completes.
2502  *
2503  * @param s The stream from which the data is to be read. The type must support
2504  * the AsyncReadStream concept.
2505  *
2506  * @param b A streambuf object into which the data will be read.
2507  *
2508  * @param match_condition The function object to be called to determine whether
2509  * a match exists. The signature of the function object must be:
2510  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
2511  * @endcode
2512  * where @c iterator represents the type:
2513  * @code buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
2514  * @endcode
2515  * The iterator parameters @c begin and @c end define the range of bytes to be
2516  * scanned to determine whether there is a match. The @c first member of the
2517  * return value is an iterator marking one-past-the-end of the bytes that have
2518  * been consumed by the match function. This iterator is used to calculate the
2519  * @c begin parameter for any subsequent invocation of the match condition. The
2520  * @c second member of the return value is true if a match has been found, false
2521  * otherwise.
2522  *
2523  * @param token The @ref completion_token that will be used to produce a
2524  * completion handler, which will be called when the read completes.
2525  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2526  * @ref yield_context, or a function object with the correct completion
2527  * signature. The function signature of the completion handler must be:
2528  * @code void handler(
2529  *   // Result of operation.
2530  *   const boost::system::error_code& error,
2531  *
2532  *   // The number of bytes in the streambuf's get
2533  *   // area that have been fully consumed by the
2534  *   // match function. O if an error occurred.
2535  *   std::size_t bytes_transferred
2536  * ); @endcode
2537  * Regardless of whether the asynchronous operation completes immediately or
2538  * not, the completion handler will not be invoked from within this function.
2539  * On immediate completion, invocation of the handler will be performed in a
2540  * manner equivalent to using boost::asio::async_immediate().
2541  *
2542  * @note After a successful async_read_until operation, the streambuf may
2543  * contain additional data beyond that which matched the function object. An
2544  * application will typically leave that data in the streambuf for a subsequent
2545  * async_read_until operation to examine.
2546  *
2547  * @par Completion Signature
2548  * @code void(boost::system::error_code, std::size_t) @endcode
2549  *
2550  * @note The default implementation of the @c is_match_condition type trait
2551  * evaluates to true for function pointers and function objects with a
2552  * @c result_type typedef. It must be specialised for other user-defined
2553  * function objects.
2554  *
2555  * @par Examples
2556  * To asynchronously read data into a streambuf until whitespace is encountered:
2557  * @code typedef boost::asio::buffers_iterator<
2558  *     boost::asio::streambuf::const_buffers_type> iterator;
2559  *
2560  * std::pair<iterator, bool>
2561  * match_whitespace(iterator begin, iterator end)
2562  * {
2563  *   iterator i = begin;
2564  *   while (i != end)
2565  *     if (std::isspace(*i++))
2566  *       return std::make_pair(i, true);
2567  *   return std::make_pair(i, false);
2568  * }
2569  * ...
2570  * void handler(const boost::system::error_code& e, std::size_t size);
2571  * ...
2572  * boost::asio::streambuf b;
2573  * boost::asio::async_read_until(s, b, match_whitespace, handler);
2574  * @endcode
2575  *
2576  * To asynchronously read data into a streambuf until a matching character is
2577  * found:
2578  * @code class match_char
2579  * {
2580  * public:
2581  *   explicit match_char(char c) : c_(c) {}
2582  *
2583  *   template <typename Iterator>
2584  *   std::pair<Iterator, bool> operator()(
2585  *       Iterator begin, Iterator end) const
2586  *   {
2587  *     Iterator i = begin;
2588  *     while (i != end)
2589  *       if (c_ == *i++)
2590  *         return std::make_pair(i, true);
2591  *     return std::make_pair(i, false);
2592  *   }
2593  *
2594  * private:
2595  *   char c_;
2596  * };
2597  *
2598  * namespace asio {
2599  *   template <> struct is_match_condition<match_char>
2600  *     : public boost::true_type {};
2601  * } // namespace asio
2602  * ...
2603  * void handler(const boost::system::error_code& e, std::size_t size);
2604  * ...
2605  * boost::asio::streambuf b;
2606  * boost::asio::async_read_until(s, b, match_char('a'), handler);
2607  * @endcode
2608  *
2609  * @par Per-Operation Cancellation
2610  * This asynchronous operation supports cancellation for the following
2611  * boost::asio::cancellation_type values:
2612  *
2613  * @li @c cancellation_type::terminal
2614  *
2615  * @li @c cancellation_type::partial
2616  *
2617  * if they are also supported by the @c AsyncReadStream type's
2618  * @c async_read_some operation.
2619  */
2620 template <typename AsyncReadStream, typename Allocator, typename MatchCondition,
2621     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2622       std::size_t)) ReadToken = default_completion_token_t<
2623         typename AsyncReadStream::executor_type>>
2624 inline auto async_read_until(AsyncReadStream& s,
2625     boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,
2626     ReadToken&& token = default_completion_token_t<
2627       typename AsyncReadStream::executor_type>(),
2628     constraint_t<is_match_condition<MatchCondition>::value> = 0)
2629   -> decltype(
2630     async_initiate<ReadToken,
2631       void (boost::system::error_code, std::size_t)>(
2632         declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),
2633         token, basic_streambuf_ref<Allocator>(b), match_condition))
2634 {
2635   return async_initiate<ReadToken,
2636     void (boost::system::error_code, std::size_t)>(
2637       detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),
2638       token, basic_streambuf_ref<Allocator>(b), match_condition);
2639 }
2640 
2641 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
2642 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
2643 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2644 
2645 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2646 /// until it contains a specified delimiter.
2647 /**
2648  * This function is used to asynchronously read data into the specified dynamic
2649  * buffer sequence until the dynamic buffer sequence's get area contains the
2650  * specified delimiter. It is an initiating function for an @ref
2651  * asynchronous_operation, and always returns immediately. The asynchronous
2652  * operation will continue until one of the following conditions is true:
2653  *
2654  * @li The get area of the dynamic buffer sequence contains the specified
2655  * delimiter.
2656  *
2657  * @li An error occurred.
2658  *
2659  * This operation is implemented in terms of zero or more calls to the stream's
2660  * async_read_some function, and is known as a <em>composed operation</em>. If
2661  * the dynamic buffer sequence's get area already contains the delimiter, this
2662  * asynchronous operation completes immediately. The program must ensure that
2663  * the stream performs no other read operations (such as async_read,
2664  * async_read_until, the stream's async_read_some function, or any other
2665  * composed operations that perform reads) until this operation completes.
2666  *
2667  * @param s The stream from which the data is to be read. The type must support
2668  * the AsyncReadStream concept.
2669  *
2670  * @param buffers The dynamic buffer sequence into which the data will be read.
2671  * Although the buffers object may be copied as necessary, ownership of the
2672  * underlying memory blocks is retained by the caller, which must guarantee
2673  * that they remain valid until the completion handler is called.
2674  *
2675  * @param delim The delimiter character.
2676  *
2677  * @param token The @ref completion_token that will be used to produce a
2678  * completion handler, which will be called when the read completes.
2679  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2680  * @ref yield_context, or a function object with the correct completion
2681  * signature. The function signature of the completion handler must be:
2682  * @code void handler(
2683  *   // Result of operation.
2684  *   const boost::system::error_code& error,
2685  *
2686  *   // The number of bytes in the dynamic buffer sequence's
2687  *   // get area up to and including the delimiter.
2688  *   // 0 if an error occurred.
2689  *   std::size_t bytes_transferred
2690  * ); @endcode
2691  * Regardless of whether the asynchronous operation completes immediately or
2692  * not, the completion handler will not be invoked from within this function.
2693  * On immediate completion, invocation of the handler will be performed in a
2694  * manner equivalent to using boost::asio::async_immediate().
2695  *
2696  * @par Completion Signature
2697  * @code void(boost::system::error_code, std::size_t) @endcode
2698  *
2699  * @note After a successful async_read_until operation, the dynamic buffer
2700  * sequence may contain additional data beyond the delimiter. An application
2701  * will typically leave that data in the dynamic buffer sequence for a
2702  * subsequent async_read_until operation to examine.
2703  *
2704  * @par Example
2705  * To asynchronously read data into a @c std::string until a newline is
2706  * encountered:
2707  * @code std::string data;
2708  * ...
2709  * void handler(const boost::system::error_code& e, std::size_t size)
2710  * {
2711  *   if (!e)
2712  *   {
2713  *     std::string line = data.substr(0, n);
2714  *     data.erase(0, n);
2715  *     ...
2716  *   }
2717  * }
2718  * ...
2719  * boost::asio::async_read_until(s, data, '\n', handler); @endcode
2720  * After the @c async_read_until operation completes successfully, the buffer
2721  * @c data contains the delimiter:
2722  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
2723  * The call to @c substr then extracts the data up to and including the
2724  * delimiter, so that the string @c line contains:
2725  * @code { 'a', 'b', ..., 'c', '\n' } @endcode
2726  * After the call to @c erase, the remaining data is left in the buffer @c data
2727  * as follows:
2728  * @code { 'd', 'e', ... } @endcode
2729  * This data may be the start of a new line, to be extracted by a subsequent
2730  * @c async_read_until operation.
2731  *
2732  * @par Per-Operation Cancellation
2733  * This asynchronous operation supports cancellation for the following
2734  * boost::asio::cancellation_type values:
2735  *
2736  * @li @c cancellation_type::terminal
2737  *
2738  * @li @c cancellation_type::partial
2739  *
2740  * if they are also supported by the @c AsyncReadStream type's
2741  * @c async_read_some operation.
2742  */
2743 template <typename AsyncReadStream, typename DynamicBuffer_v2,
2744     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2745       std::size_t)) ReadToken = default_completion_token_t<
2746         typename AsyncReadStream::executor_type>>
2747 inline auto async_read_until(AsyncReadStream& s,
2748     DynamicBuffer_v2 buffers, char delim,
2749     ReadToken&& token = default_completion_token_t<
2750       typename AsyncReadStream::executor_type>(),
2751     constraint_t<
2752       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
2753     > = 0)
2754   -> decltype(
2755     async_initiate<ReadToken,
2756       void (boost::system::error_code, std::size_t)>(
2757         declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream>>(),
2758         token, static_cast<DynamicBuffer_v2&&>(buffers), delim))
2759 {
2760   return async_initiate<ReadToken,
2761     void (boost::system::error_code, std::size_t)>(
2762       detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),
2763       token, static_cast<DynamicBuffer_v2&&>(buffers), delim);
2764 }
2765 
2766 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2767 /// until it contains a specified delimiter.
2768 /**
2769  * This function is used to asynchronously read data into the specified dynamic
2770  * buffer sequence until the dynamic buffer sequence's get area contains the
2771  * specified delimiter. It is an initiating function for an @ref
2772  * asynchronous_operation, and always returns immediately. The asynchronous
2773  * operation will continue until one of the following conditions is true:
2774  *
2775  * @li The get area of the dynamic buffer sequence contains the specified
2776  * delimiter.
2777  *
2778  * @li An error occurred.
2779  *
2780  * This operation is implemented in terms of zero or more calls to the stream's
2781  * async_read_some function, and is known as a <em>composed operation</em>. If
2782  * the dynamic buffer sequence's get area already contains the delimiter, this
2783  * asynchronous operation completes immediately. The program must ensure that
2784  * the stream performs no other read operations (such as async_read,
2785  * async_read_until, the stream's async_read_some function, or any other
2786  * composed operations that perform reads) until this operation completes.
2787  *
2788  * @param s The stream from which the data is to be read. The type must support
2789  * the AsyncReadStream concept.
2790  *
2791  * @param buffers The dynamic buffer sequence into which the data will be read.
2792  * Although the buffers object may be copied as necessary, ownership of the
2793  * underlying memory blocks is retained by the caller, which must guarantee
2794  * that they remain valid until the completion handler is called.
2795  *
2796  * @param delim The delimiter string.
2797  *
2798  * @param token The @ref completion_token that will be used to produce a
2799  * completion handler, which will be called when the read completes.
2800  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2801  * @ref yield_context, or a function object with the correct completion
2802  * signature. The function signature of the completion handler must be:
2803  * @code void handler(
2804  *   // Result of operation.
2805  *   const boost::system::error_code& error,
2806  *
2807  *   // The number of bytes in the dynamic buffer sequence's
2808  *   // get area up to and including the delimiter.
2809  *   std::size_t bytes_transferred
2810  * ); @endcode
2811  * Regardless of whether the asynchronous operation completes immediately or
2812  * not, the completion handler will not be invoked from within this function.
2813  * On immediate completion, invocation of the handler will be performed in a
2814  * manner equivalent to using boost::asio::async_immediate().
2815  *
2816  * @par Completion Signature
2817  * @code void(boost::system::error_code, std::size_t) @endcode
2818  *
2819  * @note After a successful async_read_until operation, the dynamic buffer
2820  * sequence may contain additional data beyond the delimiter. An application
2821  * will typically leave that data in the dynamic buffer sequence for a
2822  * subsequent async_read_until operation to examine.
2823  *
2824  * @par Example
2825  * To asynchronously read data into a @c std::string until a CR-LF sequence is
2826  * encountered:
2827  * @code std::string data;
2828  * ...
2829  * void handler(const boost::system::error_code& e, std::size_t size)
2830  * {
2831  *   if (!e)
2832  *   {
2833  *     std::string line = data.substr(0, n);
2834  *     data.erase(0, n);
2835  *     ...
2836  *   }
2837  * }
2838  * ...
2839  * boost::asio::async_read_until(s, data, "\r\n", handler); @endcode
2840  * After the @c async_read_until operation completes successfully, the string
2841  * @c data contains the delimiter:
2842  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2843  * The call to @c substr then extracts the data up to and including the
2844  * delimiter, so that the string @c line contains:
2845  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
2846  * After the call to @c erase, the remaining data is left in the string @c data
2847  * as follows:
2848  * @code { 'd', 'e', ... } @endcode
2849  * This data may be the start of a new line, to be extracted by a subsequent
2850  * @c async_read_until operation.
2851  *
2852  * @par Per-Operation Cancellation
2853  * This asynchronous operation supports cancellation for the following
2854  * boost::asio::cancellation_type values:
2855  *
2856  * @li @c cancellation_type::terminal
2857  *
2858  * @li @c cancellation_type::partial
2859  *
2860  * if they are also supported by the @c AsyncReadStream type's
2861  * @c async_read_some operation.
2862  */
2863 template <typename AsyncReadStream, typename DynamicBuffer_v2,
2864     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2865       std::size_t)) ReadToken = default_completion_token_t<
2866         typename AsyncReadStream::executor_type>>
2867 inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
2868     BOOST_ASIO_STRING_VIEW_PARAM delim,
2869     ReadToken&& token = default_completion_token_t<
2870       typename AsyncReadStream::executor_type>(),
2871     constraint_t<
2872       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
2873     > = 0)
2874   -> decltype(
2875     async_initiate<ReadToken,
2876       void (boost::system::error_code, std::size_t)>(
2877         declval<detail::initiate_async_read_until_delim_string_v2<
2878           AsyncReadStream>>(),
2879         token, static_cast<DynamicBuffer_v2&&>(buffers),
2880         static_cast<std::string>(delim)))
2881 {
2882   return async_initiate<ReadToken,
2883     void (boost::system::error_code, std::size_t)>(
2884       detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),
2885       token, static_cast<DynamicBuffer_v2&&>(buffers),
2886       static_cast<std::string>(delim));
2887 }
2888 
2889 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
2890 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
2891   || defined(GENERATING_DOCUMENTATION)
2892 
2893 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2894 /// until some part of its data matches a regular expression.
2895 /**
2896  * This function is used to asynchronously read data into the specified dynamic
2897  * buffer sequence until the dynamic buffer sequence's get area contains some
2898  * data that matches a regular expression. It is an initiating function for an
2899  * @ref asynchronous_operation, and always returns immediately. The
2900  * asynchronous operation will continue until one of the following conditions
2901  * is true:
2902  *
2903  * @li A substring of the dynamic buffer sequence's get area matches the regular
2904  * expression.
2905  *
2906  * @li An error occurred.
2907  *
2908  * This operation is implemented in terms of zero or more calls to the stream's
2909  * async_read_some function, and is known as a <em>composed operation</em>. If
2910  * the dynamic buffer sequence's get area already contains data that matches
2911  * the regular expression, this asynchronous operation completes immediately.
2912  * The program must ensure that the stream performs no other read operations
2913  * (such as async_read, async_read_until, the stream's async_read_some
2914  * function, or any other composed operations that perform reads) until this
2915  * operation completes.
2916  *
2917  * @param s The stream from which the data is to be read. The type must support
2918  * the AsyncReadStream concept.
2919  *
2920  * @param buffers The dynamic buffer sequence into which the data will be read.
2921  * Although the buffers object may be copied as necessary, ownership of the
2922  * underlying memory blocks is retained by the caller, which must guarantee
2923  * that they remain valid until the completion handler is called.
2924  *
2925  * @param expr The regular expression.
2926  *
2927  * @param token The @ref completion_token that will be used to produce a
2928  * completion handler, which will be called when the read completes.
2929  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2930  * @ref yield_context, or a function object with the correct completion
2931  * signature. The function signature of the completion handler must be:
2932  * @code void handler(
2933  *   // Result of operation.
2934  *   const boost::system::error_code& error,
2935  *
2936  *   // The number of bytes in the dynamic buffer
2937  *   // sequence's get area up to and including the
2938  *   // substring that matches the regular expression.
2939  *   // 0 if an error occurred.
2940  *   std::size_t bytes_transferred
2941  * ); @endcode
2942  * Regardless of whether the asynchronous operation completes immediately or
2943  * not, the completion handler will not be invoked from within this function.
2944  * On immediate completion, invocation of the handler will be performed in a
2945  * manner equivalent to using boost::asio::async_immediate().
2946  *
2947  * @par Completion Signature
2948  * @code void(boost::system::error_code, std::size_t) @endcode
2949  *
2950  * @note After a successful async_read_until operation, the dynamic buffer
2951  * sequence may contain additional data beyond that which matched the regular
2952  * expression. An application will typically leave that data in the dynamic
2953  * buffer sequence for a subsequent async_read_until operation to examine.
2954  *
2955  * @par Example
2956  * To asynchronously read data into a @c std::string until a CR-LF sequence is
2957  * encountered:
2958  * @code std::string data;
2959  * ...
2960  * void handler(const boost::system::error_code& e, std::size_t size)
2961  * {
2962  *   if (!e)
2963  *   {
2964  *     std::string line = data.substr(0, n);
2965  *     data.erase(0, n);
2966  *     ...
2967  *   }
2968  * }
2969  * ...
2970  * boost::asio::async_read_until(s, data,
2971  *     boost::regex("\r\n"), handler); @endcode
2972  * After the @c async_read_until operation completes successfully, the string
2973  * @c data contains the data which matched the regular expression:
2974  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2975  * The call to @c substr then extracts the data up to and including the match,
2976  * so that the string @c line contains:
2977  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
2978  * After the call to @c erase, the remaining data is left in the string @c data
2979  * as follows:
2980  * @code { 'd', 'e', ... } @endcode
2981  * This data may be the start of a new line, to be extracted by a subsequent
2982  * @c async_read_until operation.
2983  *
2984  * @par Per-Operation Cancellation
2985  * This asynchronous operation supports cancellation for the following
2986  * boost::asio::cancellation_type values:
2987  *
2988  * @li @c cancellation_type::terminal
2989  *
2990  * @li @c cancellation_type::partial
2991  *
2992  * if they are also supported by the @c AsyncReadStream type's
2993  * @c async_read_some operation.
2994  */
2995 template <typename AsyncReadStream, typename DynamicBuffer_v2, typename Traits,
2996     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2997       std::size_t)) ReadToken = default_completion_token_t<
2998         typename AsyncReadStream::executor_type>>
2999 inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
3000     const boost::basic_regex<char, Traits>& expr,
3001     ReadToken&& token = default_completion_token_t<
3002       typename AsyncReadStream::executor_type>(),
3003     constraint_t<
3004       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
3005     > = 0)
3006   -> decltype(
3007     async_initiate<ReadToken,
3008       void (boost::system::error_code, std::size_t)>(
3009         declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream>>(),
3010         token, static_cast<DynamicBuffer_v2&&>(buffers), expr))
3011 {
3012   return async_initiate<ReadToken,
3013     void (boost::system::error_code, std::size_t)>(
3014       detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),
3015       token, static_cast<DynamicBuffer_v2&&>(buffers), expr);
3016 }
3017 
3018 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
3019        // || defined(GENERATING_DOCUMENTATION)
3020 
3021 /// Start an asynchronous operation to read data into a dynamic buffer sequence
3022 /// until a function object indicates a match.
3023 /**
3024  * This function is used to asynchronously read data into the specified dynamic
3025  * buffer sequence until a user-defined match condition function object, when
3026  * applied to the data contained in the dynamic buffer sequence, indicates a
3027  * successful match. It is an initiating function for an @ref
3028  * asynchronous_operation, and always returns immediately. The asynchronous
3029  * operation will continue until one of the following conditions is true:
3030  *
3031  * @li The match condition function object returns a std::pair where the second
3032  * element evaluates to true.
3033  *
3034  * @li An error occurred.
3035  *
3036  * This operation is implemented in terms of zero or more calls to the stream's
3037  * async_read_some function, and is known as a <em>composed operation</em>. If
3038  * the match condition function object already indicates a match, this
3039  * asynchronous operation completes immediately. The program must ensure that
3040  * the stream performs no other read operations (such as async_read,
3041  * async_read_until, the stream's async_read_some function, or any other
3042  * composed operations that perform reads) until this operation completes.
3043  *
3044  * @param s The stream from which the data is to be read. The type must support
3045  * the AsyncReadStream concept.
3046  *
3047  * @param buffers The dynamic buffer sequence into which the data will be read.
3048  * Although the buffers object may be copied as necessary, ownership of the
3049  * underlying memory blocks is retained by the caller, which must guarantee
3050  * that they remain valid until the completion handler is called.
3051  *
3052  * @param match_condition The function object to be called to determine whether
3053  * a match exists. The signature of the function object must be:
3054  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
3055  * @endcode
3056  * where @c iterator represents the type:
3057  * @code buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>
3058  * @endcode
3059  * The iterator parameters @c begin and @c end define the range of bytes to be
3060  * scanned to determine whether there is a match. The @c first member of the
3061  * return value is an iterator marking one-past-the-end of the bytes that have
3062  * been consumed by the match function. This iterator is used to calculate the
3063  * @c begin parameter for any subsequent invocation of the match condition. The
3064  * @c second member of the return value is true if a match has been found, false
3065  * otherwise.
3066  *
3067  * @param token The @ref completion_token that will be used to produce a
3068  * completion handler, which will be called when the read completes.
3069  * Potential completion tokens include @ref use_future, @ref use_awaitable,
3070  * @ref yield_context, or a function object with the correct completion
3071  * signature. The function signature of the completion handler must be:
3072  * @code void handler(
3073  *   // Result of operation.
3074  *   const boost::system::error_code& error,
3075  *
3076  *   // The number of bytes in the dynamic buffer sequence's
3077  *   // get area that have been fully consumed by the match
3078  *   // function. O if an error occurred.
3079  *   std::size_t bytes_transferred
3080  * ); @endcode
3081  * Regardless of whether the asynchronous operation completes immediately or
3082  * not, the completion handler will not be invoked from within this function.
3083  * On immediate completion, invocation of the handler will be performed in a
3084  * manner equivalent to using boost::asio::async_immediate().
3085  *
3086  * @note After a successful async_read_until operation, the dynamic buffer
3087  * sequence may contain additional data beyond that which matched the function
3088  * object. An application will typically leave that data in the dynamic buffer
3089  * sequence for a subsequent async_read_until operation to examine.
3090  *
3091  * @par Completion Signature
3092  * @code void(boost::system::error_code, std::size_t) @endcode
3093  *
3094  * @note The default implementation of the @c is_match_condition type trait
3095  * evaluates to true for function pointers and function objects with a
3096  * @c result_type typedef. It must be specialised for other user-defined
3097  * function objects.
3098  *
3099  * @par Examples
3100  * To asynchronously read data into a @c std::string until whitespace is
3101  * encountered:
3102  * @code typedef boost::asio::buffers_iterator<
3103  *     boost::asio::const_buffers_1> iterator;
3104  *
3105  * std::pair<iterator, bool>
3106  * match_whitespace(iterator begin, iterator end)
3107  * {
3108  *   iterator i = begin;
3109  *   while (i != end)
3110  *     if (std::isspace(*i++))
3111  *       return std::make_pair(i, true);
3112  *   return std::make_pair(i, false);
3113  * }
3114  * ...
3115  * void handler(const boost::system::error_code& e, std::size_t size);
3116  * ...
3117  * std::string data;
3118  * boost::asio::async_read_until(s, data, match_whitespace, handler);
3119  * @endcode
3120  *
3121  * To asynchronously read data into a @c std::string until a matching character
3122  * is found:
3123  * @code class match_char
3124  * {
3125  * public:
3126  *   explicit match_char(char c) : c_(c) {}
3127  *
3128  *   template <typename Iterator>
3129  *   std::pair<Iterator, bool> operator()(
3130  *       Iterator begin, Iterator end) const
3131  *   {
3132  *     Iterator i = begin;
3133  *     while (i != end)
3134  *       if (c_ == *i++)
3135  *         return std::make_pair(i, true);
3136  *     return std::make_pair(i, false);
3137  *   }
3138  *
3139  * private:
3140  *   char c_;
3141  * };
3142  *
3143  * namespace asio {
3144  *   template <> struct is_match_condition<match_char>
3145  *     : public boost::true_type {};
3146  * } // namespace asio
3147  * ...
3148  * void handler(const boost::system::error_code& e, std::size_t size);
3149  * ...
3150  * std::string data;
3151  * boost::asio::async_read_until(s, data, match_char('a'), handler);
3152  * @endcode
3153  *
3154  * @par Per-Operation Cancellation
3155  * This asynchronous operation supports cancellation for the following
3156  * boost::asio::cancellation_type values:
3157  *
3158  * @li @c cancellation_type::terminal
3159  *
3160  * @li @c cancellation_type::partial
3161  *
3162  * if they are also supported by the @c AsyncReadStream type's
3163  * @c async_read_some operation.
3164  */
3165 template <typename AsyncReadStream,
3166     typename DynamicBuffer_v2, typename MatchCondition,
3167     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
3168       std::size_t)) ReadToken = default_completion_token_t<
3169         typename AsyncReadStream::executor_type>>
3170 inline auto async_read_until(AsyncReadStream& s,
3171     DynamicBuffer_v2 buffers, MatchCondition match_condition,
3172     ReadToken&& token = default_completion_token_t<
3173       typename AsyncReadStream::executor_type>(),
3174     constraint_t<
3175       is_match_condition<MatchCondition>::value
3176     > = 0,
3177     constraint_t<
3178       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
3179     > = 0)
3180   -> decltype(
3181     async_initiate<ReadToken,
3182       void (boost::system::error_code, std::size_t)>(
3183         declval<detail::initiate_async_read_until_match_v2<AsyncReadStream>>(),
3184         token, static_cast<DynamicBuffer_v2&&>(buffers), match_condition))
3185 {
3186   return async_initiate<ReadToken,
3187     void (boost::system::error_code, std::size_t)>(
3188       detail::initiate_async_read_until_match_v2<AsyncReadStream>(s),
3189       token, static_cast<DynamicBuffer_v2&&>(buffers),
3190       match_condition);
3191 }
3192 
3193 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
3194 
3195 /*@}*/
3196 
3197 } // namespace asio
3198 } // namespace boost
3199 
3200 #include <boost/asio/detail/pop_options.hpp>
3201 
3202 #include <boost/asio/impl/read_until.hpp>
3203 
3204 #endif // BOOST_ASIO_READ_UNTIL_HPP