Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:45

0001 //
0002 // read_until.hpp
0003 // ~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 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::post().
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 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 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1676 /// until it contains a specified delimiter.
1677 /**
1678  * This function is used to asynchronously read data into the specified dynamic
1679  * buffer sequence until the dynamic buffer sequence's get area contains the
1680  * specified delimiter. It is an initiating function for an @ref
1681  * asynchronous_operation, and always returns immediately. The asynchronous
1682  * operation will continue until one of the following conditions is true:
1683  *
1684  * @li The get area of the dynamic buffer sequence contains the specified
1685  * delimiter.
1686  *
1687  * @li An error occurred.
1688  *
1689  * This operation is implemented in terms of zero or more calls to the stream's
1690  * async_read_some function, and is known as a <em>composed operation</em>. If
1691  * the dynamic buffer sequence's get area already contains the delimiter, this
1692  * asynchronous operation completes immediately. The program must ensure that
1693  * the stream performs no other read operations (such as async_read,
1694  * async_read_until, the stream's async_read_some function, or any other
1695  * composed operations that perform reads) until this operation completes.
1696  *
1697  * @param s The stream from which the data is to be read. The type must support
1698  * the AsyncReadStream concept.
1699  *
1700  * @param buffers The dynamic buffer sequence into which the data will be read.
1701  * Although the buffers object may be copied as necessary, ownership of the
1702  * underlying memory blocks is retained by the caller, which must guarantee
1703  * that they remain valid until the completion handler is called.
1704  *
1705  * @param delim The delimiter string.
1706  *
1707  * @param token The @ref completion_token that will be used to produce a
1708  * completion handler, which will be called when the read completes.
1709  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1710  * @ref yield_context, or a function object with the correct completion
1711  * signature. The function signature of the completion handler must be:
1712  * @code void handler(
1713  *   // Result of operation.
1714  *   const boost::system::error_code& error,
1715  *
1716  *   // The number of bytes in the dynamic buffer sequence's
1717  *   // get area up to and including the delimiter.
1718  *   std::size_t bytes_transferred
1719  * ); @endcode
1720  * Regardless of whether the asynchronous operation completes immediately or
1721  * not, the completion handler will not be invoked from within this function.
1722  * On immediate completion, invocation of the handler will be performed in a
1723  * manner equivalent to using boost::asio::post().
1724  *
1725  * @par Completion Signature
1726  * @code void(boost::system::error_code, std::size_t) @endcode
1727  *
1728  * @note After a successful async_read_until operation, the dynamic buffer
1729  * sequence may contain additional data beyond the delimiter. An application
1730  * will typically leave that data in the dynamic buffer sequence for a
1731  * subsequent async_read_until operation to examine.
1732  *
1733  * @par Example
1734  * To asynchronously read data into a @c std::string until a CR-LF sequence is
1735  * encountered:
1736  * @code std::string data;
1737  * ...
1738  * void handler(const boost::system::error_code& e, std::size_t size)
1739  * {
1740  *   if (!e)
1741  *   {
1742  *     std::string line = data.substr(0, n);
1743  *     data.erase(0, n);
1744  *     ...
1745  *   }
1746  * }
1747  * ...
1748  * boost::asio::async_read_until(s, data, "\r\n", handler); @endcode
1749  * After the @c async_read_until operation completes successfully, the string
1750  * @c data contains the delimiter:
1751  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1752  * The call to @c substr then extracts the data up to and including the
1753  * delimiter, so that the string @c line contains:
1754  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1755  * After the call to @c erase, the remaining data is left in the string @c data
1756  * as follows:
1757  * @code { 'd', 'e', ... } @endcode
1758  * This data may be the start of a new line, to be extracted by a subsequent
1759  * @c async_read_until operation.
1760  *
1761  * @par Per-Operation Cancellation
1762  * This asynchronous operation supports cancellation for the following
1763  * boost::asio::cancellation_type values:
1764  *
1765  * @li @c cancellation_type::terminal
1766  *
1767  * @li @c cancellation_type::partial
1768  *
1769  * if they are also supported by the @c AsyncReadStream type's
1770  * @c async_read_some operation.
1771  */
1772 template <typename AsyncReadStream, typename DynamicBuffer_v1,
1773     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1774       std::size_t)) ReadToken = default_completion_token_t<
1775         typename AsyncReadStream::executor_type>>
1776 auto async_read_until(AsyncReadStream& s,
1777     DynamicBuffer_v1&& buffers,
1778     BOOST_ASIO_STRING_VIEW_PARAM delim,
1779     ReadToken&& token = default_completion_token_t<
1780       typename AsyncReadStream::executor_type>(),
1781     constraint_t<
1782       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
1783     > = 0,
1784     constraint_t<
1785       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
1786     > = 0)
1787   -> decltype(
1788     async_initiate<ReadToken,
1789       void (boost::system::error_code, std::size_t)>(
1790         declval<detail::initiate_async_read_until_delim_string_v1<
1791           AsyncReadStream>>(),
1792         token, static_cast<DynamicBuffer_v1&&>(buffers),
1793         static_cast<std::string>(delim)));
1794 
1795 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
1796 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
1797   || defined(GENERATING_DOCUMENTATION)
1798 
1799 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1800 /// until some part of its data matches a regular expression.
1801 /**
1802  * This function is used to asynchronously read data into the specified dynamic
1803  * buffer sequence until the dynamic buffer sequence's get area contains some
1804  * data that matches a regular expression. It is an initiating function for an
1805  * @ref asynchronous_operation, and always returns immediately. The
1806  * asynchronous operation will continue until one of the following conditions
1807  * is true:
1808  *
1809  * @li A substring of the dynamic buffer sequence's get area matches the regular
1810  * expression.
1811  *
1812  * @li An error occurred.
1813  *
1814  * This operation is implemented in terms of zero or more calls to the stream's
1815  * async_read_some function, and is known as a <em>composed operation</em>. If
1816  * the dynamic buffer sequence's get area already contains data that matches
1817  * the regular expression, this asynchronous operation completes immediately.
1818  * The program must ensure that the stream performs no other read operations
1819  * (such as async_read, async_read_until, the stream's async_read_some
1820  * function, or any other composed operations that perform reads) until this
1821  * operation completes.
1822  *
1823  * @param s The stream from which the data is to be read. The type must support
1824  * the AsyncReadStream concept.
1825  *
1826  * @param buffers The dynamic buffer sequence into which the data will be read.
1827  * Although the buffers object may be copied as necessary, ownership of the
1828  * underlying memory blocks is retained by the caller, which must guarantee
1829  * that they remain valid until the completion handler is called.
1830  *
1831  * @param expr The regular expression.
1832  *
1833  * @param token The @ref completion_token that will be used to produce a
1834  * completion handler, which will be called when the read completes.
1835  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1836  * @ref yield_context, or a function object with the correct completion
1837  * signature. The function signature of the completion handler must be:
1838  * @code void handler(
1839  *   // Result of operation.
1840  *   const boost::system::error_code& error,
1841  *
1842  *   // The number of bytes in the dynamic buffer
1843  *   // sequence's get area up to and including the
1844  *   // substring that matches the regular expression.
1845  *   // 0 if an error occurred.
1846  *   std::size_t bytes_transferred
1847  * ); @endcode
1848  * Regardless of whether the asynchronous operation completes immediately or
1849  * not, the completion handler will not be invoked from within this function.
1850  * On immediate completion, invocation of the handler will be performed in a
1851  * manner equivalent to using boost::asio::post().
1852  *
1853  * @par Completion Signature
1854  * @code void(boost::system::error_code, std::size_t) @endcode
1855  *
1856  * @note After a successful async_read_until operation, the dynamic buffer
1857  * sequence may contain additional data beyond that which matched the regular
1858  * expression. An application will typically leave that data in the dynamic
1859  * buffer sequence for a subsequent async_read_until operation to examine.
1860  *
1861  * @par Example
1862  * To asynchronously read data into a @c std::string until a CR-LF sequence is
1863  * encountered:
1864  * @code std::string data;
1865  * ...
1866  * void handler(const boost::system::error_code& e, std::size_t size)
1867  * {
1868  *   if (!e)
1869  *   {
1870  *     std::string line = data.substr(0, n);
1871  *     data.erase(0, n);
1872  *     ...
1873  *   }
1874  * }
1875  * ...
1876  * boost::asio::async_read_until(s, data,
1877  *     boost::regex("\r\n"), handler); @endcode
1878  * After the @c async_read_until operation completes successfully, the string
1879  * @c data contains the data which matched the regular expression:
1880  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
1881  * The call to @c substr then extracts the data up to and including the match,
1882  * so that the string @c line contains:
1883  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
1884  * After the call to @c erase, the remaining data is left in the string @c data
1885  * as follows:
1886  * @code { 'd', 'e', ... } @endcode
1887  * This data may be the start of a new line, to be extracted by a subsequent
1888  * @c async_read_until operation.
1889  *
1890  * @par Per-Operation Cancellation
1891  * This asynchronous operation supports cancellation for the following
1892  * boost::asio::cancellation_type values:
1893  *
1894  * @li @c cancellation_type::terminal
1895  *
1896  * @li @c cancellation_type::partial
1897  *
1898  * if they are also supported by the @c AsyncReadStream type's
1899  * @c async_read_some operation.
1900  */
1901 template <typename AsyncReadStream, typename DynamicBuffer_v1, typename Traits,
1902     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1903       std::size_t)) ReadToken = default_completion_token_t<
1904         typename AsyncReadStream::executor_type>>
1905 auto async_read_until(AsyncReadStream& s, DynamicBuffer_v1&& buffers,
1906     const boost::basic_regex<char, Traits>& expr,
1907     ReadToken&& token = default_completion_token_t<
1908       typename AsyncReadStream::executor_type>(),
1909     constraint_t<
1910       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
1911     > = 0,
1912     constraint_t<
1913       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
1914     > = 0)
1915   -> decltype(
1916     async_initiate<ReadToken,
1917       void (boost::system::error_code, std::size_t)>(
1918         declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),
1919         token, static_cast<DynamicBuffer_v1&&>(buffers), expr));
1920 
1921 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
1922        // || defined(GENERATING_DOCUMENTATION)
1923 
1924 /// Start an asynchronous operation to read data into a dynamic buffer sequence
1925 /// until a function object indicates a match.
1926 /**
1927  * This function is used to asynchronously read data into the specified dynamic
1928  * buffer sequence until a user-defined match condition function object, when
1929  * applied to the data contained in the dynamic buffer sequence, indicates a
1930  * successful match. It is an initiating function for an @ref
1931  * asynchronous_operation, and always returns immediately. The asynchronous
1932  * operation will continue until one of the following conditions is true:
1933  *
1934  * @li The match condition function object returns a std::pair where the second
1935  * element evaluates to true.
1936  *
1937  * @li An error occurred.
1938  *
1939  * This operation is implemented in terms of zero or more calls to the stream's
1940  * async_read_some function, and is known as a <em>composed operation</em>. If
1941  * the match condition function object already indicates a match, this
1942  * asynchronous operation completes immediately. The program must ensure that
1943  * the stream performs no other read operations (such as async_read,
1944  * async_read_until, the stream's async_read_some function, or any other
1945  * composed operations that perform reads) until this operation completes.
1946  *
1947  * @param s The stream from which the data is to be read. The type must support
1948  * the AsyncReadStream concept.
1949  *
1950  * @param buffers The dynamic buffer sequence into which the data will be read.
1951  * Although the buffers object may be copied as necessary, ownership of the
1952  * underlying memory blocks is retained by the caller, which must guarantee
1953  * that they remain valid until the completion handler is called.
1954  *
1955  * @param match_condition The function object to be called to determine whether
1956  * a match exists. The signature of the function object must be:
1957  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
1958  * @endcode
1959  * where @c iterator represents the type:
1960  * @code buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
1961  * @endcode
1962  * The iterator parameters @c begin and @c end define the range of bytes to be
1963  * scanned to determine whether there is a match. The @c first member of the
1964  * return value is an iterator marking one-past-the-end of the bytes that have
1965  * been consumed by the match function. This iterator is used to calculate the
1966  * @c begin parameter for any subsequent invocation of the match condition. The
1967  * @c second member of the return value is true if a match has been found, false
1968  * otherwise.
1969  *
1970  * @param token The @ref completion_token that will be used to produce a
1971  * completion handler, which will be called when the read completes.
1972  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1973  * @ref yield_context, or a function object with the correct completion
1974  * signature. The function signature of the completion handler must be:
1975  * @code void handler(
1976  *   // Result of operation.
1977  *   const boost::system::error_code& error,
1978  *
1979  *   // The number of bytes in the dynamic buffer sequence's
1980  *   // get area that have been fully consumed by the match
1981  *   // function. O if an error occurred.
1982  *   std::size_t bytes_transferred
1983  * ); @endcode
1984  * Regardless of whether the asynchronous operation completes immediately or
1985  * not, the completion handler will not be invoked from within this function.
1986  * On immediate completion, invocation of the handler will be performed in a
1987  * manner equivalent to using boost::asio::post().
1988  *
1989  * @note After a successful async_read_until operation, the dynamic buffer
1990  * sequence may contain additional data beyond that which matched the function
1991  * object. An application will typically leave that data in the dynamic buffer
1992  * sequence for a subsequent async_read_until operation to examine.
1993  *
1994  * @par Completion Signature
1995  * @code void(boost::system::error_code, std::size_t) @endcode
1996  *
1997  * @note The default implementation of the @c is_match_condition type trait
1998  * evaluates to true for function pointers and function objects with a
1999  * @c result_type typedef. It must be specialised for other user-defined
2000  * function objects.
2001  *
2002  * @par Examples
2003  * To asynchronously read data into a @c std::string until whitespace is
2004  * encountered:
2005  * @code typedef boost::asio::buffers_iterator<
2006  *     boost::asio::const_buffers_1> iterator;
2007  *
2008  * std::pair<iterator, bool>
2009  * match_whitespace(iterator begin, iterator end)
2010  * {
2011  *   iterator i = begin;
2012  *   while (i != end)
2013  *     if (std::isspace(*i++))
2014  *       return std::make_pair(i, true);
2015  *   return std::make_pair(i, false);
2016  * }
2017  * ...
2018  * void handler(const boost::system::error_code& e, std::size_t size);
2019  * ...
2020  * std::string data;
2021  * boost::asio::async_read_until(s, data, match_whitespace, handler);
2022  * @endcode
2023  *
2024  * To asynchronously read data into a @c std::string until a matching character
2025  * is found:
2026  * @code class match_char
2027  * {
2028  * public:
2029  *   explicit match_char(char c) : c_(c) {}
2030  *
2031  *   template <typename Iterator>
2032  *   std::pair<Iterator, bool> operator()(
2033  *       Iterator begin, Iterator end) const
2034  *   {
2035  *     Iterator i = begin;
2036  *     while (i != end)
2037  *       if (c_ == *i++)
2038  *         return std::make_pair(i, true);
2039  *     return std::make_pair(i, false);
2040  *   }
2041  *
2042  * private:
2043  *   char c_;
2044  * };
2045  *
2046  * namespace asio {
2047  *   template <> struct is_match_condition<match_char>
2048  *     : public boost::true_type {};
2049  * } // namespace asio
2050  * ...
2051  * void handler(const boost::system::error_code& e, std::size_t size);
2052  * ...
2053  * std::string data;
2054  * boost::asio::async_read_until(s, data, match_char('a'), handler);
2055  * @endcode
2056  *
2057  * @par Per-Operation Cancellation
2058  * This asynchronous operation supports cancellation for the following
2059  * boost::asio::cancellation_type values:
2060  *
2061  * @li @c cancellation_type::terminal
2062  *
2063  * @li @c cancellation_type::partial
2064  *
2065  * if they are also supported by the @c AsyncReadStream type's
2066  * @c async_read_some operation.
2067  */
2068 template <typename AsyncReadStream,
2069     typename DynamicBuffer_v1, typename MatchCondition,
2070     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2071       std::size_t)) ReadToken = default_completion_token_t<
2072         typename AsyncReadStream::executor_type>>
2073 auto async_read_until(AsyncReadStream& s,
2074     DynamicBuffer_v1&& buffers, MatchCondition match_condition,
2075     ReadToken&& token = default_completion_token_t<
2076       typename AsyncReadStream::executor_type>(),
2077     constraint_t<
2078       is_match_condition<MatchCondition>::value
2079     > = 0,
2080     constraint_t<
2081       is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
2082     > = 0,
2083     constraint_t<
2084       !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
2085     > = 0)
2086   -> decltype(
2087     async_initiate<ReadToken,
2088       void (boost::system::error_code, std::size_t)>(
2089         declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),
2090         token, static_cast<DynamicBuffer_v1&&>(buffers),
2091         match_condition));
2092 
2093 #if !defined(BOOST_ASIO_NO_IOSTREAM)
2094 
2095 /// Start an asynchronous operation to read data into a streambuf until it
2096 /// contains a specified delimiter.
2097 /**
2098  * This function is used to asynchronously read data into the specified
2099  * streambuf until the streambuf's get area contains the specified delimiter.
2100  * It is an initiating function for an @ref asynchronous_operation, and always
2101  * returns immediately. The asynchronous operation will continue until one of
2102  * the following conditions is true:
2103  *
2104  * @li The get area of the streambuf contains the specified delimiter.
2105  *
2106  * @li An error occurred.
2107  *
2108  * This operation is implemented in terms of zero or more calls to the stream's
2109  * async_read_some function, and is known as a <em>composed operation</em>. If
2110  * the streambuf's get area already contains the delimiter, this asynchronous
2111  * operation completes immediately. The program must ensure that the stream
2112  * performs no other read operations (such as async_read, async_read_until, the
2113  * stream's async_read_some function, or any other composed operations that
2114  * perform reads) until this operation completes.
2115  *
2116  * @param s The stream from which the data is to be read. The type must support
2117  * the AsyncReadStream concept.
2118  *
2119  * @param b A streambuf object into which the data will be read. Ownership of
2120  * the streambuf is retained by the caller, which must guarantee that it remains
2121  * valid until the completion handler is called.
2122  *
2123  * @param delim The delimiter character.
2124  *
2125  * @param token The @ref completion_token that will be used to produce a
2126  * completion handler, which will be called when the read completes.
2127  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2128  * @ref yield_context, or a function object with the correct completion
2129  * signature. The function signature of the completion handler must be:
2130  * @code void handler(
2131  *   // Result of operation.
2132  *   const boost::system::error_code& error,
2133  *
2134  *   // The number of bytes in the streambuf's get
2135  *   // area up to and including the delimiter.
2136  *   // 0 if an error occurred.
2137  *   std::size_t bytes_transferred
2138  * ); @endcode
2139  * Regardless of whether the asynchronous operation completes immediately or
2140  * not, the completion handler will not be invoked from within this function.
2141  * On immediate completion, invocation of the handler will be performed in a
2142  * manner equivalent to using boost::asio::post().
2143  *
2144  * @par Completion Signature
2145  * @code void(boost::system::error_code, std::size_t) @endcode
2146  *
2147  * @note After a successful async_read_until operation, the streambuf may
2148  * contain additional data beyond the delimiter. An application will typically
2149  * leave that data in the streambuf for a subsequent async_read_until operation
2150  * to examine.
2151  *
2152  * @par Example
2153  * To asynchronously read data into a streambuf until a newline is encountered:
2154  * @code boost::asio::streambuf b;
2155  * ...
2156  * void handler(const boost::system::error_code& e, std::size_t size)
2157  * {
2158  *   if (!e)
2159  *   {
2160  *     std::istream is(&b);
2161  *     std::string line;
2162  *     std::getline(is, line);
2163  *     ...
2164  *   }
2165  * }
2166  * ...
2167  * boost::asio::async_read_until(s, b, '\n', handler); @endcode
2168  * After the @c async_read_until operation completes successfully, the buffer
2169  * @c b contains the delimiter:
2170  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
2171  * The call to @c std::getline then extracts the data up to and including the
2172  * newline (which is discarded), so that the string @c line contains:
2173  * @code { 'a', 'b', ..., 'c' } @endcode
2174  * The remaining data is left in the buffer @c b as follows:
2175  * @code { 'd', 'e', ... } @endcode
2176  * This data may be the start of a new line, to be extracted by a subsequent
2177  * @c async_read_until operation.
2178  *
2179  * @par Per-Operation Cancellation
2180  * This asynchronous operation supports cancellation for the following
2181  * boost::asio::cancellation_type values:
2182  *
2183  * @li @c cancellation_type::terminal
2184  *
2185  * @li @c cancellation_type::partial
2186  *
2187  * if they are also supported by the @c AsyncReadStream type's
2188  * @c async_read_some operation.
2189  */
2190 template <typename AsyncReadStream, typename Allocator,
2191     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2192       std::size_t)) ReadToken = default_completion_token_t<
2193         typename AsyncReadStream::executor_type>>
2194 auto async_read_until(AsyncReadStream& s,
2195     boost::asio::basic_streambuf<Allocator>& b, char delim,
2196     ReadToken&& token = default_completion_token_t<
2197       typename AsyncReadStream::executor_type>())
2198   -> decltype(
2199     async_initiate<ReadToken,
2200       void (boost::system::error_code, std::size_t)>(
2201         declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),
2202         token, basic_streambuf_ref<Allocator>(b), delim));
2203 
2204 /// Start an asynchronous operation to read data into a streambuf until it
2205 /// contains a specified delimiter.
2206 /**
2207  * This function is used to asynchronously read data into the specified
2208  * streambuf until the streambuf's get area contains the specified delimiter.
2209  * It is an initiating function for an @ref asynchronous_operation, and always
2210  * returns immediately. The asynchronous operation will continue until one of
2211  * the following conditions is true:
2212  *
2213  * @li The get area of the streambuf contains the specified delimiter.
2214  *
2215  * @li An error occurred.
2216  *
2217  * This operation is implemented in terms of zero or more calls to the stream's
2218  * async_read_some function, and is known as a <em>composed operation</em>. If
2219  * the streambuf's get area already contains the delimiter, this asynchronous
2220  * operation completes immediately. The program must ensure that the stream
2221  * performs no other read operations (such as async_read, async_read_until, the
2222  * stream's async_read_some function, or any other composed operations that
2223  * perform reads) until this operation completes.
2224  *
2225  * @param s The stream from which the data is to be read. The type must support
2226  * the AsyncReadStream concept.
2227  *
2228  * @param b A streambuf object into which the data will be read. Ownership of
2229  * the streambuf is retained by the caller, which must guarantee that it remains
2230  * valid until the completion handler is called.
2231  *
2232  * @param delim The delimiter string.
2233  *
2234  * @param token The @ref completion_token that will be used to produce a
2235  * completion handler, which will be called when the read completes.
2236  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2237  * @ref yield_context, or a function object with the correct completion
2238  * signature. The function signature of the completion handler must be:
2239  * @code void handler(
2240  *   // Result of operation.
2241  *   const boost::system::error_code& error,
2242  *
2243  *   // The number of bytes in the streambuf's get
2244  *   // area up to and including the delimiter.
2245  *   // 0 if an error occurred.
2246  *   std::size_t bytes_transferred
2247  * ); @endcode
2248  * Regardless of whether the asynchronous operation completes immediately or
2249  * not, the completion handler will not be invoked from within this function.
2250  * On immediate completion, invocation of the handler will be performed in a
2251  * manner equivalent to using boost::asio::post().
2252  *
2253  * @par Completion Signature
2254  * @code void(boost::system::error_code, std::size_t) @endcode
2255  *
2256  * @note After a successful async_read_until operation, the streambuf may
2257  * contain additional data beyond the delimiter. An application will typically
2258  * leave that data in the streambuf for a subsequent async_read_until operation
2259  * to examine.
2260  *
2261  * @par Example
2262  * To asynchronously read data into a streambuf until a newline is encountered:
2263  * @code boost::asio::streambuf b;
2264  * ...
2265  * void handler(const boost::system::error_code& e, std::size_t size)
2266  * {
2267  *   if (!e)
2268  *   {
2269  *     std::istream is(&b);
2270  *     std::string line;
2271  *     std::getline(is, line);
2272  *     ...
2273  *   }
2274  * }
2275  * ...
2276  * boost::asio::async_read_until(s, b, "\r\n", handler); @endcode
2277  * After the @c async_read_until operation completes successfully, the buffer
2278  * @c b contains the delimiter:
2279  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2280  * The call to @c std::getline then extracts the data up to and including the
2281  * newline (which is discarded), so that the string @c line contains:
2282  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
2283  * The remaining data is left in the buffer @c b as follows:
2284  * @code { 'd', 'e', ... } @endcode
2285  * This data may be the start of a new line, to be extracted by a subsequent
2286  * @c async_read_until operation.
2287  *
2288  * @par Per-Operation Cancellation
2289  * This asynchronous operation supports cancellation for the following
2290  * boost::asio::cancellation_type values:
2291  *
2292  * @li @c cancellation_type::terminal
2293  *
2294  * @li @c cancellation_type::partial
2295  *
2296  * if they are also supported by the @c AsyncReadStream type's
2297  * @c async_read_some operation.
2298  */
2299 template <typename AsyncReadStream, typename Allocator,
2300     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2301       std::size_t)) ReadToken = default_completion_token_t<
2302         typename AsyncReadStream::executor_type>>
2303 auto async_read_until(AsyncReadStream& s,
2304     boost::asio::basic_streambuf<Allocator>& b,
2305     BOOST_ASIO_STRING_VIEW_PARAM delim,
2306     ReadToken&& token = default_completion_token_t<
2307       typename AsyncReadStream::executor_type>())
2308   -> decltype(
2309     async_initiate<ReadToken,
2310       void (boost::system::error_code, std::size_t)>(
2311         declval<detail::initiate_async_read_until_delim_string_v1<
2312           AsyncReadStream>>(),
2313         token, basic_streambuf_ref<Allocator>(b),
2314         static_cast<std::string>(delim)));
2315 
2316 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
2317   || defined(GENERATING_DOCUMENTATION)
2318 
2319 /// Start an asynchronous operation to read data into a streambuf until some
2320 /// part of its data matches a regular expression.
2321 /**
2322  * This function is used to asynchronously read data into the specified
2323  * streambuf until the streambuf's get area contains some data that matches a
2324  * regular expression. It is an initiating function for an @ref
2325  * asynchronous_operation, and always returns immediately. The asynchronous
2326  * operation will continue until one of the following conditions is true:
2327  *
2328  * @li A substring of the streambuf's get area matches the regular expression.
2329  *
2330  * @li An error occurred.
2331  *
2332  * This operation is implemented in terms of zero or more calls to the stream's
2333  * async_read_some function, and is known as a <em>composed operation</em>. If
2334  * the streambuf's get area already contains data that matches the regular
2335  * expression, this asynchronous operation completes immediately. The program
2336  * must ensure that the stream performs no other read operations (such as
2337  * async_read, async_read_until, the stream's async_read_some function, or any
2338  * other composed operations that perform reads) until this operation
2339  * completes.
2340  *
2341  * @param s The stream from which the data is to be read. The type must support
2342  * the AsyncReadStream concept.
2343  *
2344  * @param b A streambuf object into which the data will be read. Ownership of
2345  * the streambuf is retained by the caller, which must guarantee that it remains
2346  * valid until the completion handler is called.
2347  *
2348  * @param expr The regular expression.
2349  *
2350  * @param token The @ref completion_token that will be used to produce a
2351  * completion handler, which will be called when the read completes.
2352  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2353  * @ref yield_context, or a function object with the correct completion
2354  * signature. The function signature of the completion handler must be:
2355  * @code void handler(
2356  *   // Result of operation.
2357  *   const boost::system::error_code& error,
2358  *
2359  *   // The number of bytes in the streambuf's get
2360  *   // area up to and including the substring
2361  *   // that matches the regular. expression.
2362  *   // 0 if an error occurred.
2363  *   std::size_t bytes_transferred
2364  * ); @endcode
2365  * Regardless of whether the asynchronous operation completes immediately or
2366  * not, the completion handler will not be invoked from within this function.
2367  * On immediate completion, invocation of the handler will be performed in a
2368  * manner equivalent to using boost::asio::post().
2369  *
2370  * @par Completion Signature
2371  * @code void(boost::system::error_code, std::size_t) @endcode
2372  *
2373  * @note After a successful async_read_until operation, the streambuf may
2374  * contain additional data beyond that which matched the regular expression. An
2375  * application will typically leave that data in the streambuf for a subsequent
2376  * async_read_until operation to examine.
2377  *
2378  * @par Example
2379  * To asynchronously read data into a streambuf until a CR-LF sequence is
2380  * encountered:
2381  * @code boost::asio::streambuf b;
2382  * ...
2383  * void handler(const boost::system::error_code& e, std::size_t size)
2384  * {
2385  *   if (!e)
2386  *   {
2387  *     std::istream is(&b);
2388  *     std::string line;
2389  *     std::getline(is, line);
2390  *     ...
2391  *   }
2392  * }
2393  * ...
2394  * boost::asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode
2395  * After the @c async_read_until operation completes successfully, the buffer
2396  * @c b contains the data which matched the regular expression:
2397  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2398  * The call to @c std::getline then extracts the data up to and including the
2399  * newline (which is discarded), so that the string @c line contains:
2400  * @code { 'a', 'b', ..., 'c', '\r' } @endcode
2401  * The remaining data is left in the buffer @c b as follows:
2402  * @code { 'd', 'e', ... } @endcode
2403  * This data may be the start of a new line, to be extracted by a subsequent
2404  * @c async_read_until operation.
2405  *
2406  * @par Per-Operation Cancellation
2407  * This asynchronous operation supports cancellation for the following
2408  * boost::asio::cancellation_type values:
2409  *
2410  * @li @c cancellation_type::terminal
2411  *
2412  * @li @c cancellation_type::partial
2413  *
2414  * if they are also supported by the @c AsyncReadStream type's
2415  * @c async_read_some operation.
2416  */
2417 template <typename AsyncReadStream, typename Allocator, typename Traits,
2418     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2419       std::size_t)) ReadToken = default_completion_token_t<
2420         typename AsyncReadStream::executor_type>>
2421 auto async_read_until(AsyncReadStream& s,
2422     boost::asio::basic_streambuf<Allocator>& b,
2423     const boost::basic_regex<char, Traits>& expr,
2424     ReadToken&& token = default_completion_token_t<
2425       typename AsyncReadStream::executor_type>())
2426   -> decltype(
2427     async_initiate<ReadToken,
2428       void (boost::system::error_code, std::size_t)>(
2429         declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),
2430         token, basic_streambuf_ref<Allocator>(b), expr));
2431 
2432 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
2433        // || defined(GENERATING_DOCUMENTATION)
2434 
2435 /// Start an asynchronous operation to read data into a streambuf until a
2436 /// function object indicates a match.
2437 /**
2438  * This function is used to asynchronously read data into the specified
2439  * streambuf until a user-defined match condition function object, when applied
2440  * to the data contained in the streambuf, indicates a successful match. It is
2441  * an initiating function for an @ref asynchronous_operation, and always
2442  * returns immediately. The asynchronous operation will continue until one of
2443  * the following conditions is true:
2444  *
2445  * @li The match condition function object returns a std::pair where the second
2446  * element evaluates to true.
2447  *
2448  * @li An error occurred.
2449  *
2450  * This operation is implemented in terms of zero or more calls to the stream's
2451  * async_read_some function, and is known as a <em>composed operation</em>. If
2452  * the match condition function object already indicates a match, this
2453  * asynchronous operation completes immediately. The program must ensure that
2454  * the stream performs no other read operations (such as async_read,
2455  * async_read_until, the stream's async_read_some function, or any other
2456  * composed operations that perform reads) until this operation completes.
2457  *
2458  * @param s The stream from which the data is to be read. The type must support
2459  * the AsyncReadStream concept.
2460  *
2461  * @param b A streambuf object into which the data will be read.
2462  *
2463  * @param match_condition The function object to be called to determine whether
2464  * a match exists. The signature of the function object must be:
2465  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
2466  * @endcode
2467  * where @c iterator represents the type:
2468  * @code buffers_iterator<basic_streambuf<Allocator>::const_buffers_type>
2469  * @endcode
2470  * The iterator parameters @c begin and @c end define the range of bytes to be
2471  * scanned to determine whether there is a match. The @c first member of the
2472  * return value is an iterator marking one-past-the-end of the bytes that have
2473  * been consumed by the match function. This iterator is used to calculate the
2474  * @c begin parameter for any subsequent invocation of the match condition. The
2475  * @c second member of the return value is true if a match has been found, false
2476  * otherwise.
2477  *
2478  * @param token The @ref completion_token that will be used to produce a
2479  * completion handler, which will be called when the read completes.
2480  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2481  * @ref yield_context, or a function object with the correct completion
2482  * signature. The function signature of the completion handler must be:
2483  * @code void handler(
2484  *   // Result of operation.
2485  *   const boost::system::error_code& error,
2486  *
2487  *   // The number of bytes in the streambuf's get
2488  *   // area that have been fully consumed by the
2489  *   // match function. O if an error occurred.
2490  *   std::size_t bytes_transferred
2491  * ); @endcode
2492  * Regardless of whether the asynchronous operation completes immediately or
2493  * not, the completion handler will not be invoked from within this function.
2494  * On immediate completion, invocation of the handler will be performed in a
2495  * manner equivalent to using boost::asio::post().
2496  *
2497  * @note After a successful async_read_until operation, the streambuf may
2498  * contain additional data beyond that which matched the function object. An
2499  * application will typically leave that data in the streambuf for a subsequent
2500  * async_read_until operation to examine.
2501  *
2502  * @par Completion Signature
2503  * @code void(boost::system::error_code, std::size_t) @endcode
2504  *
2505  * @note The default implementation of the @c is_match_condition type trait
2506  * evaluates to true for function pointers and function objects with a
2507  * @c result_type typedef. It must be specialised for other user-defined
2508  * function objects.
2509  *
2510  * @par Examples
2511  * To asynchronously read data into a streambuf until whitespace is encountered:
2512  * @code typedef boost::asio::buffers_iterator<
2513  *     boost::asio::streambuf::const_buffers_type> iterator;
2514  *
2515  * std::pair<iterator, bool>
2516  * match_whitespace(iterator begin, iterator end)
2517  * {
2518  *   iterator i = begin;
2519  *   while (i != end)
2520  *     if (std::isspace(*i++))
2521  *       return std::make_pair(i, true);
2522  *   return std::make_pair(i, false);
2523  * }
2524  * ...
2525  * void handler(const boost::system::error_code& e, std::size_t size);
2526  * ...
2527  * boost::asio::streambuf b;
2528  * boost::asio::async_read_until(s, b, match_whitespace, handler);
2529  * @endcode
2530  *
2531  * To asynchronously read data into a streambuf until a matching character is
2532  * found:
2533  * @code class match_char
2534  * {
2535  * public:
2536  *   explicit match_char(char c) : c_(c) {}
2537  *
2538  *   template <typename Iterator>
2539  *   std::pair<Iterator, bool> operator()(
2540  *       Iterator begin, Iterator end) const
2541  *   {
2542  *     Iterator i = begin;
2543  *     while (i != end)
2544  *       if (c_ == *i++)
2545  *         return std::make_pair(i, true);
2546  *     return std::make_pair(i, false);
2547  *   }
2548  *
2549  * private:
2550  *   char c_;
2551  * };
2552  *
2553  * namespace asio {
2554  *   template <> struct is_match_condition<match_char>
2555  *     : public boost::true_type {};
2556  * } // namespace asio
2557  * ...
2558  * void handler(const boost::system::error_code& e, std::size_t size);
2559  * ...
2560  * boost::asio::streambuf b;
2561  * boost::asio::async_read_until(s, b, match_char('a'), handler);
2562  * @endcode
2563  *
2564  * @par Per-Operation Cancellation
2565  * This asynchronous operation supports cancellation for the following
2566  * boost::asio::cancellation_type values:
2567  *
2568  * @li @c cancellation_type::terminal
2569  *
2570  * @li @c cancellation_type::partial
2571  *
2572  * if they are also supported by the @c AsyncReadStream type's
2573  * @c async_read_some operation.
2574  */
2575 template <typename AsyncReadStream, typename Allocator, typename MatchCondition,
2576     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2577       std::size_t)) ReadToken = default_completion_token_t<
2578         typename AsyncReadStream::executor_type>>
2579 auto async_read_until(AsyncReadStream& s,
2580     boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,
2581     ReadToken&& token = default_completion_token_t<
2582       typename AsyncReadStream::executor_type>(),
2583     constraint_t<is_match_condition<MatchCondition>::value> = 0)
2584   -> decltype(
2585     async_initiate<ReadToken,
2586       void (boost::system::error_code, std::size_t)>(
2587         declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),
2588         token, basic_streambuf_ref<Allocator>(b), match_condition));
2589 
2590 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
2591 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
2592 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2593 
2594 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2595 /// until it contains a specified delimiter.
2596 /**
2597  * This function is used to asynchronously read data into the specified dynamic
2598  * buffer sequence until the dynamic buffer sequence's get area contains the
2599  * specified delimiter. It is an initiating function for an @ref
2600  * asynchronous_operation, and always returns immediately. The asynchronous
2601  * operation will continue until one of the following conditions is true:
2602  *
2603  * @li The get area of the dynamic buffer sequence contains the specified
2604  * delimiter.
2605  *
2606  * @li An error occurred.
2607  *
2608  * This operation is implemented in terms of zero or more calls to the stream's
2609  * async_read_some function, and is known as a <em>composed operation</em>. If
2610  * the dynamic buffer sequence's get area already contains the delimiter, this
2611  * asynchronous operation completes immediately. The program must ensure that
2612  * the stream performs no other read operations (such as async_read,
2613  * async_read_until, the stream's async_read_some function, or any other
2614  * composed operations that perform reads) until this operation completes.
2615  *
2616  * @param s The stream from which the data is to be read. The type must support
2617  * the AsyncReadStream concept.
2618  *
2619  * @param buffers The dynamic buffer sequence into which the data will be read.
2620  * Although the buffers object may be copied as necessary, ownership of the
2621  * underlying memory blocks is retained by the caller, which must guarantee
2622  * that they remain valid until the completion handler is called.
2623  *
2624  * @param delim The delimiter character.
2625  *
2626  * @param token The @ref completion_token that will be used to produce a
2627  * completion handler, which will be called when the read completes.
2628  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2629  * @ref yield_context, or a function object with the correct completion
2630  * signature. The function signature of the completion handler must be:
2631  * @code void handler(
2632  *   // Result of operation.
2633  *   const boost::system::error_code& error,
2634  *
2635  *   // The number of bytes in the dynamic buffer sequence's
2636  *   // get area up to and including the delimiter.
2637  *   // 0 if an error occurred.
2638  *   std::size_t bytes_transferred
2639  * ); @endcode
2640  * Regardless of whether the asynchronous operation completes immediately or
2641  * not, the completion handler will not be invoked from within this function.
2642  * On immediate completion, invocation of the handler will be performed in a
2643  * manner equivalent to using boost::asio::post().
2644  *
2645  * @par Completion Signature
2646  * @code void(boost::system::error_code, std::size_t) @endcode
2647  *
2648  * @note After a successful async_read_until operation, the dynamic buffer
2649  * sequence may contain additional data beyond the delimiter. An application
2650  * will typically leave that data in the dynamic buffer sequence for a
2651  * subsequent async_read_until operation to examine.
2652  *
2653  * @par Example
2654  * To asynchronously read data into a @c std::string until a newline is
2655  * encountered:
2656  * @code std::string data;
2657  * ...
2658  * void handler(const boost::system::error_code& e, std::size_t size)
2659  * {
2660  *   if (!e)
2661  *   {
2662  *     std::string line = data.substr(0, n);
2663  *     data.erase(0, n);
2664  *     ...
2665  *   }
2666  * }
2667  * ...
2668  * boost::asio::async_read_until(s, data, '\n', handler); @endcode
2669  * After the @c async_read_until operation completes successfully, the buffer
2670  * @c data contains the delimiter:
2671  * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
2672  * The call to @c substr then extracts the data up to and including the
2673  * delimiter, so that the string @c line contains:
2674  * @code { 'a', 'b', ..., 'c', '\n' } @endcode
2675  * After the call to @c erase, the remaining data is left in the buffer @c data
2676  * as follows:
2677  * @code { 'd', 'e', ... } @endcode
2678  * This data may be the start of a new line, to be extracted by a subsequent
2679  * @c async_read_until operation.
2680  *
2681  * @par Per-Operation Cancellation
2682  * This asynchronous operation supports cancellation for the following
2683  * boost::asio::cancellation_type values:
2684  *
2685  * @li @c cancellation_type::terminal
2686  *
2687  * @li @c cancellation_type::partial
2688  *
2689  * if they are also supported by the @c AsyncReadStream type's
2690  * @c async_read_some operation.
2691  */
2692 template <typename AsyncReadStream, typename DynamicBuffer_v2,
2693     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2694       std::size_t)) ReadToken = default_completion_token_t<
2695         typename AsyncReadStream::executor_type>>
2696 auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim,
2697     ReadToken&& token = default_completion_token_t<
2698       typename AsyncReadStream::executor_type>(),
2699     constraint_t<
2700       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
2701     > = 0)
2702   -> decltype(
2703     async_initiate<ReadToken,
2704       void (boost::system::error_code, std::size_t)>(
2705         declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream>>(),
2706         token, static_cast<DynamicBuffer_v2&&>(buffers), delim));
2707 
2708 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2709 /// until it contains a specified delimiter.
2710 /**
2711  * This function is used to asynchronously read data into the specified dynamic
2712  * buffer sequence until the dynamic buffer sequence's get area contains the
2713  * specified delimiter. It is an initiating function for an @ref
2714  * asynchronous_operation, and always returns immediately. The asynchronous
2715  * operation will continue until one of the following conditions is true:
2716  *
2717  * @li The get area of the dynamic buffer sequence contains the specified
2718  * delimiter.
2719  *
2720  * @li An error occurred.
2721  *
2722  * This operation is implemented in terms of zero or more calls to the stream's
2723  * async_read_some function, and is known as a <em>composed operation</em>. If
2724  * the dynamic buffer sequence's get area already contains the delimiter, this
2725  * asynchronous operation completes immediately. The program must ensure that
2726  * the stream performs no other read operations (such as async_read,
2727  * async_read_until, the stream's async_read_some function, or any other
2728  * composed operations that perform reads) until this operation completes.
2729  *
2730  * @param s The stream from which the data is to be read. The type must support
2731  * the AsyncReadStream concept.
2732  *
2733  * @param buffers The dynamic buffer sequence into which the data will be read.
2734  * Although the buffers object may be copied as necessary, ownership of the
2735  * underlying memory blocks is retained by the caller, which must guarantee
2736  * that they remain valid until the completion handler is called.
2737  *
2738  * @param delim The delimiter string.
2739  *
2740  * @param token The @ref completion_token that will be used to produce a
2741  * completion handler, which will be called when the read completes.
2742  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2743  * @ref yield_context, or a function object with the correct completion
2744  * signature. The function signature of the completion handler must be:
2745  * @code void handler(
2746  *   // Result of operation.
2747  *   const boost::system::error_code& error,
2748  *
2749  *   // The number of bytes in the dynamic buffer sequence's
2750  *   // get area up to and including the delimiter.
2751  *   std::size_t bytes_transferred
2752  * ); @endcode
2753  * Regardless of whether the asynchronous operation completes immediately or
2754  * not, the completion handler will not be invoked from within this function.
2755  * On immediate completion, invocation of the handler will be performed in a
2756  * manner equivalent to using boost::asio::post().
2757  *
2758  * @par Completion Signature
2759  * @code void(boost::system::error_code, std::size_t) @endcode
2760  *
2761  * @note After a successful async_read_until operation, the dynamic buffer
2762  * sequence may contain additional data beyond the delimiter. An application
2763  * will typically leave that data in the dynamic buffer sequence for a
2764  * subsequent async_read_until operation to examine.
2765  *
2766  * @par Example
2767  * To asynchronously read data into a @c std::string until a CR-LF sequence is
2768  * encountered:
2769  * @code std::string data;
2770  * ...
2771  * void handler(const boost::system::error_code& e, std::size_t size)
2772  * {
2773  *   if (!e)
2774  *   {
2775  *     std::string line = data.substr(0, n);
2776  *     data.erase(0, n);
2777  *     ...
2778  *   }
2779  * }
2780  * ...
2781  * boost::asio::async_read_until(s, data, "\r\n", handler); @endcode
2782  * After the @c async_read_until operation completes successfully, the string
2783  * @c data contains the delimiter:
2784  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2785  * The call to @c substr then extracts the data up to and including the
2786  * delimiter, so that the string @c line contains:
2787  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
2788  * After the call to @c erase, the remaining data is left in the string @c data
2789  * as follows:
2790  * @code { 'd', 'e', ... } @endcode
2791  * This data may be the start of a new line, to be extracted by a subsequent
2792  * @c async_read_until operation.
2793  *
2794  * @par Per-Operation Cancellation
2795  * This asynchronous operation supports cancellation for the following
2796  * boost::asio::cancellation_type values:
2797  *
2798  * @li @c cancellation_type::terminal
2799  *
2800  * @li @c cancellation_type::partial
2801  *
2802  * if they are also supported by the @c AsyncReadStream type's
2803  * @c async_read_some operation.
2804  */
2805 template <typename AsyncReadStream, typename DynamicBuffer_v2,
2806     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2807       std::size_t)) ReadToken = default_completion_token_t<
2808         typename AsyncReadStream::executor_type>>
2809 auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
2810     BOOST_ASIO_STRING_VIEW_PARAM delim,
2811     ReadToken&& token = default_completion_token_t<
2812       typename AsyncReadStream::executor_type>(),
2813     constraint_t<
2814       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
2815     > = 0)
2816   -> decltype(
2817     async_initiate<ReadToken,
2818       void (boost::system::error_code, std::size_t)>(
2819         declval<detail::initiate_async_read_until_delim_string_v2<
2820           AsyncReadStream>>(),
2821         token, static_cast<DynamicBuffer_v2&&>(buffers),
2822         static_cast<std::string>(delim)));
2823 
2824 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
2825 #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
2826   || defined(GENERATING_DOCUMENTATION)
2827 
2828 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2829 /// until some part of its data matches a regular expression.
2830 /**
2831  * This function is used to asynchronously read data into the specified dynamic
2832  * buffer sequence until the dynamic buffer sequence's get area contains some
2833  * data that matches a regular expression. It is an initiating function for an
2834  * @ref asynchronous_operation, and always returns immediately. The
2835  * asynchronous operation will continue until one of the following conditions
2836  * is true:
2837  *
2838  * @li A substring of the dynamic buffer sequence's get area matches the regular
2839  * expression.
2840  *
2841  * @li An error occurred.
2842  *
2843  * This operation is implemented in terms of zero or more calls to the stream's
2844  * async_read_some function, and is known as a <em>composed operation</em>. If
2845  * the dynamic buffer sequence's get area already contains data that matches
2846  * the regular expression, this asynchronous operation completes immediately.
2847  * The program must ensure that the stream performs no other read operations
2848  * (such as async_read, async_read_until, the stream's async_read_some
2849  * function, or any other composed operations that perform reads) until this
2850  * operation completes.
2851  *
2852  * @param s The stream from which the data is to be read. The type must support
2853  * the AsyncReadStream concept.
2854  *
2855  * @param buffers The dynamic buffer sequence into which the data will be read.
2856  * Although the buffers object may be copied as necessary, ownership of the
2857  * underlying memory blocks is retained by the caller, which must guarantee
2858  * that they remain valid until the completion handler is called.
2859  *
2860  * @param expr The regular expression.
2861  *
2862  * @param token The @ref completion_token that will be used to produce a
2863  * completion handler, which will be called when the read completes.
2864  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2865  * @ref yield_context, or a function object with the correct completion
2866  * signature. The function signature of the completion handler must be:
2867  * @code void handler(
2868  *   // Result of operation.
2869  *   const boost::system::error_code& error,
2870  *
2871  *   // The number of bytes in the dynamic buffer
2872  *   // sequence's get area up to and including the
2873  *   // substring that matches the regular expression.
2874  *   // 0 if an error occurred.
2875  *   std::size_t bytes_transferred
2876  * ); @endcode
2877  * Regardless of whether the asynchronous operation completes immediately or
2878  * not, the completion handler will not be invoked from within this function.
2879  * On immediate completion, invocation of the handler will be performed in a
2880  * manner equivalent to using boost::asio::post().
2881  *
2882  * @par Completion Signature
2883  * @code void(boost::system::error_code, std::size_t) @endcode
2884  *
2885  * @note After a successful async_read_until operation, the dynamic buffer
2886  * sequence may contain additional data beyond that which matched the regular
2887  * expression. An application will typically leave that data in the dynamic
2888  * buffer sequence for a subsequent async_read_until operation to examine.
2889  *
2890  * @par Example
2891  * To asynchronously read data into a @c std::string until a CR-LF sequence is
2892  * encountered:
2893  * @code std::string data;
2894  * ...
2895  * void handler(const boost::system::error_code& e, std::size_t size)
2896  * {
2897  *   if (!e)
2898  *   {
2899  *     std::string line = data.substr(0, n);
2900  *     data.erase(0, n);
2901  *     ...
2902  *   }
2903  * }
2904  * ...
2905  * boost::asio::async_read_until(s, data,
2906  *     boost::regex("\r\n"), handler); @endcode
2907  * After the @c async_read_until operation completes successfully, the string
2908  * @c data contains the data which matched the regular expression:
2909  * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
2910  * The call to @c substr then extracts the data up to and including the match,
2911  * so that the string @c line contains:
2912  * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
2913  * After the call to @c erase, the remaining data is left in the string @c data
2914  * as follows:
2915  * @code { 'd', 'e', ... } @endcode
2916  * This data may be the start of a new line, to be extracted by a subsequent
2917  * @c async_read_until operation.
2918  *
2919  * @par Per-Operation Cancellation
2920  * This asynchronous operation supports cancellation for the following
2921  * boost::asio::cancellation_type values:
2922  *
2923  * @li @c cancellation_type::terminal
2924  *
2925  * @li @c cancellation_type::partial
2926  *
2927  * if they are also supported by the @c AsyncReadStream type's
2928  * @c async_read_some operation.
2929  */
2930 template <typename AsyncReadStream, typename DynamicBuffer_v2, typename Traits,
2931     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2932       std::size_t)) ReadToken = default_completion_token_t<
2933         typename AsyncReadStream::executor_type>>
2934 auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
2935     const boost::basic_regex<char, Traits>& expr,
2936     ReadToken&& token = default_completion_token_t<
2937       typename AsyncReadStream::executor_type>(),
2938     constraint_t<
2939       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
2940     > = 0)
2941   -> decltype(
2942     async_initiate<ReadToken,
2943       void (boost::system::error_code, std::size_t)>(
2944         declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream>>(),
2945         token, static_cast<DynamicBuffer_v2&&>(buffers), expr));
2946 
2947 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
2948        // || defined(GENERATING_DOCUMENTATION)
2949 
2950 /// Start an asynchronous operation to read data into a dynamic buffer sequence
2951 /// until a function object indicates a match.
2952 /**
2953  * This function is used to asynchronously read data into the specified dynamic
2954  * buffer sequence until a user-defined match condition function object, when
2955  * applied to the data contained in the dynamic buffer sequence, indicates a
2956  * successful match. It is an initiating function for an @ref
2957  * asynchronous_operation, and always returns immediately. The asynchronous
2958  * operation will continue until one of the following conditions is true:
2959  *
2960  * @li The match condition function object returns a std::pair where the second
2961  * element evaluates to true.
2962  *
2963  * @li An error occurred.
2964  *
2965  * This operation is implemented in terms of zero or more calls to the stream's
2966  * async_read_some function, and is known as a <em>composed operation</em>. If
2967  * the match condition function object already indicates a match, this
2968  * asynchronous operation completes immediately. The program must ensure that
2969  * the stream performs no other read operations (such as async_read,
2970  * async_read_until, the stream's async_read_some function, or any other
2971  * composed operations that perform reads) until this operation completes.
2972  *
2973  * @param s The stream from which the data is to be read. The type must support
2974  * the AsyncReadStream concept.
2975  *
2976  * @param buffers The dynamic buffer sequence into which the data will be read.
2977  * Although the buffers object may be copied as necessary, ownership of the
2978  * underlying memory blocks is retained by the caller, which must guarantee
2979  * that they remain valid until the completion handler is called.
2980  *
2981  * @param match_condition The function object to be called to determine whether
2982  * a match exists. The signature of the function object must be:
2983  * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
2984  * @endcode
2985  * where @c iterator represents the type:
2986  * @code buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>
2987  * @endcode
2988  * The iterator parameters @c begin and @c end define the range of bytes to be
2989  * scanned to determine whether there is a match. The @c first member of the
2990  * return value is an iterator marking one-past-the-end of the bytes that have
2991  * been consumed by the match function. This iterator is used to calculate the
2992  * @c begin parameter for any subsequent invocation of the match condition. The
2993  * @c second member of the return value is true if a match has been found, false
2994  * otherwise.
2995  *
2996  * @param token The @ref completion_token that will be used to produce a
2997  * completion handler, which will be called when the read completes.
2998  * Potential completion tokens include @ref use_future, @ref use_awaitable,
2999  * @ref yield_context, or a function object with the correct completion
3000  * signature. The function signature of the completion handler must be:
3001  * @code void handler(
3002  *   // Result of operation.
3003  *   const boost::system::error_code& error,
3004  *
3005  *   // The number of bytes in the dynamic buffer sequence's
3006  *   // get area that have been fully consumed by the match
3007  *   // function. O if an error occurred.
3008  *   std::size_t bytes_transferred
3009  * ); @endcode
3010  * Regardless of whether the asynchronous operation completes immediately or
3011  * not, the completion handler will not be invoked from within this function.
3012  * On immediate completion, invocation of the handler will be performed in a
3013  * manner equivalent to using boost::asio::post().
3014  *
3015  * @note After a successful async_read_until operation, the dynamic buffer
3016  * sequence may contain additional data beyond that which matched the function
3017  * object. An application will typically leave that data in the dynamic buffer
3018  * sequence for a subsequent async_read_until operation to examine.
3019  *
3020  * @par Completion Signature
3021  * @code void(boost::system::error_code, std::size_t) @endcode
3022  *
3023  * @note The default implementation of the @c is_match_condition type trait
3024  * evaluates to true for function pointers and function objects with a
3025  * @c result_type typedef. It must be specialised for other user-defined
3026  * function objects.
3027  *
3028  * @par Examples
3029  * To asynchronously read data into a @c std::string until whitespace is
3030  * encountered:
3031  * @code typedef boost::asio::buffers_iterator<
3032  *     boost::asio::const_buffers_1> iterator;
3033  *
3034  * std::pair<iterator, bool>
3035  * match_whitespace(iterator begin, iterator end)
3036  * {
3037  *   iterator i = begin;
3038  *   while (i != end)
3039  *     if (std::isspace(*i++))
3040  *       return std::make_pair(i, true);
3041  *   return std::make_pair(i, false);
3042  * }
3043  * ...
3044  * void handler(const boost::system::error_code& e, std::size_t size);
3045  * ...
3046  * std::string data;
3047  * boost::asio::async_read_until(s, data, match_whitespace, handler);
3048  * @endcode
3049  *
3050  * To asynchronously read data into a @c std::string until a matching character
3051  * is found:
3052  * @code class match_char
3053  * {
3054  * public:
3055  *   explicit match_char(char c) : c_(c) {}
3056  *
3057  *   template <typename Iterator>
3058  *   std::pair<Iterator, bool> operator()(
3059  *       Iterator begin, Iterator end) const
3060  *   {
3061  *     Iterator i = begin;
3062  *     while (i != end)
3063  *       if (c_ == *i++)
3064  *         return std::make_pair(i, true);
3065  *     return std::make_pair(i, false);
3066  *   }
3067  *
3068  * private:
3069  *   char c_;
3070  * };
3071  *
3072  * namespace asio {
3073  *   template <> struct is_match_condition<match_char>
3074  *     : public boost::true_type {};
3075  * } // namespace asio
3076  * ...
3077  * void handler(const boost::system::error_code& e, std::size_t size);
3078  * ...
3079  * std::string data;
3080  * boost::asio::async_read_until(s, data, match_char('a'), handler);
3081  * @endcode
3082  *
3083  * @par Per-Operation Cancellation
3084  * This asynchronous operation supports cancellation for the following
3085  * boost::asio::cancellation_type values:
3086  *
3087  * @li @c cancellation_type::terminal
3088  *
3089  * @li @c cancellation_type::partial
3090  *
3091  * if they are also supported by the @c AsyncReadStream type's
3092  * @c async_read_some operation.
3093  */
3094 template <typename AsyncReadStream,
3095     typename DynamicBuffer_v2, typename MatchCondition,
3096     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
3097       std::size_t)) ReadToken = default_completion_token_t<
3098         typename AsyncReadStream::executor_type>>
3099 auto async_read_until(AsyncReadStream& s,
3100     DynamicBuffer_v2 buffers, MatchCondition match_condition,
3101     ReadToken&& token = default_completion_token_t<
3102       typename AsyncReadStream::executor_type>(),
3103     constraint_t<
3104       is_match_condition<MatchCondition>::value
3105     > = 0,
3106     constraint_t<
3107       is_dynamic_buffer_v2<DynamicBuffer_v2>::value
3108     > = 0)
3109   -> decltype(
3110     async_initiate<ReadToken,
3111       void (boost::system::error_code, std::size_t)>(
3112         declval<detail::initiate_async_read_until_match_v2<AsyncReadStream>>(),
3113         token, static_cast<DynamicBuffer_v2&&>(buffers), match_condition));
3114 
3115 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
3116 
3117 /*@}*/
3118 
3119 } // namespace asio
3120 } // namespace boost
3121 
3122 #include <boost/asio/detail/pop_options.hpp>
3123 
3124 #include <boost/asio/impl/read_until.hpp>
3125 
3126 #endif // BOOST_ASIO_READ_UNTIL_HPP