diff --git a/linx64/include/boost/accumulators/numeric/functional.hpp b/linx64/include/boost/accumulators/numeric/functional.hpp index d5d79f5c..858decc1 100644 --- a/linx64/include/boost/accumulators/numeric/functional.hpp +++ b/linx64/include/boost/accumulators/numeric/functional.hpp @@ -99,11 +99,9 @@ namespace boost { namespace numeric }; \ template \ struct Name ## _base \ - : std::unary_function< \ - typename remove_const::type \ - , typename result_of_ ## Name::type \ - > \ { \ + typedef typename remove_const::type argument_type; \ + typedef typename result_of_ ## Name::type result_type; \ typename result_of_ ## Name::type operator ()(Arg &arg) const \ { \ return Op arg; \ @@ -138,12 +136,10 @@ namespace boost { namespace numeric }; \ template \ struct Name ## _base \ - : std::binary_function< \ - typename remove_const::type \ - , typename remove_const::type \ - , typename result_of_ ## Name::type \ - > \ { \ + typedef typename remove_const::type first_argument_type; \ + typedef typename remove_const::type second_argument_type; \ + typedef typename result_of_ ## Name::type result_type; \ typename result_of_ ## Name::type \ operator ()(Left &left, Right &right) const \ { \ @@ -220,8 +216,11 @@ namespace boost { namespace numeric { template struct min_assign_base - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { if(numeric::less(right, left)) @@ -233,8 +232,11 @@ namespace boost { namespace numeric template struct max_assign_base - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { if(numeric::greater(right, left)) @@ -258,8 +260,10 @@ namespace boost { namespace numeric template struct promote_base - : std::unary_function { + typedef From argument_type; + typedef To result_type; + To operator ()(From &from) const { return from; @@ -268,8 +272,10 @@ namespace boost { namespace numeric template struct promote_base - : std::unary_function { + typedef ToFrom argument_type; + typedef ToFrom result_type; + ToFrom &operator ()(ToFrom &tofrom) { return tofrom; @@ -278,10 +284,12 @@ namespace boost { namespace numeric template struct as_min_base - : std::unary_function::type> { BOOST_STATIC_ASSERT(std::numeric_limits::type>::is_specialized); + typedef Arg argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(Arg &) const { return (std::numeric_limits::type>::min)(); @@ -290,10 +298,12 @@ namespace boost { namespace numeric template struct as_min_base >::type> - : std::unary_function::type> { BOOST_STATIC_ASSERT(std::numeric_limits::type>::is_specialized); + typedef Arg argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(Arg &) const { return -(std::numeric_limits::type>::max)(); @@ -302,10 +312,12 @@ namespace boost { namespace numeric template struct as_max_base - : std::unary_function::type> { BOOST_STATIC_ASSERT(std::numeric_limits::type>::is_specialized); + typedef Arg argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(Arg &) const { return (std::numeric_limits::type>::max)(); @@ -314,8 +326,10 @@ namespace boost { namespace numeric template struct as_zero_base - : std::unary_function::type> { + typedef Arg argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(Arg &) const { return numeric::zero::type>::value; @@ -324,8 +338,10 @@ namespace boost { namespace numeric template struct as_one_base - : std::unary_function::type> { + typedef Arg argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(Arg &) const { return numeric::one::type>::value; diff --git a/linx64/include/boost/accumulators/numeric/functional/valarray.hpp b/linx64/include/boost/accumulators/numeric/functional/valarray.hpp index c24b4585..1996c758 100644 --- a/linx64/include/boost/accumulators/numeric/functional/valarray.hpp +++ b/linx64/include/boost/accumulators/numeric/functional/valarray.hpp @@ -118,17 +118,9 @@ namespace boost { namespace numeric #define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \ template \ struct Name \ - : std::binary_function< \ - Left \ - , Right \ - , std::valarray< \ - typename Name< \ - typename Left::value_type \ - , typename Right::value_type \ - >::result_type \ - > \ - > \ { \ + typedef Left first_argument_type; \ + typedef Right second_argument_type; \ typedef typename Left::value_type left_value_type; \ typedef typename Right::value_type right_value_type; \ typedef \ @@ -145,14 +137,9 @@ namespace boost { namespace numeric }; \ template \ struct Name \ - : std::binary_function< \ - Left \ - , Right \ - , std::valarray< \ - typename Name::result_type \ - > \ - > \ { \ + typedef Left first_argument_type; \ + typedef Right second_argument_type; \ typedef typename Left::value_type left_value_type; \ typedef \ std::valarray< \ @@ -167,14 +154,9 @@ namespace boost { namespace numeric }; \ template \ struct Name \ - : std::binary_function< \ - Left \ - , Right \ - , std::valarray< \ - typename Name::result_type \ - > \ - > \ { \ + typedef Left first_argument_type; \ + typedef Right second_argument_type; \ typedef typename Right::value_type right_value_type; \ typedef \ std::valarray< \ @@ -200,8 +182,11 @@ namespace boost { namespace numeric // element-wise min of std::valarray template struct min_assign - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { BOOST_ASSERT(left.size() == right.size()); @@ -219,8 +204,11 @@ namespace boost { namespace numeric // element-wise max of std::valarray template struct max_assign - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { BOOST_ASSERT(left.size() == right.size()); @@ -247,8 +235,10 @@ namespace boost { namespace numeric // promote template struct promote - : std::unary_function { + typedef From argument_type; + typedef To result_type; + To operator ()(From &arr) const { typename remove_const::type res(arr.size()); @@ -262,8 +252,10 @@ namespace boost { namespace numeric template struct promote - : std::unary_function { + typedef ToFrom argument_type; + typedef ToFrom result_type; + ToFrom &operator ()(ToFrom &tofrom) const { return tofrom; @@ -275,8 +267,10 @@ namespace boost { namespace numeric // if(numeric::promote(a == b)) template struct promote - : std::unary_function { + typedef From argument_type; + typedef bool result_type; + bool operator ()(From &arr) const { BOOST_MPL_ASSERT((is_same)); @@ -300,8 +294,10 @@ namespace boost { namespace numeric // functional::as_min template struct as_min - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -314,8 +310,10 @@ namespace boost { namespace numeric // functional::as_max template struct as_max - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -328,8 +326,10 @@ namespace boost { namespace numeric // functional::as_zero template struct as_zero - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -342,8 +342,10 @@ namespace boost { namespace numeric // functional::as_one template struct as_one - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() diff --git a/linx64/include/boost/accumulators/numeric/functional/vector.hpp b/linx64/include/boost/accumulators/numeric/functional/vector.hpp index 8a68a3f3..4c2fbd8a 100644 --- a/linx64/include/boost/accumulators/numeric/functional/vector.hpp +++ b/linx64/include/boost/accumulators/numeric/functional/vector.hpp @@ -195,8 +195,11 @@ namespace boost { namespace numeric // element-wise min of std::vector template struct min_assign - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { BOOST_ASSERT(left.size() == right.size()); @@ -214,8 +217,11 @@ namespace boost { namespace numeric // element-wise max of std::vector template struct max_assign - : std::binary_function { + typedef Left first_argument_type; + typedef Right second_argument_type; + typedef void result_type; + void operator ()(Left &left, Right &right) const { BOOST_ASSERT(left.size() == right.size()); @@ -242,8 +248,10 @@ namespace boost { namespace numeric // promote template struct promote - : std::unary_function { + typedef From argument_type; + typedef To result_type; + To operator ()(From &arr) const { typename remove_const::type res(arr.size()); @@ -257,8 +265,10 @@ namespace boost { namespace numeric template struct promote - : std::unary_function { + typedef ToFrom argument_type; + typedef ToFrom result_type; + ToFrom &operator ()(ToFrom &tofrom) const { return tofrom; @@ -269,8 +279,10 @@ namespace boost { namespace numeric // functional::as_min template struct as_min - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -283,8 +295,10 @@ namespace boost { namespace numeric // functional::as_max template struct as_max - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -297,8 +311,10 @@ namespace boost { namespace numeric // functional::as_zero template struct as_zero - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() @@ -311,8 +327,10 @@ namespace boost { namespace numeric // functional::as_one template struct as_one - : std::unary_function::type> { + typedef T argument_type; + typedef typename remove_const::type result_type; + typename remove_const::type operator ()(T &arr) const { return 0 == arr.size() diff --git a/linx64/include/boost/accumulators/statistics/covariance.hpp b/linx64/include/boost/accumulators/statistics/covariance.hpp index 73c92aeb..b3030b96 100644 --- a/linx64/include/boost/accumulators/statistics/covariance.hpp +++ b/linx64/include/boost/accumulators/statistics/covariance.hpp @@ -50,17 +50,9 @@ namespace boost { namespace numeric template struct outer_product - : std::binary_function< - Left - , Right - , ublas::matrix< - typename functional::multiplies< - typename Left::value_type - , typename Right::value_type - >::result_type - > - > { + typedef Left first_argument_type; + typedef Right second_argument_type; typedef ublas::matrix< typename functional::multiplies< diff --git a/linx64/include/boost/accumulators/statistics/tail.hpp b/linx64/include/boost/accumulators/statistics/tail.hpp index cc9267f9..be6cdee3 100644 --- a/linx64/include/boost/accumulators/statistics/tail.hpp +++ b/linx64/include/boost/accumulators/statistics/tail.hpp @@ -248,8 +248,11 @@ namespace impl /////////////////////////////////////////////////////////////////////////////// // struct indirect_cmp - : std::binary_function { + typedef std::size_t first_argument_type; + typedef std::size_t second_argument_type; + typedef bool result_type; + indirect_cmp(std::vector const &s) : samples(s) { diff --git a/linx64/include/boost/accumulators/statistics/tail_variate_means.hpp b/linx64/include/boost/accumulators/statistics/tail_variate_means.hpp index d34d4abc..a97eab56 100644 --- a/linx64/include/boost/accumulators/statistics/tail_variate_means.hpp +++ b/linx64/include/boost/accumulators/statistics/tail_variate_means.hpp @@ -118,7 +118,11 @@ namespace impl this->tail_means_.begin() , this->tail_means_.end() , this->tail_means_.begin() +#ifdef BOOST_NO_CXX98_BINDERS + , std::bind(std::divides(), std::placeholders::_1, factor) +#else , std::bind2nd(std::divides(), factor) +#endif ); } else diff --git a/linx64/include/boost/accumulators/statistics/times2_iterator.hpp b/linx64/include/boost/accumulators/statistics/times2_iterator.hpp index d46dd042..dbd81af7 100644 --- a/linx64/include/boost/accumulators/statistics/times2_iterator.hpp +++ b/linx64/include/boost/accumulators/statistics/times2_iterator.hpp @@ -23,7 +23,11 @@ namespace boost { namespace accumulators namespace detail { typedef transform_iterator< +#ifdef BOOST_NO_CXX98_BINDERS + decltype(std::bind(std::multiplies(), 2, std::placeholders::_1)) +#else std::binder1st > +#endif , counting_iterator > times2_iterator; @@ -31,7 +35,11 @@ namespace detail { return make_transform_iterator( make_counting_iterator(i) +#ifdef BOOST_NO_CXX98_BINDERS + , std::bind(std::multiplies(), 2, std::placeholders::_1) +#else , std::bind1st(std::multiplies(), 2) +#endif ); } diff --git a/linx64/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp b/linx64/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp index 2c907833..b1133109 100644 --- a/linx64/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp +++ b/linx64/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp @@ -169,7 +169,11 @@ namespace impl this->tail_means_.begin() , this->tail_means_.end() , this->tail_means_.begin() +#ifdef BOOST_NO_CXX98_BINDERS + , std::bind(numeric::functional::divides(), std::placeholders::_1, factor) +#else , std::bind2nd(numeric::functional::divides(), factor) +#endif ); return make_iterator_range(this->tail_means_); diff --git a/linx64/include/boost/algorithm/algorithm.hpp b/linx64/include/boost/algorithm/algorithm.hpp index ab0d4aff..2bbee1d2 100644 --- a/linx64/include/boost/algorithm/algorithm.hpp +++ b/linx64/include/boost/algorithm/algorithm.hpp @@ -25,10 +25,10 @@ namespace boost { namespace algorithm { template -T identity_operation ( std::multiplies ) { return T(1); } +BOOST_CXX14_CONSTEXPR T identity_operation ( std::multiplies ) { return T(1); } template -T identity_operation ( std::plus ) { return T(0); } +BOOST_CXX14_CONSTEXPR T identity_operation ( std::plus ) { return T(0); } /// \fn power ( T x, Integer n ) @@ -40,7 +40,7 @@ T identity_operation ( std::plus ) { return T(0); } // \remark Taken from Knuth, The Art of Computer Programming, Volume 2: // Seminumerical Algorithms, Section 4.6.3 template -typename boost::enable_if, T>::type +BOOST_CXX14_CONSTEXPR typename boost::enable_if, T>::type power (T x, Integer n) { T y = 1; // Should be "T y{1};" if (n == 0) return y; @@ -67,7 +67,7 @@ power (T x, Integer n) { // \remark Taken from Knuth, The Art of Computer Programming, Volume 2: // Seminumerical Algorithms, Section 4.6.3 template -typename boost::enable_if, T>::type +BOOST_CXX14_CONSTEXPR typename boost::enable_if, T>::type power (T x, Integer n, Operation op) { T y = identity_operation(op); if (n == 0) return y; diff --git a/linx64/include/boost/algorithm/apply_permutation.hpp b/linx64/include/boost/algorithm/apply_permutation.hpp new file mode 100644 index 00000000..b9de0ded --- /dev/null +++ b/linx64/include/boost/algorithm/apply_permutation.hpp @@ -0,0 +1,126 @@ +/* + Copyright (c) Alexander Zaitsev , 2017 + + Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) + + See http://www.boost.org/ for latest version. + + + Based on https://blogs.msdn.microsoft.com/oldnewthing/20170104-00/?p=95115 +*/ + +/// \file apply_permutation.hpp +/// \brief Apply permutation to a sequence. +/// \author Alexander Zaitsev + +#ifndef BOOST_ALGORITHM_APPLY_PERMUTATION_HPP +#define BOOST_ALGORITHM_APPLY_PERMUTATION_HPP + +#include +#include + +#include +#include + +namespace boost { namespace algorithm +{ + +/// \fn apply_permutation ( RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end, RandomAccessIterator2 ind_begin ) +/// \brief Reorder item sequence with index sequence order +/// +/// \param item_begin The start of the item sequence +/// \param item_end One past the end of the item sequence +/// \param ind_begin The start of the index sequence. +/// +/// \note Item sequence size should be equal to index size. Otherwise behavior is undefined. +/// Complexity: O(N). +template +void +apply_permutation(RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end, + RandomAccessIterator2 ind_begin, RandomAccessIterator2 ind_end) +{ + typedef typename std::iterator_traits::difference_type Diff; + typedef typename std::iterator_traits::difference_type Index; + using std::swap; + Diff size = std::distance(item_begin, item_end); + for (Diff i = 0; i < size; i++) + { + Diff current = i; + while (i != ind_begin[current]) + { + Index next = ind_begin[current]; + swap(item_begin[current], item_begin[next]); + ind_begin[current] = current; + current = next; + } + ind_begin[current] = current; + } +} + +/// \fn apply_reverse_permutation ( RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end, RandomAccessIterator2 ind_begin ) +/// \brief Reorder item sequence with index sequence order +/// +/// \param item_begin The start of the item sequence +/// \param item_end One past the end of the item sequence +/// \param ind_begin The start of the index sequence. +/// +/// \note Item sequence size should be equal to index size. Otherwise behavior is undefined. +/// Complexity: O(N). +template +void +apply_reverse_permutation( + RandomAccessIterator1 item_begin, + RandomAccessIterator1 item_end, + RandomAccessIterator2 ind_begin, + RandomAccessIterator2 ind_end) +{ + typedef typename std::iterator_traits::difference_type Diff; + using std::swap; + Diff length = std::distance(item_begin, item_end); + for (Diff i = 0; i < length; i++) + { + while (i != ind_begin[i]) + { + Diff next = ind_begin[i]; + swap(item_begin[i], item_begin[next]); + swap(ind_begin[i], ind_begin[next]); + } + } +} + +/// \fn apply_permutation ( Range1 item_range, Range2 ind_range ) +/// \brief Reorder item sequence with index sequence order +/// +/// \param item_range The item sequence +/// \param ind_range The index sequence +/// +/// \note Item sequence size should be equal to index size. Otherwise behavior is undefined. +/// Complexity: O(N). +template +void +apply_permutation(Range1& item_range, Range2& ind_range) +{ + apply_permutation(boost::begin(item_range), boost::end(item_range), + boost::begin(ind_range), boost::end(ind_range)); +} + +/// \fn apply_reverse_permutation ( Range1 item_range, Range2 ind_range ) +/// \brief Reorder item sequence with index sequence order +/// +/// \param item_range The item sequence +/// \param ind_range The index sequence +/// +/// \note Item sequence size should be equal to index size. Otherwise behavior is undefined. +/// Complexity: O(N). +template +void +apply_reverse_permutation(Range1& item_range, Range2& ind_range) +{ + apply_reverse_permutation(boost::begin(item_range), boost::end(item_range), + boost::begin(ind_range), boost::end(ind_range)); +} + +}} +#endif //BOOST_ALGORITHM_APPLY_PERMUTATION_HPP diff --git a/linx64/include/boost/algorithm/clamp.hpp b/linx64/include/boost/algorithm/clamp.hpp index 7bfa47ec..d027acdf 100644 --- a/linx64/include/boost/algorithm/clamp.hpp +++ b/linx64/include/boost/algorithm/clamp.hpp @@ -46,7 +46,7 @@ namespace boost { namespace algorithm { /// p ( a, b ) returns a boolean. /// template - T const & clamp ( T const& val, + BOOST_CXX14_CONSTEXPR T const & clamp ( T const& val, typename boost::mpl::identity::type const & lo, typename boost::mpl::identity::type const & hi, Pred p ) { @@ -68,11 +68,11 @@ namespace boost { namespace algorithm { /// \param hi The upper bound of the range to be clamped to /// template - T const& clamp ( const T& val, + BOOST_CXX14_CONSTEXPR T const& clamp ( const T& val, typename boost::mpl::identity::type const & lo, typename boost::mpl::identity::type const & hi ) { - return (clamp) ( val, lo, hi, std::less()); + return boost::algorithm::clamp ( val, lo, hi, std::less()); } /// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, @@ -87,13 +87,13 @@ namespace boost { namespace algorithm { /// \param hi The upper bound of the range to be clamped to /// template - OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, + BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, typename std::iterator_traits::value_type const & lo, typename std::iterator_traits::value_type const & hi ) { // this could also be written with bind and std::transform while ( first != last ) - *out++ = clamp ( *first++, lo, hi ); + *out++ = boost::algorithm::clamp ( *first++, lo, hi ); return out; } @@ -108,12 +108,12 @@ namespace boost { namespace algorithm { /// \param hi The upper bound of the range to be clamped to /// template - typename boost::disable_if_c::value, OutputIterator>::type + BOOST_CXX14_CONSTEXPR typename boost::disable_if_c::value, OutputIterator>::type clamp_range ( const Range &r, OutputIterator out, typename std::iterator_traits::type>::value_type const & lo, typename std::iterator_traits::type>::value_type const & hi ) { - return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi ); + return boost::algorithm::clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi ); } @@ -133,13 +133,13 @@ namespace boost { namespace algorithm { /// template - OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, + BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, typename std::iterator_traits::value_type const & lo, typename std::iterator_traits::value_type const & hi, Pred p ) { // this could also be written with bind and std::transform while ( first != last ) - *out++ = clamp ( *first++, lo, hi, p ); + *out++ = boost::algorithm::clamp ( *first++, lo, hi, p ); return out; } @@ -160,13 +160,13 @@ namespace boost { namespace algorithm { // Disable this template if the first two parameters are the same type; // In that case, the user will get the two iterator version. template - typename boost::disable_if_c::value, OutputIterator>::type + BOOST_CXX14_CONSTEXPR typename boost::disable_if_c::value, OutputIterator>::type clamp_range ( const Range &r, OutputIterator out, typename std::iterator_traits::type>::value_type const & lo, typename std::iterator_traits::type>::value_type const & hi, Pred p ) { - return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p ); + return boost::algorithm::clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p ); } diff --git a/linx64/include/boost/algorithm/cxx11/all_of.hpp b/linx64/include/boost/algorithm/cxx11/all_of.hpp index 8280b18d..527bbd50 100644 --- a/linx64/include/boost/algorithm/cxx11/all_of.hpp +++ b/linx64/include/boost/algorithm/cxx11/all_of.hpp @@ -27,7 +27,7 @@ namespace boost { namespace algorithm { /// /// \note This function is part of the C++2011 standard library. template -bool all_of ( InputIterator first, InputIterator last, Predicate p ) +BOOST_CXX14_CONSTEXPR bool all_of ( InputIterator first, InputIterator last, Predicate p ) { for ( ; first != last; ++first ) if ( !p(*first)) @@ -43,7 +43,7 @@ bool all_of ( InputIterator first, InputIterator last, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -bool all_of ( const Range &r, Predicate p ) +BOOST_CXX14_CONSTEXPR bool all_of ( const Range &r, Predicate p ) { return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p ); } @@ -57,7 +57,7 @@ bool all_of ( const Range &r, Predicate p ) /// \param val A value to compare against /// template -bool all_of_equal ( InputIterator first, InputIterator last, const T &val ) +BOOST_CXX14_CONSTEXPR bool all_of_equal ( InputIterator first, InputIterator last, const T &val ) { for ( ; first != last; ++first ) if ( val != *first ) @@ -73,7 +73,7 @@ bool all_of_equal ( InputIterator first, InputIterator last, const T &val ) /// \param val A value to compare against /// template -bool all_of_equal ( const Range &r, const T &val ) +BOOST_CXX14_CONSTEXPR bool all_of_equal ( const Range &r, const T &val ) { return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val ); } diff --git a/linx64/include/boost/algorithm/cxx11/any_of.hpp b/linx64/include/boost/algorithm/cxx11/any_of.hpp index e68135a2..d9e24141 100644 --- a/linx64/include/boost/algorithm/cxx11/any_of.hpp +++ b/linx64/include/boost/algorithm/cxx11/any_of.hpp @@ -28,7 +28,7 @@ namespace boost { namespace algorithm { /// \param p A predicate for testing the elements of the sequence /// template -bool any_of ( InputIterator first, InputIterator last, Predicate p ) +BOOST_CXX14_CONSTEXPR bool any_of ( InputIterator first, InputIterator last, Predicate p ) { for ( ; first != last; ++first ) if ( p(*first)) @@ -44,7 +44,7 @@ bool any_of ( InputIterator first, InputIterator last, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -bool any_of ( const Range &r, Predicate p ) +BOOST_CXX14_CONSTEXPR bool any_of ( const Range &r, Predicate p ) { return boost::algorithm::any_of (boost::begin (r), boost::end (r), p); } @@ -58,7 +58,7 @@ bool any_of ( const Range &r, Predicate p ) /// \param val A value to compare against /// template -bool any_of_equal ( InputIterator first, InputIterator last, const V &val ) +BOOST_CXX14_CONSTEXPR bool any_of_equal ( InputIterator first, InputIterator last, const V &val ) { for ( ; first != last; ++first ) if ( val == *first ) @@ -74,7 +74,7 @@ bool any_of_equal ( InputIterator first, InputIterator last, const V &val ) /// \param val A value to compare against /// template -bool any_of_equal ( const Range &r, const V &val ) +BOOST_CXX14_CONSTEXPR bool any_of_equal ( const Range &r, const V &val ) { return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val); } diff --git a/linx64/include/boost/algorithm/cxx11/copy_if.hpp b/linx64/include/boost/algorithm/cxx11/copy_if.hpp index 73e85d99..dc1fdeff 100644 --- a/linx64/include/boost/algorithm/cxx11/copy_if.hpp +++ b/linx64/include/boost/algorithm/cxx11/copy_if.hpp @@ -29,7 +29,7 @@ namespace boost { namespace algorithm { /// \param p A predicate for testing the elements of the range /// \note This function is part of the C++2011 standard library. template -OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) +BOOST_CXX14_CONSTEXPR OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) { for ( ; first != last; ++first ) if (p(*first)) @@ -47,7 +47,7 @@ OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator /// \param p A predicate for testing the elements of the range /// template -OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) +BOOST_CXX14_CONSTEXPR OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) { return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p); } @@ -64,7 +64,7 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -std::pair +BOOST_CXX14_CONSTEXPR std::pair copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) { for ( ; first != last && p(*first); ++first ) @@ -82,7 +82,7 @@ copy_while ( InputIterator first, InputIterator last, OutputIterator result, Pre /// \param p A predicate for testing the elements of the range /// template -std::pair::type, OutputIterator> +BOOST_CXX14_CONSTEXPR std::pair::type, OutputIterator> copy_while ( const Range &r, OutputIterator result, Predicate p ) { return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p); @@ -100,7 +100,7 @@ copy_while ( const Range &r, OutputIterator result, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -std::pair +BOOST_CXX14_CONSTEXPR std::pair copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) { for ( ; first != last && !p(*first); ++first ) @@ -118,7 +118,7 @@ copy_until ( InputIterator first, InputIterator last, OutputIterator result, Pre /// \param p A predicate for testing the elements of the range /// template -std::pair::type, OutputIterator> +BOOST_CXX14_CONSTEXPR std::pair::type, OutputIterator> copy_until ( const Range &r, OutputIterator result, Predicate p ) { return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p); diff --git a/linx64/include/boost/algorithm/cxx11/copy_n.hpp b/linx64/include/boost/algorithm/cxx11/copy_n.hpp index ac880856..e4bebd07 100644 --- a/linx64/include/boost/algorithm/cxx11/copy_n.hpp +++ b/linx64/include/boost/algorithm/cxx11/copy_n.hpp @@ -24,7 +24,7 @@ namespace boost { namespace algorithm { /// \param result An output iterator to write the results into /// \note This function is part of the C++2011 standard library. template -OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result ) +BOOST_CXX14_CONSTEXPR OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result ) { for ( ; n > 0; --n, ++first, ++result ) *result = *first; diff --git a/linx64/include/boost/algorithm/cxx11/find_if_not.hpp b/linx64/include/boost/algorithm/cxx11/find_if_not.hpp index 02ff4dce..6f5799a3 100644 --- a/linx64/include/boost/algorithm/cxx11/find_if_not.hpp +++ b/linx64/include/boost/algorithm/cxx11/find_if_not.hpp @@ -26,7 +26,7 @@ namespace boost { namespace algorithm { /// \param p A predicate for testing the elements of the range /// \note This function is part of the C++2011 standard library. template -InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p ) +BOOST_CXX14_CONSTEXPR InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p ) { for ( ; first != last; ++first ) if ( !p(*first)) @@ -42,7 +42,7 @@ InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p /// \param p A predicate for testing the elements of the range /// template -typename boost::range_iterator::type find_if_not ( const Range &r, Predicate p ) +BOOST_CXX14_CONSTEXPR typename boost::range_iterator::type find_if_not ( const Range &r, Predicate p ) { return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p); } diff --git a/linx64/include/boost/algorithm/cxx11/iota.hpp b/linx64/include/boost/algorithm/cxx11/iota.hpp index 675093f0..6efc4d8d 100644 --- a/linx64/include/boost/algorithm/cxx11/iota.hpp +++ b/linx64/include/boost/algorithm/cxx11/iota.hpp @@ -25,7 +25,7 @@ namespace boost { namespace algorithm { /// \param value The initial value of the sequence to be generated /// \note This function is part of the C++2011 standard library. template -void iota ( ForwardIterator first, ForwardIterator last, T value ) +BOOST_CXX14_CONSTEXPR void iota ( ForwardIterator first, ForwardIterator last, T value ) { for ( ; first != last; ++first, ++value ) *first = value; @@ -38,7 +38,7 @@ void iota ( ForwardIterator first, ForwardIterator last, T value ) /// \param value The initial value of the sequence to be generated /// template -void iota ( Range &r, T value ) +BOOST_CXX14_CONSTEXPR void iota ( Range &r, T value ) { boost::algorithm::iota (boost::begin(r), boost::end(r), value); } @@ -52,7 +52,7 @@ void iota ( Range &r, T value ) /// \param n The number of items to write /// template -OutputIterator iota_n ( OutputIterator out, T value, std::size_t n ) +BOOST_CXX14_CONSTEXPR OutputIterator iota_n ( OutputIterator out, T value, std::size_t n ) { for ( ; n > 0; --n, ++value ) *out++ = value; diff --git a/linx64/include/boost/algorithm/cxx11/is_partitioned.hpp b/linx64/include/boost/algorithm/cxx11/is_partitioned.hpp index cb6c71e3..fb2c5a17 100644 --- a/linx64/include/boost/algorithm/cxx11/is_partitioned.hpp +++ b/linx64/include/boost/algorithm/cxx11/is_partitioned.hpp @@ -18,14 +18,15 @@ namespace boost { namespace algorithm { /// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) -/// \brief Tests to see if a sequence is partitioned according to a predicate +/// \brief Tests to see if a sequence is partitioned according to a predicate. +/// In other words, all the items in the sequence that satisfy the predicate are at the beginning of the sequence. /// /// \param first The start of the input sequence /// \param last One past the end of the input sequence /// \param p The predicate to test the values with /// \note This function is part of the C++2011 standard library. template -bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) +BOOST_CXX14_CONSTEXPR bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) { // Run through the part that satisfy the predicate for ( ; first != last; ++first ) @@ -39,13 +40,14 @@ bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p } /// \fn is_partitioned ( const Range &r, UnaryPredicate p ) -/// \brief Generates an increasing sequence of values, and stores them in the input Range. +/// \brief Tests to see if a sequence is partitioned according to a predicate. +/// In other words, all the items in the sequence that satisfy the predicate are at the beginning of the sequence. /// /// \param r The input range /// \param p The predicate to test the values with /// template -bool is_partitioned ( const Range &r, UnaryPredicate p ) +BOOST_CXX14_CONSTEXPR bool is_partitioned ( const Range &r, UnaryPredicate p ) { return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p); } diff --git a/linx64/include/boost/algorithm/cxx11/is_sorted.hpp b/linx64/include/boost/algorithm/cxx11/is_sorted.hpp index f4dbb38c..27662116 100644 --- a/linx64/include/boost/algorithm/cxx11/is_sorted.hpp +++ b/linx64/include/boost/algorithm/cxx11/is_sorted.hpp @@ -34,7 +34,7 @@ namespace boost { namespace algorithm { /// \param p A binary predicate that returns true if two elements are ordered. /// template - ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p ) + BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p ) { if ( first == last ) return last; // the empty sequence is ordered ForwardIterator next = first; @@ -54,7 +54,7 @@ namespace boost { namespace algorithm { /// \param last One past the end of the sequence /// template - ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; return boost::algorithm::is_sorted_until ( first, last, std::less()); @@ -69,7 +69,7 @@ namespace boost { namespace algorithm { /// \param p A binary predicate that returns true if two elements are ordered. /// template - bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p ) + BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p ) { return boost::algorithm::is_sorted_until (first, last, p) == last; } @@ -81,7 +81,7 @@ namespace boost { namespace algorithm { /// \param last One past the end of the sequence /// template - bool is_sorted ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last ) { return boost::algorithm::is_sorted_until (first, last) == last; } @@ -98,7 +98,7 @@ namespace boost { namespace algorithm { /// \param p A binary predicate that returns true if two elements are ordered. /// template - typename boost::lazy_disable_if_c< + BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same::value, typename boost::range_iterator >::type is_sorted_until ( const R &range, Pred p ) @@ -113,7 +113,7 @@ namespace boost { namespace algorithm { /// \param range The range to be tested. /// template - typename boost::range_iterator::type is_sorted_until ( const R &range ) + BOOST_CXX14_CONSTEXPR typename boost::range_iterator::type is_sorted_until ( const R &range ) { return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range )); } @@ -126,7 +126,7 @@ namespace boost { namespace algorithm { /// \param p A binary predicate that returns true if two elements are ordered. /// template - typename boost::lazy_disable_if_c< boost::is_same::value, boost::mpl::identity >::type + BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same::value, boost::mpl::identity >::type is_sorted ( const R &range, Pred p ) { return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p ); @@ -139,7 +139,7 @@ namespace boost { namespace algorithm { /// \param range The range to be tested. /// template - bool is_sorted ( const R &range ) + BOOST_CXX14_CONSTEXPR bool is_sorted ( const R &range ) { return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range )); } @@ -159,7 +159,7 @@ namespace boost { namespace algorithm { /// \note This function will return true for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_strictly_increasing instead. template - bool is_increasing ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR bool is_increasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; return boost::algorithm::is_sorted (first, last, std::less()); @@ -175,7 +175,7 @@ namespace boost { namespace algorithm { /// \note This function will return true for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_strictly_increasing instead. template - bool is_increasing ( const R &range ) + BOOST_CXX14_CONSTEXPR bool is_increasing ( const R &range ) { return is_increasing ( boost::begin ( range ), boost::end ( range )); } @@ -192,7 +192,7 @@ namespace boost { namespace algorithm { /// \note This function will return true for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_strictly_decreasing instead. template - bool is_decreasing ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR bool is_decreasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; return boost::algorithm::is_sorted (first, last, std::greater()); @@ -207,7 +207,7 @@ namespace boost { namespace algorithm { /// \note This function will return true for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_strictly_decreasing instead. template - bool is_decreasing ( const R &range ) + BOOST_CXX14_CONSTEXPR bool is_decreasing ( const R &range ) { return is_decreasing ( boost::begin ( range ), boost::end ( range )); } @@ -224,7 +224,7 @@ namespace boost { namespace algorithm { /// \note This function will return false for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_increasing instead. template - bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; return boost::algorithm::is_sorted (first, last, std::less_equal()); @@ -239,7 +239,7 @@ namespace boost { namespace algorithm { /// \note This function will return false for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_increasing instead. template - bool is_strictly_increasing ( const R &range ) + BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( const R &range ) { return is_strictly_increasing ( boost::begin ( range ), boost::end ( range )); } @@ -255,7 +255,7 @@ namespace boost { namespace algorithm { /// \note This function will return false for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_decreasing instead. template - bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ) + BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; return boost::algorithm::is_sorted (first, last, std::greater_equal()); @@ -270,7 +270,7 @@ namespace boost { namespace algorithm { /// \note This function will return false for sequences that contain items that compare /// equal. If that is not what you intended, you should use is_decreasing instead. template - bool is_strictly_decreasing ( const R &range ) + BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( const R &range ) { return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range )); } diff --git a/linx64/include/boost/algorithm/cxx11/none_of.hpp b/linx64/include/boost/algorithm/cxx11/none_of.hpp index ba13144f..e537c267 100644 --- a/linx64/include/boost/algorithm/cxx11/none_of.hpp +++ b/linx64/include/boost/algorithm/cxx11/none_of.hpp @@ -26,7 +26,7 @@ namespace boost { namespace algorithm { /// \param p A predicate for testing the elements of the sequence /// template -bool none_of ( InputIterator first, InputIterator last, Predicate p ) +BOOST_CXX14_CONSTEXPR bool none_of ( InputIterator first, InputIterator last, Predicate p ) { for ( ; first != last; ++first ) if ( p(*first)) @@ -42,7 +42,7 @@ bool none_of ( InputIterator first, InputIterator last, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -bool none_of ( const Range &r, Predicate p ) +BOOST_CXX14_CONSTEXPR bool none_of ( const Range &r, Predicate p ) { return boost::algorithm::none_of (boost::begin (r), boost::end (r), p ); } @@ -56,7 +56,7 @@ bool none_of ( const Range &r, Predicate p ) /// \param val A value to compare against /// template -bool none_of_equal ( InputIterator first, InputIterator last, const V &val ) +BOOST_CXX14_CONSTEXPR bool none_of_equal ( InputIterator first, InputIterator last, const V &val ) { for ( ; first != last; ++first ) if ( val == *first ) @@ -72,7 +72,7 @@ bool none_of_equal ( InputIterator first, InputIterator last, const V &val ) /// \param val A value to compare against /// template -bool none_of_equal ( const Range &r, const V & val ) +BOOST_CXX14_CONSTEXPR bool none_of_equal ( const Range &r, const V & val ) { return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val); } diff --git a/linx64/include/boost/algorithm/cxx11/one_of.hpp b/linx64/include/boost/algorithm/cxx11/one_of.hpp index b6e8c771..3b95180d 100644 --- a/linx64/include/boost/algorithm/cxx11/one_of.hpp +++ b/linx64/include/boost/algorithm/cxx11/one_of.hpp @@ -12,7 +12,6 @@ #ifndef BOOST_ALGORITHM_ONE_OF_HPP #define BOOST_ALGORITHM_ONE_OF_HPP -#include // for std::find and std::find_if #include #include @@ -28,12 +27,16 @@ namespace boost { namespace algorithm { /// \param p A predicate for testing the elements of the sequence /// template -bool one_of ( InputIterator first, InputIterator last, Predicate p ) +BOOST_CXX14_CONSTEXPR bool one_of ( InputIterator first, InputIterator last, Predicate p ) { - InputIterator i = std::find_if (first, last, p); - if (i == last) +// find_if + for (; first != last; ++first) + if (p(*first)) + break; + + if (first == last) return false; // Didn't occur at all - return boost::algorithm::none_of (++i, last, p); + return boost::algorithm::none_of (++first, last, p); } /// \fn one_of ( const Range &r, Predicate p ) @@ -43,7 +46,7 @@ bool one_of ( InputIterator first, InputIterator last, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -bool one_of ( const Range &r, Predicate p ) +BOOST_CXX14_CONSTEXPR bool one_of ( const Range &r, Predicate p ) { return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p ); } @@ -57,12 +60,16 @@ bool one_of ( const Range &r, Predicate p ) /// \param val A value to compare against /// template -bool one_of_equal ( InputIterator first, InputIterator last, const V &val ) +BOOST_CXX14_CONSTEXPR bool one_of_equal ( InputIterator first, InputIterator last, const V &val ) { - InputIterator i = std::find (first, last, val); // find first occurrence of 'val' - if (i == last) +// find + for (; first != last; ++first) + if (*first == val) + break; + + if (first == last) return false; // Didn't occur at all - return boost::algorithm::none_of_equal (++i, last, val); + return boost::algorithm::none_of_equal (++first, last, val); } /// \fn one_of_equal ( const Range &r, const V &val ) @@ -72,7 +79,7 @@ bool one_of_equal ( InputIterator first, InputIterator last, const V &val ) /// \param val A value to compare against /// template -bool one_of_equal ( const Range &r, const V &val ) +BOOST_CXX14_CONSTEXPR bool one_of_equal ( const Range &r, const V &val ) { return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val ); } diff --git a/linx64/include/boost/algorithm/cxx11/partition_copy.hpp b/linx64/include/boost/algorithm/cxx11/partition_copy.hpp index f347f212..635b1e73 100644 --- a/linx64/include/boost/algorithm/cxx11/partition_copy.hpp +++ b/linx64/include/boost/algorithm/cxx11/partition_copy.hpp @@ -14,6 +14,7 @@ #include // for std::pair +#include #include #include @@ -35,7 +36,7 @@ namespace boost { namespace algorithm { /// \note This function is part of the C++2011 standard library. template -std::pair +BOOST_CXX14_CONSTEXPR std::pair partition_copy ( InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p ) { @@ -57,7 +58,7 @@ partition_copy ( InputIterator first, InputIterator last, /// template -std::pair +BOOST_CXX14_CONSTEXPR std::pair partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p ) { diff --git a/linx64/include/boost/algorithm/cxx14/equal.hpp b/linx64/include/boost/algorithm/cxx14/equal.hpp index f1539f88..526aae99 100644 --- a/linx64/include/boost/algorithm/cxx14/equal.hpp +++ b/linx64/include/boost/algorithm/cxx14/equal.hpp @@ -12,8 +12,6 @@ #ifndef BOOST_ALGORITHM_EQUAL_HPP #define BOOST_ALGORITHM_EQUAL_HPP -#include // for std::equal -#include // for std::binary_function #include namespace boost { namespace algorithm { @@ -21,11 +19,12 @@ namespace boost { namespace algorithm { namespace detail { template - struct eq : public std::binary_function { - bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;} + struct eq { + BOOST_CONSTEXPR bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;} }; template + BOOST_CXX14_CONSTEXPR bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, std::random_access_iterator_tag, std::random_access_iterator_tag ) @@ -33,11 +32,16 @@ namespace detail { // Random-access iterators let is check the sizes in constant time if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 )) return false; - // If we know that the sequences are the same size, the original version is fine - return std::equal ( first1, last1, first2, pred ); + + // std::equal + for (; first1 != last1; ++first1, ++first2) + if (!pred(*first1, *first2)) + return false; + return true; } template + BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, std::input_iterator_tag, std::input_iterator_tag ) @@ -61,6 +65,7 @@ namespace detail { /// \param last2 One past the end of the second range. /// \param pred A predicate for comparing the elements of the ranges template +BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred ) { @@ -79,6 +84,7 @@ bool equal ( InputIterator1 first1, InputIterator1 last1, /// \param first2 The start of the second range. /// \param last2 One past the end of the second range. template +BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 ) { diff --git a/linx64/include/boost/algorithm/cxx14/mismatch.hpp b/linx64/include/boost/algorithm/cxx14/mismatch.hpp index c3de4182..46017190 100644 --- a/linx64/include/boost/algorithm/cxx14/mismatch.hpp +++ b/linx64/include/boost/algorithm/cxx14/mismatch.hpp @@ -2,7 +2,7 @@ Copyright (c) Marshall Clow 2008-2012. Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE10.txt or copy at http://www.boost.org/LICENSE10.txt) + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ /// \file mismatch.hpp @@ -13,6 +13,7 @@ #define BOOST_ALGORITHM_MISMATCH_HPP #include // for std::pair +#include namespace boost { namespace algorithm { @@ -27,7 +28,7 @@ namespace boost { namespace algorithm { /// \param last2 One past the end of the second range. /// \param pred A predicate for comparing the elements of the ranges template -std::pair mismatch ( +BOOST_CXX14_CONSTEXPR std::pair mismatch ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred ) @@ -47,7 +48,7 @@ std::pair mismatch ( /// \param first2 The start of the second range. /// \param last2 One past the end of the second range. template -std::pair mismatch ( +BOOST_CXX14_CONSTEXPR std::pair mismatch ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 ) { diff --git a/linx64/include/boost/algorithm/cxx17/exclusive_scan.hpp b/linx64/include/boost/algorithm/cxx17/exclusive_scan.hpp new file mode 100644 index 00000000..e4ec112d --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/exclusive_scan.hpp @@ -0,0 +1,52 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file exclusive_scan.hpp +/// \brief ??? +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_EXCLUSIVE_SCAN_HPP +#define BOOST_ALGORITHM_EXCLUSIVE_SCAN_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, BinaryOperation bOp) +{ + if (first != last) + { + T saved = init; + do + { + init = bOp(init, *first); + *result = saved; + saved = init; + ++result; + } while (++first != last); + } + return result; +} + +template +OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init) +{ + typedef typename std::iterator_traits::value_type VT; + return boost::algorithm::exclusive_scan(first, last, result, init, std::plus()); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_EXCLUSIVE_SCAN_HPP diff --git a/linx64/include/boost/algorithm/cxx17/for_each_n.hpp b/linx64/include/boost/algorithm/cxx17/for_each_n.hpp new file mode 100644 index 00000000..71f6cde3 --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/for_each_n.hpp @@ -0,0 +1,37 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file for_each_n.hpp +/// \brief Apply a functor to the elements of a sequence +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_FOR_EACH_N_HPP +#define BOOST_ALGORITHM_FOR_EACH_N_HPP + +#include // for std::pair + +namespace boost { namespace algorithm { + +/// \fn for_each_n(InputIterator first, Size n, Function f); +/// \return first + n +/// +/// \param first The start of the first range. +/// \param n One past the end of the first range. +/// \param f A functor to apply to the elements of the sequence +/// \note If f returns a result, the result is ignored. +template +InputIterator for_each_n(InputIterator first, Size n, Function f) +{ + for ( ; n > 0; --n, ++first ) + f(*first); + + return first; +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_FOR_EACH_N_HPP diff --git a/linx64/include/boost/algorithm/cxx17/inclusive_scan.hpp b/linx64/include/boost/algorithm/cxx17/inclusive_scan.hpp new file mode 100644 index 00000000..5c60c39d --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/inclusive_scan.hpp @@ -0,0 +1,60 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file transform_reduce.hpp +/// \brief Combine the (transformed) elements of a sequence (or two) into a single value. +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP +#define BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +OutputIterator inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation bOp, T init) +{ + for (; first != last; ++first, (void) ++result) { + init = bOp(init, *first); + *result = init; + } + return result; +} + + +template +OutputIterator inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation bOp) +{ + if (first != last) { + typename std::iterator_traits::value_type init = *first; + *result++ = init; + if (++first != last) + return boost::algorithm::inclusive_scan(first, last, result, bOp, init); + } + + return result; +} + +template +OutputIterator inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result) +{ + typedef typename std::iterator_traits::value_type VT; + return boost::algorithm::inclusive_scan(first, last, result, std::plus()); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP diff --git a/linx64/include/boost/algorithm/cxx17/reduce.hpp b/linx64/include/boost/algorithm/cxx17/reduce.hpp new file mode 100644 index 00000000..55424b6e --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/reduce.hpp @@ -0,0 +1,72 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file reduce.hpp +/// \brief Combine the elements of a sequence into a single value +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_REDUCE_HPP +#define BOOST_ALGORITHM_REDUCE_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +T reduce(InputIterator first, InputIterator last, T init, BinaryOperation bOp) +{ + ; + for (; first != last; ++first) + init = bOp(init, *first); + return init; +} + +template +T reduce(InputIterator first, InputIterator last, T init) +{ + typedef typename std::iterator_traits::value_type VT; + return boost::algorithm::reduce(first, last, init, std::plus()); +} + +template +typename std::iterator_traits::value_type +reduce(InputIterator first, InputIterator last) +{ + return boost::algorithm::reduce(first, last, + typename std::iterator_traits::value_type()); +} + +template +typename boost::range_value::type +reduce(const Range &r) +{ + return boost::algorithm::reduce(boost::begin(r), boost::end(r)); +} + +// Not sure that this won't be ambiguous (1) +template +T reduce(const Range &r, T init) +{ + return boost::algorithm::reduce(boost::begin (r), boost::end (r), init); +} + + +// Not sure that this won't be ambiguous (2) +template +T reduce(const Range &r, T init, BinaryOperation bOp) +{ + return boost::algorithm::reduce(boost::begin(r), boost::end(r), init, bOp); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_REDUCE_HPP diff --git a/linx64/include/boost/algorithm/cxx17/transform_exclusive_scan.hpp b/linx64/include/boost/algorithm/cxx17/transform_exclusive_scan.hpp new file mode 100644 index 00000000..dd3c9c83 --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/transform_exclusive_scan.hpp @@ -0,0 +1,46 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file transform_exclusive_scan.hpp +/// \brief ???? +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_TRANSFORM_EXCLUSIVE_SCAN_HPP +#define BOOST_ALGORITHM_TRANSFORM_EXCLUSIVE_SCAN_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, + BinaryOperation bOp, UnaryOperation uOp) +{ + if (first != last) + { + T saved = init; + do + { + init = bOp(init, uOp(*first)); + *result = saved; + saved = init; + ++result; + } while (++first != last); + } + return result; +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_TRANSFORM_EXCLUSIVE_SCAN_HPP diff --git a/linx64/include/boost/algorithm/cxx17/transform_inclusive_scan.hpp b/linx64/include/boost/algorithm/cxx17/transform_inclusive_scan.hpp new file mode 100644 index 00000000..1d119765 --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/transform_inclusive_scan.hpp @@ -0,0 +1,59 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file transform_reduce.hpp +/// \brief Combine the (transformed) elements of a sequence (or two) into a single value. +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP +#define BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation bOp, UnaryOperation uOp, + T init) +{ + for (; first != last; ++first, (void) ++result) { + init = bOp(init, uOp(*first)); + *result = init; + } + + return result; +} + +template +OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation bOp, UnaryOperation uOp) +{ + if (first != last) { + typename std::iterator_traits::value_type init = uOp(*first); + *result++ = init; + if (++first != last) + return boost::algorithm::transform_inclusive_scan + (first, last, result, bOp, uOp, init); + } + + return result; +} + + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP diff --git a/linx64/include/boost/algorithm/cxx17/transform_reduce.hpp b/linx64/include/boost/algorithm/cxx17/transform_reduce.hpp new file mode 100644 index 00000000..86963847 --- /dev/null +++ b/linx64/include/boost/algorithm/cxx17/transform_reduce.hpp @@ -0,0 +1,55 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file transform_reduce.hpp +/// \brief Combine the (transformed) elements of a sequence (or two) into a single value. +/// \author Marshall Clow + +#ifndef BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP +#define BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP + +#include // for std::plus +#include // for std::iterator_traits + +#include +#include +#include + +namespace boost { namespace algorithm { + +template +T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryOperation1 bOp1, BinaryOperation2 bOp2) +{ + for (; first1 != last1; ++first1, (void) ++first2) + init = bOp1(init, bOp2(*first1, *first2)); + return init; +} + +template +T transform_reduce(InputIterator first, InputIterator last, + T init, BinaryOperation bOp, UnaryOperation uOp) +{ + for (; first != last; ++first) + init = bOp(init, uOp(*first)); + return init; +} + +template +T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init) +{ + return boost::algorithm::transform_reduce(first1, last1, first2, init, + std::plus(), std::multiplies()); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP diff --git a/linx64/include/boost/algorithm/find_backward.hpp b/linx64/include/boost/algorithm/find_backward.hpp new file mode 100644 index 00000000..66901a14 --- /dev/null +++ b/linx64/include/boost/algorithm/find_backward.hpp @@ -0,0 +1,97 @@ +/* + Copyright (c) T. Zachary Laine 2018. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE10.txt or copy at http://www.boost.org/LICENSE10.txt) +*/ +#ifndef BOOST_ALGORITHM_FIND_BACKWARD_HPP +#define BOOST_ALGORITHM_FIND_BACKWARD_HPP + +#include +#include +#include + +#include + + +namespace boost { namespace algorithm { + +template +BOOST_CXX14_CONSTEXPR +BidiIter find_backward(BidiIter first, BidiIter last, const T & x) +{ + BidiIter it = last; + while (it != first) { + if (*--it == x) + return it; + } + return last; +} + +template +BOOST_CXX14_CONSTEXPR +typename boost::range_iterator::type find_backward(Range & range, const T & x) +{ + return ::boost::algorithm::find_backward(boost::begin(range), boost::end(range), x); +} + +template +BOOST_CXX14_CONSTEXPR +BidiIter find_not_backward(BidiIter first, BidiIter last, const T & x) +{ + BidiIter it = last; + while (it != first) { + if (*--it != x) + return it; + } + return last; +} + +template +BOOST_CXX14_CONSTEXPR +typename boost::range_iterator::type find_not_backward(Range & range, const T & x) +{ + return ::boost::algorithm::find_not_backward(boost::begin(range), boost::end(range), x); +} + +template +BOOST_CXX14_CONSTEXPR +BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p) +{ + BidiIter it = last; + while (it != first) { + if (p(*--it)) + return it; + } + return last; +} + +template +BOOST_CXX14_CONSTEXPR +typename boost::range_iterator::type find_if_backward(Range & range, Pred p) +{ + return ::boost::algorithm::find_if_backward(boost::begin(range), boost::end(range), p); +} + +template +BOOST_CXX14_CONSTEXPR +BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p) +{ + BidiIter it = last; + while (it != first) { + if (!p(*--it)) + return it; + } + return last; +} + +template +BOOST_CXX14_CONSTEXPR +typename boost::range_iterator::type find_if_not_backward(Range & range, Pred p) +{ + return ::boost::algorithm::find_if_not_backward(boost::begin(range), boost::end(range), p); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_FIND_BACKWARD_HPP diff --git a/linx64/include/boost/algorithm/find_not.hpp b/linx64/include/boost/algorithm/find_not.hpp new file mode 100644 index 00000000..ef4df00b --- /dev/null +++ b/linx64/include/boost/algorithm/find_not.hpp @@ -0,0 +1,39 @@ +/* + Copyright (c) T. Zachary Laine 2018. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE10.txt or copy at http://www.boost.org/LICENSE10.txt) +*/ +#ifndef BOOST_ALGORITHM_FIND_NOT_HPP +#define BOOST_ALGORITHM_FIND_NOT_HPP + +#include +#include +#include + +#include + + +namespace boost { namespace algorithm { + +template +BOOST_CXX14_CONSTEXPR +InputIter find_not(InputIter first, Sentinel last, const T & x) +{ + for (; first != last; ++first) { + if (*first != x) + break; + } + return first; +} + +template +BOOST_CXX14_CONSTEXPR +typename boost::range_iterator::type find_not(Range & r, const T & x) +{ + return ::boost::algorithm::find_not(boost::begin(r), boost::end(r), x); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_FIND_NOT_HPP diff --git a/linx64/include/boost/algorithm/hex.hpp b/linx64/include/boost/algorithm/hex.hpp index 739e89f2..b8335843 100644 --- a/linx64/include/boost/algorithm/hex.hpp +++ b/linx64/include/boost/algorithm/hex.hpp @@ -73,7 +73,7 @@ namespace detail { else if ( c >= 'A' && c <= 'F' ) retval = c - 'A' + 10; else if ( c >= 'a' && c <= 'f' ) retval = c - 'a' + 10; else BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c)); - return retval; + return static_cast(retval); } // My own iterator_traits class. diff --git a/linx64/include/boost/algorithm/is_palindrome.hpp b/linx64/include/boost/algorithm/is_palindrome.hpp index cc63e180..09881109 100644 --- a/linx64/include/boost/algorithm/is_palindrome.hpp +++ b/linx64/include/boost/algorithm/is_palindrome.hpp @@ -35,7 +35,7 @@ namespace boost { namespace algorithm { /// For other sequences function will return false. /// Complexity: O(N). template -bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predicate p ) +bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predicate p) { if(begin == end) { @@ -63,7 +63,7 @@ bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predi /// \return true if the entire sequence is palindrome /// /// \param begin The start of the input sequence -/// \param end One past the end of the input sequence +/// \param end One past the end of the input sequence /// /// \note This function will return true for empty sequences and for palindromes. /// For other sequences function will return false. @@ -71,26 +71,8 @@ bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predi template bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end) { - if(begin == end) - { - return true; - } - - --end; - while(begin != end) - { - if(!(*begin == *end)) - { - return false; - } - ++begin; - if(begin == end) - { - break; - } - --end; - } - return true; + return is_palindrome(begin, end, + std::equal_to::value_type> ()); } /// \fn is_palindrome ( const R& range ) @@ -122,7 +104,6 @@ bool is_palindrome(const R& range, Predicate p) return is_palindrome(boost::begin(range), boost::end(range), p); } - /// \fn is_palindrome ( const char* str ) /// \return true if the entire sequence is palindrome /// @@ -138,7 +119,6 @@ bool is_palindrome(const char* str) return is_palindrome(str, str + strlen(str)); } - /// \fn is_palindrome ( const char* str, Predicate p ) /// \return true if the entire sequence is palindrome /// @@ -155,7 +135,6 @@ bool is_palindrome(const char* str, Predicate p) return true; return is_palindrome(str, str + strlen(str), p); } - }} #endif // BOOST_ALGORITHM_IS_PALINDROME_HPP diff --git a/linx64/include/boost/algorithm/is_partitioned_until.hpp b/linx64/include/boost/algorithm/is_partitioned_until.hpp new file mode 100644 index 00000000..42683e1d --- /dev/null +++ b/linx64/include/boost/algorithm/is_partitioned_until.hpp @@ -0,0 +1,63 @@ +/* + Copyright (c) Alexander Zaitsev , 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +/// \file is_partitioned_until.hpp +/// \brief Tell if a sequence is partitioned +/// \author Alexander Zaitsev + +#ifndef BOOST_ALGORITHM_IS_PARTITIONED_UNTIL_HPP +#define BOOST_ALGORITHM_IS_PARTITIONED_UNTIL_HPP + +#include +#include + +namespace boost { namespace algorithm { + +/// \fn is_partitioned_until ( InputIterator first, InputIterator last, UnaryPredicate p ) +/// \brief Tests to see if a sequence is partitioned according to a predicate. +/// In other words, all the items in the sequence that satisfy the predicate are at the beginning of the sequence. +/// +/// \param first The start of the input sequence +/// \param last One past the end of the input sequence +/// \param p The predicate to test the values with +/// +/// \note Returns the first iterator 'it' in the sequence [first, last) for which is_partitioned(first, it, p) is false. +/// Returns last if the entire sequence is partitioned. +/// Complexity: O(N). +template +InputIterator is_partitioned_until ( InputIterator first, InputIterator last, UnaryPredicate p ) +{ +// Run through the part that satisfy the predicate + for ( ; first != last; ++first ) + if ( !p (*first)) + break; +// Now the part that does not satisfy the predicate + for ( ; first != last; ++first ) + if ( p (*first)) + return first; + return last; +} + +/// \fn is_partitioned_until ( const Range &r, UnaryPredicate p ) +/// \brief Tests to see if a sequence is partitioned according to a predicate. +/// In other words, all the items in the sequence that satisfy the predicate are at the beginning of the sequence. +/// +/// \param r The input range +/// \param p The predicate to test the values with +/// +/// \note Returns the first iterator 'it' in the sequence [first, last) for which is_partitioned(first, it, p) is false. +/// Returns last if the entire sequence is partitioned. +/// Complexity: O(N). +template +typename boost::range_iterator::type is_partitioned_until ( const Range &r, UnaryPredicate p ) +{ + return boost::algorithm::is_partitioned_until (boost::begin(r), boost::end(r), p); +} + +}} + +#endif // BOOST_ALGORITHM_IS_PARTITIONED_UNTIL_HPP diff --git a/linx64/include/boost/algorithm/searching/boyer_moore.hpp b/linx64/include/boost/algorithm/searching/boyer_moore.hpp index 65a809dd..192d4dec 100644 --- a/linx64/include/boost/algorithm/searching/boyer_moore.hpp +++ b/linx64/include/boost/algorithm/searching/boyer_moore.hpp @@ -152,8 +152,8 @@ Requirements: template - void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) { - const std::size_t count = std::distance ( pat_first, pat_last ); + void compute_bm_prefix ( Iter first, Iter last, Container &prefix ) { + const std::size_t count = std::distance ( first, last ); BOOST_ASSERT ( count > 0 ); BOOST_ASSERT ( prefix.size () == count ); @@ -161,26 +161,26 @@ Requirements: std::size_t k = 0; for ( std::size_t i = 1; i < count; ++i ) { BOOST_ASSERT ( k < count ); - while ( k > 0 && ( pat_first[k] != pat_first[i] )) { + while ( k > 0 && ( first[k] != first[i] )) { BOOST_ASSERT ( k < count ); k = prefix [ k - 1 ]; } - if ( pat_first[k] == pat_first[i] ) + if ( first[k] == first[i] ) k++; prefix [ i ] = k; } } - void build_suffix_table ( patIter pat_first, patIter pat_last ) { - const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last ); + void build_suffix_table ( patIter first, patIter last ) { + const std::size_t count = (std::size_t) std::distance ( first, last ); if ( count > 0 ) { // empty pattern std::vector::value_type> reversed(count); - (void) std::reverse_copy ( pat_first, pat_last, reversed.begin ()); + (void) std::reverse_copy ( first, last, reversed.begin ()); std::vector prefix (count); - compute_bm_prefix ( pat_first, pat_last, prefix ); + compute_bm_prefix ( first, last, prefix ); std::vector prefix_reversed (count); compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed ); diff --git a/linx64/include/boost/algorithm/searching/knuth_morris_pratt.hpp b/linx64/include/boost/algorithm/searching/knuth_morris_pratt.hpp index c890c9ca..5b5b64a7 100644 --- a/linx64/include/boost/algorithm/searching/knuth_morris_pratt.hpp +++ b/linx64/include/boost/algorithm/searching/knuth_morris_pratt.hpp @@ -155,9 +155,9 @@ namespace boost { namespace algorithm { void preKmp ( patIter first, patIter last ) { - const /*std::size_t*/ int count = std::distance ( first, last ); + const difference_type count = std::distance ( first, last ); - int i, j; + difference_type i, j; i = 0; j = skip_[0] = -1; @@ -177,7 +177,7 @@ namespace boost { namespace algorithm { void init_skip_table ( patIter first, patIter last ) { const difference_type count = std::distance ( first, last ); - int j; + difference_type j; skip_ [ 0 ] = -1; for ( int i = 1; i <= count; ++i ) { j = skip_ [ i - 1 ]; diff --git a/linx64/include/boost/algorithm/string/detail/case_conv.hpp b/linx64/include/boost/algorithm/string/detail/case_conv.hpp index 42621c74..233912ca 100644 --- a/linx64/include/boost/algorithm/string/detail/case_conv.hpp +++ b/linx64/include/boost/algorithm/string/detail/case_conv.hpp @@ -30,8 +30,10 @@ namespace boost { // a tolower functor template - struct to_lowerF : public std::unary_function + struct to_lowerF { + typedef CharT argument_type; + typedef CharT result_type; // Constructor to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {} @@ -50,8 +52,10 @@ namespace boost { // a toupper functor template - struct to_upperF : public std::unary_function + struct to_upperF { + typedef CharT argument_type; + typedef CharT result_type; // Constructor to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {} diff --git a/linx64/include/boost/algorithm/string/detail/find_iterator.hpp b/linx64/include/boost/algorithm/string/detail/find_iterator.hpp index 9b78a0f7..4f90a98f 100644 --- a/linx64/include/boost/algorithm/string/detail/find_iterator.hpp +++ b/linx64/include/boost/algorithm/string/detail/find_iterator.hpp @@ -40,7 +40,7 @@ namespace boost { // Protected construction/destruction // Default constructor - find_iterator_base() {}; + find_iterator_base() {} // Copy construction find_iterator_base( const find_iterator_base& Other ) : m_Finder(Other.m_Finder) {} diff --git a/linx64/include/boost/algorithm/string/detail/util.hpp b/linx64/include/boost/algorithm/string/detail/util.hpp index cf4a8b1c..7844b672 100644 --- a/linx64/include/boost/algorithm/string/detail/util.hpp +++ b/linx64/include/boost/algorithm/string/detail/util.hpp @@ -89,9 +89,10 @@ namespace boost { template< typename SeqT, typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > - struct copy_iterator_rangeF : - public std::unary_function< iterator_range, SeqT > + struct copy_iterator_rangeF { + typedef iterator_range argument_type; + typedef SeqT result_type; SeqT operator()( const iterator_range& Range ) const { return copy_range(Range); diff --git a/linx64/include/boost/algorithm/string/finder.hpp b/linx64/include/boost/algorithm/string/finder.hpp index 93f7ec30..61f6e415 100644 --- a/linx64/include/boost/algorithm/string/finder.hpp +++ b/linx64/include/boost/algorithm/string/finder.hpp @@ -43,7 +43,6 @@ namespace boost { The result is given as an \c iterator_range delimiting the match. \param Search A substring to be searched for. - \param Comp An element comparison predicate \return An instance of the \c first_finder object */ template @@ -84,7 +83,6 @@ namespace boost { The result is given as an \c iterator_range delimiting the match. \param Search A substring to be searched for. - \param Comp An element comparison predicate \return An instance of the \c last_finder object */ template @@ -124,7 +122,6 @@ namespace boost { \param Search A substring to be searched for. \param Nth An index of the match to be find - \param Comp An element comparison predicate \return An instance of the \c nth_finder object */ template @@ -230,7 +227,6 @@ namespace boost { \param Begin Beginning of the range \param End End of the range - \param Range The range. \return An instance of the \c range_finger object */ template< typename ForwardIteratorT > diff --git a/linx64/include/boost/align/aligned_allocator.hpp b/linx64/include/boost/align/aligned_allocator.hpp index 6d0f7889..4ec6b50c 100644 --- a/linx64/include/boost/align/aligned_allocator.hpp +++ b/linx64/include/boost/align/aligned_allocator.hpp @@ -28,8 +28,7 @@ namespace alignment { template class aligned_allocator { - BOOST_STATIC_ASSERT(detail:: - is_alignment_constant::value); + BOOST_STATIC_ASSERT(detail::is_alignment_constant::value); public: typedef T value_type; @@ -42,13 +41,6 @@ public: typedef T& reference; typedef const T& const_reference; -private: - enum { - min_align = detail::max_size::value>::value - }; - -public: template struct rebind { typedef aligned_allocator other; @@ -73,10 +65,14 @@ public: } pointer allocate(size_type size, const_void_pointer = 0) { + enum { + m = detail::max_size::value>::value + }; if (size == 0) { return 0; } - void* p = aligned_alloc(min_align, sizeof(T) * size); + void* p = boost::alignment::aligned_alloc(m, sizeof(T) * size); if (!p) { boost::throw_exception(std::bad_alloc()); } @@ -124,8 +120,7 @@ public: template class aligned_allocator { - BOOST_STATIC_ASSERT(detail:: - is_alignment_constant::value); + BOOST_STATIC_ASSERT(detail::is_alignment_constant::value); public: typedef void value_type; diff --git a/linx64/include/boost/align/aligned_allocator_adaptor.hpp b/linx64/include/boost/align/aligned_allocator_adaptor.hpp index 8905c215..91265168 100644 --- a/linx64/include/boost/align/aligned_allocator_adaptor.hpp +++ b/linx64/include/boost/align/aligned_allocator_adaptor.hpp @@ -8,13 +8,13 @@ Distributed under the Boost Software License, Version 1.0. #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP -#include #include #include #include #include #include #include +#include #include #include @@ -32,56 +32,45 @@ namespace alignment { template class aligned_allocator_adaptor : public Allocator { - BOOST_STATIC_ASSERT(detail:: - is_alignment_constant::value); + BOOST_STATIC_ASSERT(detail::is_alignment_constant::value); #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef std::allocator_traits traits; - - typedef typename traits:: - template rebind_alloc char_alloc; - - typedef typename traits:: - template rebind_traits char_traits; - + typedef typename traits::template rebind_alloc char_alloc; + typedef typename traits::template rebind_traits char_traits; typedef typename char_traits::pointer char_ptr; #else - typedef typename Allocator:: - template rebind::other char_alloc; - + typedef typename Allocator::template rebind::other char_alloc; typedef typename char_alloc::pointer char_ptr; #endif public: -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename traits::value_type value_type; - typedef typename traits::size_type size_type; -#else typedef typename Allocator::value_type value_type; - typedef typename Allocator::size_type size_type; -#endif - typedef value_type* pointer; typedef const value_type* const_pointer; typedef void* void_pointer; typedef const void* const_void_pointer; + typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; private: - enum { - min_align = detail::max_size::value>::value + template + struct min_align { + enum { + value = detail::max_size::value>::value + }; }; public: template struct rebind { #if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef aligned_allocator_adaptor, Alignment> other; + typedef aligned_allocator_adaptor, Alignment> other; #else - typedef aligned_allocator_adaptor::other, Alignment> other; + typedef aligned_allocator_adaptor::other, Alignment> other; #endif }; @@ -116,20 +105,25 @@ public: } pointer allocate(size_type size) { + enum { + m = min_align::value + }; std::size_t s = size * sizeof(value_type); - std::size_t n = s + min_align - 1; + std::size_t n = s + m - 1; char_alloc a(base()); char_ptr p = a.allocate(sizeof p + n); - void* r = detail::addressof(*p) + sizeof p; - (void)align(min_align, s, r, n); - ::new(static_cast(static_cast(r) - - 1)) char_ptr(p); + void* r = boost::to_address(p) + sizeof p; + (void)boost::alignment::align(m, s, r, n); + ::new(static_cast(static_cast(r) - 1)) char_ptr(p); return static_cast(r); } pointer allocate(size_type size, const_void_pointer hint) { + enum { + m = min_align::value + }; std::size_t s = size * sizeof(value_type); - std::size_t n = s + min_align - 1; + std::size_t n = s + m - 1; char_ptr h = char_ptr(); if (hint) { h = *(static_cast(hint) - 1); @@ -140,20 +134,21 @@ public: #else char_ptr p = a.allocate(sizeof p + n, h); #endif - void* r = detail::addressof(*p) + sizeof p; - (void)align(min_align, s, r, n); - ::new(static_cast(static_cast(r) - - 1)) char_ptr(p); + void* r = boost::to_address(p) + sizeof p; + (void)boost::alignment::align(m, s, r, n); + ::new(static_cast(static_cast(r) - 1)) char_ptr(p); return static_cast(r); } void deallocate(pointer ptr, size_type size) { + enum { + m = min_align::value + }; char_ptr* p = reinterpret_cast(ptr) - 1; char_ptr r = *p; p->~char_ptr(); char_alloc a(base()); - a.deallocate(r, sizeof r + size * sizeof(value_type) + - min_align - 1); + a.deallocate(r, sizeof r + size * sizeof(value_type) + m - 1); } }; diff --git a/linx64/include/boost/align/detail/align.hpp b/linx64/include/boost/align/detail/align.hpp index a58dcea7..905940ad 100644 --- a/linx64/include/boost/align/detail/align.hpp +++ b/linx64/include/boost/align/detail/align.hpp @@ -20,8 +20,8 @@ align(std::size_t alignment, std::size_t size, void*& ptr, { BOOST_ASSERT(detail::is_alignment(alignment)); if (size <= space) { - char* p = reinterpret_cast((reinterpret_cast(ptr) + alignment - 1) & ~(alignment - 1)); + char* p = reinterpret_cast(~(alignment - 1) & + (reinterpret_cast(ptr) + alignment - 1)); std::size_t n = space - (p - static_cast(ptr)); if (size <= n) { ptr = p; diff --git a/linx64/include/boost/align/detail/align_down.hpp b/linx64/include/boost/align/detail/align_down.hpp index 9a8c358c..de3c80d0 100644 --- a/linx64/include/boost/align/detail/align_down.hpp +++ b/linx64/include/boost/align/detail/align_down.hpp @@ -18,8 +18,8 @@ inline void* align_down(void* ptr, std::size_t alignment) BOOST_NOEXCEPT { BOOST_ASSERT(detail::is_alignment(alignment)); - return reinterpret_cast(reinterpret_cast(ptr) & ~(alignment - 1)); + return reinterpret_cast(~(alignment - 1) & + reinterpret_cast(ptr)); } } /* alignment */ diff --git a/linx64/include/boost/align/detail/align_up.hpp b/linx64/include/boost/align/detail/align_up.hpp index 86686da6..ac11f896 100644 --- a/linx64/include/boost/align/detail/align_up.hpp +++ b/linx64/include/boost/align/detail/align_up.hpp @@ -18,8 +18,8 @@ inline void* align_up(void* ptr, std::size_t alignment) BOOST_NOEXCEPT { BOOST_ASSERT(detail::is_alignment(alignment)); - return reinterpret_cast((reinterpret_cast(ptr) + alignment - 1) & ~(alignment - 1)); + return reinterpret_cast(~(alignment - 1) & + (reinterpret_cast(ptr) + alignment - 1)); } } /* alignment */ diff --git a/linx64/include/boost/align/detail/aligned_alloc.hpp b/linx64/include/boost/align/detail/aligned_alloc.hpp index 69da1965..d27a5499 100644 --- a/linx64/include/boost/align/detail/aligned_alloc.hpp +++ b/linx64/include/boost/align/detail/aligned_alloc.hpp @@ -31,7 +31,7 @@ aligned_alloc(std::size_t alignment, std::size_t size) BOOST_NOEXCEPT void* p = std::malloc(sizeof(void*) + n); if (p) { void* r = static_cast(p) + sizeof(void*); - (void)align(alignment, size, r, n); + (void)boost::alignment::align(alignment, size, r, n); *(static_cast(r) - 1) = p; p = r; } diff --git a/linx64/include/boost/align/detail/alignment_of_msvc.hpp b/linx64/include/boost/align/detail/alignment_of_msvc.hpp index 1526c7c2..440b840d 100644 --- a/linx64/include/boost/align/detail/alignment_of_msvc.hpp +++ b/linx64/include/boost/align/detail/alignment_of_msvc.hpp @@ -23,8 +23,7 @@ struct offset_value { template struct alignment_of - : min_size) - (sizeof(T) << 1)> { }; + : min_size) - (sizeof(T) << 1)> { }; } /* detail */ } /* alignment */ diff --git a/linx64/include/boost/align/detail/is_alignment.hpp b/linx64/include/boost/align/detail/is_alignment.hpp index 8bedba19..542fbe46 100644 --- a/linx64/include/boost/align/detail/is_alignment.hpp +++ b/linx64/include/boost/align/detail/is_alignment.hpp @@ -4,7 +4,6 @@ Copyright 2014 Glen Joseph Fernandes Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) - */ #ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP #define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP diff --git a/linx64/include/boost/any.hpp b/linx64/include/boost/any.hpp index 9f6b3132..f161b3ff 100644 --- a/linx64/include/boost/any.hpp +++ b/linx64/include/boost/any.hpp @@ -12,7 +12,7 @@ // with features contributed and bugs found by // Antony Polukhin, Ed Brey, Mark Rodgers, // Peter Dimov, and James Curran -// when: July 2001, April 2013 - May 2013 +// when: July 2001, April 2013 - 2019 #include @@ -30,7 +30,7 @@ #include #include #include -#include +#include namespace boost { @@ -109,7 +109,7 @@ namespace boost return *this; } - // move assignement + // move assignment any & operator=(any&& rhs) BOOST_NOEXCEPT { rhs.swap(*this); @@ -149,7 +149,7 @@ namespace boost public: // types (public so any_cast can be non-friend) #endif - class placeholder + class BOOST_SYMBOL_VISIBLE placeholder { public: // structors @@ -271,8 +271,8 @@ namespace boost // `ValueType` is not a reference. Example: // `static_cast(*result);` // which is equal to `std::string(*result);` - typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< - boost::is_reference, + typedef BOOST_DEDUCED_TYPENAME boost::conditional< + boost::is_reference::value, ValueType, BOOST_DEDUCED_TYPENAME boost::add_reference::type >::type ref_type; @@ -329,6 +329,7 @@ namespace boost } // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// Copyright Antony Polukhin, 2013-2019. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at diff --git a/linx64/include/boost/archive/basic_archive.hpp b/linx64/include/boost/archive/basic_archive.hpp index ce7ac99a..9283974f 100644 --- a/linx64/include/boost/archive/basic_archive.hpp +++ b/linx64/include/boost/archive/basic_archive.hpp @@ -127,11 +127,11 @@ public: } // used for text output - operator int () const { + operator base_type () const { return t; } // used for text input - operator int_least16_t &() { + operator base_type &() { return t; } bool operator==(const class_id_type & rhs) const { @@ -151,7 +151,10 @@ private: public: object_id_type(): t(0) {}; // note: presumes that size_t >= unsigned int. - explicit object_id_type(const std::size_t & t_) : t(t_){ + // use explicit cast to silence useless warning + explicit object_id_type(const std::size_t & t_) : t(static_cast(t_)){ + // make quadriple sure that we haven't lost any real integer + // precision BOOST_ASSERT(t_ <= boost::integer_traits::const_max); } object_id_type(const object_id_type & t_) : @@ -162,11 +165,11 @@ public: return *this; } // used for text output - operator uint_least32_t () const { + operator base_type () const { return t; } // used for text input - operator uint_least32_t & () { + operator base_type & () { return t; } bool operator==(const object_id_type & rhs) const { diff --git a/linx64/include/boost/archive/basic_binary_iarchive.hpp b/linx64/include/boost/archive/basic_binary_iarchive.hpp index c0cc655c..c85ead86 100644 --- a/linx64/include/boost/archive/basic_binary_iarchive.hpp +++ b/linx64/include/boost/archive/basic_binary_iarchive.hpp @@ -102,17 +102,29 @@ protected: } void load_override(class_id_type & t){ library_version_type lvt = this->get_library_version(); + /* + * library versions: + * boost 1.39 -> 5 + * boost 1.43 -> 7 + * boost 1.47 -> 9 + * + * + * 1) in boost 1.43 and inferior, class_id_type is always a 16bit value, with no check on the library version + * --> this means all archives with version v <= 7 are written with a 16bit class_id_type + * 2) in boost 1.44 this load_override has disappeared (and thus boost 1.44 is not backward compatible at all !!) + * 3) recent boosts reintroduced load_override with a test on the version : + * - v > 7 : this->detail_common_iarchive::load_override(t, version) + * - v > 6 : 16bit + * - other : 32bit + * --> which is obviously incorrect, see point 1 + * + * the fix here decodes class_id_type on 16bit for all v <= 7, which seems to be the correct behaviour ... + */ if(boost::archive::library_version_type(7) < lvt){ this->detail_common_iarchive::load_override(t); } - else - if(boost::archive::library_version_type(6) < lvt){ - int_least16_t x=0; - * this->This() >> x; - t = boost::archive::class_id_type(x); - } else{ - int x=0; + int_least16_t x=0; * this->This() >> x; t = boost::archive::class_id_type(x); } diff --git a/linx64/include/boost/archive/basic_text_iarchive.hpp b/linx64/include/boost/archive/basic_text_iarchive.hpp index 583041d8..48a646cc 100644 --- a/linx64/include/boost/archive/basic_text_iarchive.hpp +++ b/linx64/include/boost/archive/basic_text_iarchive.hpp @@ -21,7 +21,7 @@ // // note the fact that on libraries without wide characters, ostream is // is not a specialization of basic_ostream which in fact is not defined -// in such cases. So we can't use basic_ostream but rather +// in such cases. So we can't use basic_istream but rather // use two template parameters #include diff --git a/linx64/include/boost/archive/codecvt_null.hpp b/linx64/include/boost/archive/codecvt_null.hpp index 9cc9e572..3b39c8ed 100644 --- a/linx64/include/boost/archive/codecvt_null.hpp +++ b/linx64/include/boost/archive/codecvt_null.hpp @@ -18,8 +18,11 @@ #include #include // NULL, size_t +#ifndef BOOST_NO_CWCHAR #include // for mbstate_t +#endif #include +#include #include #include // must be the last header @@ -60,9 +63,10 @@ public: }; template<> -class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt +class BOOST_WARCHIVE_DECL codecvt_null : + public std::codecvt { - virtual BOOST_WARCHIVE_DECL std::codecvt_base::result + virtual std::codecvt_base::result do_out( std::mbstate_t & state, const wchar_t * first1, @@ -72,7 +76,7 @@ class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt(no_locale_manage) {} - virtual ~codecvt_null(){}; + //virtual ~codecvt_null(){}; }; } // namespace archive diff --git a/linx64/include/boost/archive/detail/common_iarchive.hpp b/linx64/include/boost/archive/detail/common_iarchive.hpp index 82304f1e..4176a8a5 100644 --- a/linx64/include/boost/archive/detail/common_iarchive.hpp +++ b/linx64/include/boost/archive/detail/common_iarchive.hpp @@ -35,11 +35,12 @@ class extended_type_info; // note: referred to as Curiously Recurring Template Patter (CRTP) template -class BOOST_SYMBOL_VISIBLE common_iarchive : +class BOOST_SYMBOL_VISIBLE common_iarchive : public basic_iarchive, public interface_iarchive { friend class interface_iarchive; + friend class basic_iarchive; private: virtual void vload(version_type & t){ * this->This() >> t; diff --git a/linx64/include/boost/archive/detail/common_oarchive.hpp b/linx64/include/boost/archive/detail/common_oarchive.hpp index ee42bbe5..f7428637 100644 --- a/linx64/include/boost/archive/detail/common_oarchive.hpp +++ b/linx64/include/boost/archive/detail/common_oarchive.hpp @@ -38,6 +38,7 @@ class BOOST_SYMBOL_VISIBLE common_oarchive : public interface_oarchive { friend class interface_oarchive; + friend class basic_oarchive; private: virtual void vsave(const version_type t){ * this->This() << t; diff --git a/linx64/include/boost/archive/detail/iserializer.hpp b/linx64/include/boost/archive/detail/iserializer.hpp index 6e02eec7..98cd6a17 100644 --- a/linx64/include/boost/archive/detail/iserializer.hpp +++ b/linx64/include/boost/archive/detail/iserializer.hpp @@ -57,11 +57,10 @@ namespace std{ #include -#ifndef BOOST_MSVC - #define DONT_USE_HAS_NEW_OPERATOR ( \ - BOOST_WORKAROUND(__IBMCPP__, < 1210) \ - || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ - ) +#if !defined(BOOST_MSVC) && \ + (BOOST_WORKAROUND(__IBMCPP__, < 1210) || \ + defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590)) + #define DONT_USE_HAS_NEW_OPERATOR 1 #else #define DONT_USE_HAS_NEW_OPERATOR 0 #endif @@ -90,6 +89,8 @@ namespace std{ #include #include +#include + namespace boost { namespace serialization { @@ -122,8 +123,7 @@ private: virtual void destroy(/*const*/ void *address) const { boost::serialization::access::destroy(static_cast(address)); } -protected: - // protected constructor since it's always created by singleton +public: explicit iserializer() : basic_iserializer( boost::serialization::singleton< @@ -132,7 +132,6 @@ protected: >::get_const_instance() ) {} -public: virtual BOOST_DLLEXPORT void load_object_data( basic_iarchive & ar, void *x, @@ -234,7 +233,7 @@ struct heap_allocation { // that the class might have class specific new with NO // class specific delete at all. Patches (compatible with // C++03) welcome! - delete t; + (operator delete)(t); } }; struct doesnt_have_new_operator { @@ -243,7 +242,7 @@ struct heap_allocation { } static void invoke_delete(T * t) { // Note: I'm reliance upon automatic conversion from T * to void * here - delete t; + (operator delete)(t); } }; static T * invoke_new() { @@ -306,7 +305,7 @@ private: void * x, const unsigned int file_version ) const BOOST_USED; -protected: +public: // this should alway be a singleton so make the constructor protected pointer_iserializer(); ~pointer_iserializer(); @@ -406,7 +405,7 @@ struct load_non_pointer_type { struct load_standard { template static void invoke(Archive &ar, const T & t){ - void * x = & const_cast(t); + void * x = boost::addressof(const_cast(t)); ar.load_object( x, boost::serialization::singleton< @@ -484,7 +483,7 @@ struct load_pointer_type { }; template - static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ + static const basic_pointer_iserializer * register_type(Archive &ar, const T* const /*t*/){ // there should never be any need to load an abstract polymorphic // class pointer. Inhibiting code generation for this // permits abstract base classes to be used - note: exception @@ -523,7 +522,7 @@ struct load_pointer_type { } template - static void check_load(T & /* t */){ + static void check_load(T * const /* t */){ check_pointer_level< T >(); check_pointer_tracking< T >(); } @@ -537,8 +536,8 @@ struct load_pointer_type { template static void invoke(Archive & ar, Tptr & t){ - check_load(*t); - const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); + check_load(t); + const basic_pointer_iserializer * bpis_ptr = register_type(ar, t); const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( // note major hack here !!! // I tried every way to convert Tptr &t (where Tptr might @@ -605,7 +604,7 @@ template inline void load(Archive & ar, T &t){ // if this assertion trips. It means we're trying to load a // const object with a compiler that doesn't have correct - // funtion template ordering. On other compilers, this is + // function template ordering. On other compilers, this is // handled below. detail::check_const_loading< T >(); typedef diff --git a/linx64/include/boost/archive/detail/oserializer.hpp b/linx64/include/boost/archive/detail/oserializer.hpp index c120ec55..612e1f2c 100644 --- a/linx64/include/boost/archive/detail/oserializer.hpp +++ b/linx64/include/boost/archive/detail/oserializer.hpp @@ -26,6 +26,7 @@ #include // NULL #include + #include #include @@ -68,6 +69,8 @@ #include #include +#include + namespace boost { namespace serialization { @@ -253,7 +256,7 @@ struct save_non_pointer_type { template static void invoke(Archive &ar, const T & t){ ar.save_object( - & t, + boost::addressof(t), boost::serialization::singleton< oserializer >::get_const_instance() @@ -261,6 +264,8 @@ struct save_non_pointer_type { } }; + + // adds class information to the archive. This includes // serialization level and class version struct save_conditional { @@ -338,7 +343,7 @@ struct save_pointer_type { }; template - static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){ + static const basic_pointer_oserializer * register_type(Archive &ar, T* const /*t*/){ // there should never be any need to save an abstract polymorphic // class pointer. Inhibiting code generation for this // permits abstract base classes to be used - note: exception @@ -405,7 +410,7 @@ struct save_pointer_type { // if its not a pointer to a more derived type const void *vp = static_cast(&t); if(*this_type == *true_type){ - const basic_pointer_oserializer * bpos = register_type(ar, t); + const basic_pointer_oserializer * bpos = register_type(ar, &t); ar.save_pointer(vp, bpos); return; } @@ -464,7 +469,7 @@ struct save_pointer_type { template static void invoke(Archive &ar, const TPtr t){ - register_type(ar, * t); + register_type(ar, t); if(NULL == t){ basic_oarchive & boa = boost::serialization::smart_cast_reference(ar); diff --git a/linx64/include/boost/archive/detail/utf8_codecvt_facet.hpp b/linx64/include/boost/archive/detail/utf8_codecvt_facet.hpp index a40104ab..00b2b419 100644 --- a/linx64/include/boost/archive/detail/utf8_codecvt_facet.hpp +++ b/linx64/include/boost/archive/detail/utf8_codecvt_facet.hpp @@ -13,27 +13,17 @@ #error "wide char i/o not supported on this platform" #endif -// std::codecvt_utf8 doesn't seem to work for any versions of msvc +// use boost's utf8 codecvt facet +#include +#define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { +#define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL +#define BOOST_UTF8_END_NAMESPACE }}} -#if defined(_MSC_VER) || defined(BOOST_NO_CXX11_HDR_CODECVT) - // use boost's utf8 codecvt facet - #include - #define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { namespace archive { namespace detail { - #define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL - #define BOOST_UTF8_END_NAMESPACE }}} +#include - #include - - #undef BOOST_UTF8_END_NAMESPACE - #undef BOOST_UTF8_DECL - #undef BOOST_UTF8_BEGIN_NAMESPACE -#else - // use the standard vendor supplied facet - #include - namespace boost { namespace archive { namespace detail { - typedef std::codecvt_utf8 utf8_codecvt_facet; - } } } -#endif +#undef BOOST_UTF8_END_NAMESPACE +#undef BOOST_UTF8_DECL +#undef BOOST_UTF8_BEGIN_NAMESPACE #endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP diff --git a/linx64/include/boost/archive/impl/archive_serializer_map.ipp b/linx64/include/boost/archive/impl/archive_serializer_map.ipp index 8dabf0d0..98e058dd 100644 --- a/linx64/include/boost/archive/impl/archive_serializer_map.ipp +++ b/linx64/include/boost/archive/impl/archive_serializer_map.ipp @@ -47,6 +47,10 @@ archive_serializer_map::insert(const basic_serializer * bs){ template BOOST_ARCHIVE_OR_WARCHIVE_DECL void archive_serializer_map::erase(const basic_serializer * bs){ + // note: previously this conditional was a runtime assertion with + // BOOST_ASSERT. We've changed it because we've discovered that at + // least one platform is not guaranteed to destroy singletons in + // reverse order of distruction. if(boost::serialization::singleton< extra_detail::map >::is_destroyed()) diff --git a/linx64/include/boost/archive/impl/basic_binary_iprimitive.ipp b/linx64/include/boost/archive/impl/basic_binary_iprimitive.ipp index 7082b003..e2d05108 100644 --- a/linx64/include/boost/archive/impl/basic_binary_iprimitive.ipp +++ b/linx64/include/boost/archive/impl/basic_binary_iprimitive.ipp @@ -84,6 +84,8 @@ basic_binary_iprimitive::init() ); } +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(wchar_t * ws) @@ -93,6 +95,8 @@ basic_binary_iprimitive::load(wchar_t * ws) load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); ws[l] = L'\0'; } +#endif +#endif template BOOST_ARCHIVE_OR_WARCHIVE_DECL void @@ -110,7 +114,6 @@ basic_binary_iprimitive::load(std::string & s) load_binary(&(*s.begin()), l); } -#ifndef BOOST_NO_CWCHAR template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_iprimitive::load(char * s) @@ -120,7 +123,6 @@ basic_binary_iprimitive::load(char * s) load_binary(s, l); s[l] = '\0'; } -#endif #ifndef BOOST_NO_STD_WSTRING template diff --git a/linx64/include/boost/archive/impl/basic_binary_oprimitive.ipp b/linx64/include/boost/archive/impl/basic_binary_oprimitive.ipp index 130831e4..7b042173 100644 --- a/linx64/include/boost/archive/impl/basic_binary_oprimitive.ipp +++ b/linx64/include/boost/archive/impl/basic_binary_oprimitive.ipp @@ -71,6 +71,7 @@ basic_binary_oprimitive::save(const std::string &s) } #ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T template BOOST_ARCHIVE_OR_WARCHIVE_DECL void basic_binary_oprimitive::save(const wchar_t * ws) @@ -91,6 +92,7 @@ basic_binary_oprimitive::save(const std::wstring &ws) save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); } #endif +#endif // BOOST_NO_CWCHAR template BOOST_ARCHIVE_OR_WARCHIVE_DECL diff --git a/linx64/include/boost/archive/impl/basic_xml_grammar.hpp b/linx64/include/boost/archive/impl/basic_xml_grammar.hpp index c8a52080..cc88d4fd 100644 --- a/linx64/include/boost/archive/impl/basic_xml_grammar.hpp +++ b/linx64/include/boost/archive/impl/basic_xml_grammar.hpp @@ -64,7 +64,7 @@ namespace archive { // XML grammar parsing template -class basic_xml_grammar { +class BOOST_SYMBOL_VISIBLE basic_xml_grammar { public: // The following is not necessary according to DR45, but at least // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. @@ -135,7 +135,7 @@ private: Sch, NameChar; - BOOST_SYMBOL_VISIBLE void init_chset(); + void init_chset(); bool my_parse( IStream & is, @@ -143,7 +143,7 @@ private: const CharType delimiter = L'>' ) const ; public: - BOOST_SYMBOL_VISIBLE struct return_values { + struct return_values { StringType object_name; StringType contents; //class_id_type class_id; @@ -159,12 +159,12 @@ public: tracking_level(false) {} } rv; - BOOST_SYMBOL_VISIBLE bool parse_start_tag(IStream & is) /*const*/; - BOOST_SYMBOL_VISIBLE bool parse_end_tag(IStream & is) const; - BOOST_SYMBOL_VISIBLE bool parse_string(IStream & is, StringType & s) /*const*/; - BOOST_SYMBOL_VISIBLE void init(IStream & is); - BOOST_SYMBOL_VISIBLE bool windup(IStream & is); - BOOST_SYMBOL_VISIBLE basic_xml_grammar(); + bool parse_start_tag(IStream & is) /*const*/; + bool parse_end_tag(IStream & is) const; + bool parse_string(IStream & is, StringType & s) /*const*/; + void init(IStream & is); + bool windup(IStream & is); + basic_xml_grammar(); }; } // namespace archive diff --git a/linx64/include/boost/archive/impl/text_wiarchive_impl.ipp b/linx64/include/boost/archive/impl/text_wiarchive_impl.ipp index 12af2b9f..e85625ac 100644 --- a/linx64/include/boost/archive/impl/text_wiarchive_impl.ipp +++ b/linx64/include/boost/archive/impl/text_wiarchive_impl.ipp @@ -56,7 +56,7 @@ text_wiarchive_impl::load(std::string &s) s.resize(0); s.reserve(size); while(size-- > 0){ - int x = is.narrow(is.get(), '\0'); + char x = is.narrow(is.get(), '\0'); s += x; } } diff --git a/linx64/include/boost/archive/impl/xml_wiarchive_impl.ipp b/linx64/include/boost/archive/impl/xml_wiarchive_impl.ipp index ee66c126..f572b762 100644 --- a/linx64/include/boost/archive/impl/xml_wiarchive_impl.ipp +++ b/linx64/include/boost/archive/impl/xml_wiarchive_impl.ipp @@ -161,13 +161,13 @@ xml_wiarchive_impl::xml_wiarchive_impl( gimpl(new xml_wgrammar()) { if(0 == (flags & no_codecvt)){ - std::locale l = std::locale( + archive_locale = std::locale( is_.getloc(), new boost::archive::detail::utf8_codecvt_facet ); // libstdc++ crashes without this is_.sync(); - is_.imbue(l); + is_.imbue(archive_locale); } if(0 == (flags & no_header)) init(); diff --git a/linx64/include/boost/archive/impl/xml_woarchive_impl.ipp b/linx64/include/boost/archive/impl/xml_woarchive_impl.ipp index 58f92c9d..630898b8 100644 --- a/linx64/include/boost/archive/impl/xml_woarchive_impl.ipp +++ b/linx64/include/boost/archive/impl/xml_woarchive_impl.ipp @@ -17,7 +17,9 @@ #include // strlen #include // mbtowc +#ifndef BOOST_NO_CWCHAR #include // wcslen +#endif #include #if defined(BOOST_NO_STDC_NAMESPACE) @@ -101,7 +103,6 @@ xml_woarchive_impl::save(const char * s){ template BOOST_WARCHIVE_DECL void xml_woarchive_impl::save(const wchar_t * ws){ - os << ws; typedef iterators::xml_escape xmbtows; std::copy( xmbtows(ws), @@ -124,12 +125,12 @@ xml_woarchive_impl::xml_woarchive_impl( basic_xml_oarchive(flags) { if(0 == (flags & no_codecvt)){ - std::locale l = std::locale( + archive_locale = std::locale( os_.getloc(), new boost::archive::detail::utf8_codecvt_facet ); os_.flush(); - os_.imbue(l); + os_.imbue(archive_locale); } if(0 == (flags & no_header)) this->init(); @@ -141,7 +142,7 @@ xml_woarchive_impl::~xml_woarchive_impl(){ if(std::uncaught_exception()) return; if(0 == (this->get_flags() & no_header)){ - save(L"\n"); + os << L""; } } diff --git a/linx64/include/boost/archive/iterators/base64_from_binary.hpp b/linx64/include/boost/archive/iterators/base64_from_binary.hpp index 00c4e10c..ee849944 100644 --- a/linx64/include/boost/archive/iterators/base64_from_binary.hpp +++ b/linx64/include/boost/archive/iterators/base64_from_binary.hpp @@ -41,7 +41,7 @@ template struct from_6_bit { typedef CharType result_type; CharType operator()(CharType t) const{ - const char * lookup_table = + static const char * lookup_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" diff --git a/linx64/include/boost/archive/iterators/binary_from_base64.hpp b/linx64/include/boost/archive/iterators/binary_from_base64.hpp index 2eb78282..89b8f889 100644 --- a/linx64/include/boost/archive/iterators/binary_from_base64.hpp +++ b/linx64/include/boost/archive/iterators/binary_from_base64.hpp @@ -37,7 +37,7 @@ template struct to_6_bit { typedef CharType result_type; CharType operator()(CharType t) const{ - const signed char lookup_table[] = { + static const signed char lookup_table[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, diff --git a/linx64/include/boost/archive/iterators/escape.hpp b/linx64/include/boost/archive/iterators/escape.hpp index a1fee914..103b31e0 100644 --- a/linx64/include/boost/archive/iterators/escape.hpp +++ b/linx64/include/boost/archive/iterators/escape.hpp @@ -102,7 +102,8 @@ public: super_t(base), m_bnext(NULL), m_bend(NULL), - m_full(false) + m_full(false), + m_current_value(0) { } }; diff --git a/linx64/include/boost/archive/iterators/istream_iterator.hpp b/linx64/include/boost/archive/iterators/istream_iterator.hpp index 9a1d555c..a187f605 100644 --- a/linx64/include/boost/archive/iterators/istream_iterator.hpp +++ b/linx64/include/boost/archive/iterators/istream_iterator.hpp @@ -56,7 +56,7 @@ class istream_iterator : //Access the value referred to Elem dereference() const { - return m_istream->peek(); + return static_cast(m_istream->peek()); } void increment(){ @@ -75,14 +75,14 @@ public: } istream_iterator() : - m_istream(NULL) + m_istream(NULL), + m_current_value(NULL) {} istream_iterator(const istream_iterator & rhs) : m_istream(rhs.m_istream), m_current_value(rhs.m_current_value) {} - }; } // namespace iterators diff --git a/linx64/include/boost/archive/iterators/mb_from_wchar.hpp b/linx64/include/boost/archive/iterators/mb_from_wchar.hpp index b6dc9b21..eb30480c 100644 --- a/linx64/include/boost/archive/iterators/mb_from_wchar.hpp +++ b/linx64/include/boost/archive/iterators/mb_from_wchar.hpp @@ -18,8 +18,9 @@ #include #include // size_t +#ifndef BOOST_NO_CWCHAR #include // mbstate_t - +#endif #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ @@ -85,12 +86,15 @@ class mb_from_wchar wchar_t value = * this->base_reference(); const wchar_t *wend; char *bend; - std::codecvt_base::result r = m_codecvt_facet.out( - m_mbs, - & value, & value + 1, wend, - m_buffer, m_buffer + sizeof(m_buffer), bend + BOOST_VERIFY( + m_codecvt_facet.out( + m_mbs, + & value, & value + 1, wend, + m_buffer, m_buffer + sizeof(m_buffer), bend + ) + == + std::codecvt_base::ok ); - BOOST_ASSERT(std::codecvt_base::ok == r); m_bnext = 0; m_bend = bend - m_buffer; } diff --git a/linx64/include/boost/archive/iterators/transform_width.hpp b/linx64/include/boost/archive/iterators/transform_width.hpp index d042560e..09c050a9 100644 --- a/linx64/include/boost/archive/iterators/transform_width.hpp +++ b/linx64/include/boost/archive/iterators/transform_width.hpp @@ -111,6 +111,7 @@ public: transform_width(T start) : super_t(Base(static_cast< T >(start))), m_buffer_out_full(false), + m_buffer_out(0), // To disable GCC warning, but not truly necessary //(m_buffer_in will be initialized later before being //used because m_remaining_bits == 0) diff --git a/linx64/include/boost/archive/iterators/wchar_from_mb.hpp b/linx64/include/boost/archive/iterators/wchar_from_mb.hpp index 52a44bdc..2af8f640 100644 --- a/linx64/include/boost/archive/iterators/wchar_from_mb.hpp +++ b/linx64/include/boost/archive/iterators/wchar_from_mb.hpp @@ -19,7 +19,9 @@ #include #include #include // size_t +#ifndef BOOST_NO_CWCHAR #include // mbstate_t +#endif #include // copy #include diff --git a/linx64/include/boost/archive/iterators/xml_unescape.hpp b/linx64/include/boost/archive/iterators/xml_unescape.hpp index 69977404..9d3c3af9 100644 --- a/linx64/include/boost/archive/iterators/xml_unescape.hpp +++ b/linx64/include/boost/archive/iterators/xml_unescape.hpp @@ -16,6 +16,8 @@ // See http://www.boost.org for updates, documentation, and revision history. +#include +#include #include #include @@ -42,11 +44,11 @@ class xml_unescape return unescape, Base>::dereference(); } public: - // workaround msvc 7.1 ICU crash - #if defined(BOOST_MSVC) + // msvc versions prior to 14.0 crash with and ICE + #if BOOST_WORKAROUND(BOOST_MSVC, < 1900) typedef int value_type; #else - typedef typename this_t::value_type value_type; + typedef typename super_t::value_type value_type; #endif void drain_residue(const char *literal); diff --git a/linx64/include/boost/archive/polymorphic_binary_iarchive.hpp b/linx64/include/boost/archive/polymorphic_binary_iarchive.hpp index 4a898a8a..20559bd8 100644 --- a/linx64/include/boost/archive/polymorphic_binary_iarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_binary_iarchive.hpp @@ -28,7 +28,7 @@ namespace boost { namespace archive { -class polymorphic_binary_iarchive : +class BOOST_SYMBOL_VISIBLE polymorphic_binary_iarchive : public detail::polymorphic_iarchive_route { public: diff --git a/linx64/include/boost/archive/polymorphic_binary_oarchive.hpp b/linx64/include/boost/archive/polymorphic_binary_oarchive.hpp index 931b243f..96febd7a 100644 --- a/linx64/include/boost/archive/polymorphic_binary_oarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_binary_oarchive.hpp @@ -23,13 +23,15 @@ namespace boost { namespace archive { -typedef detail::polymorphic_oarchive_route< - binary_oarchive_impl< - binary_oarchive, - std::ostream::char_type, - std::ostream::traits_type - > - > polymorphic_binary_oarchive; +class BOOST_SYMBOL_VISIBLE polymorphic_binary_oarchive : + public detail::polymorphic_oarchive_route +{ +public: + polymorphic_binary_oarchive(std::ostream & os, unsigned int flags = 0) : + detail::polymorphic_oarchive_route(os, flags) + {} + ~polymorphic_binary_oarchive(){} +}; } // namespace archive } // namespace boost diff --git a/linx64/include/boost/archive/polymorphic_text_iarchive.hpp b/linx64/include/boost/archive/polymorphic_text_iarchive.hpp index 7bef2927..3e59bfe6 100644 --- a/linx64/include/boost/archive/polymorphic_text_iarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_text_iarchive.hpp @@ -28,7 +28,7 @@ namespace boost { namespace archive { -class polymorphic_text_iarchive : +class BOOST_SYMBOL_VISIBLE polymorphic_text_iarchive : public detail::polymorphic_iarchive_route { public: diff --git a/linx64/include/boost/archive/polymorphic_text_oarchive.hpp b/linx64/include/boost/archive/polymorphic_text_oarchive.hpp index 457aad9f..233d37c7 100644 --- a/linx64/include/boost/archive/polymorphic_text_oarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_text_oarchive.hpp @@ -23,9 +23,15 @@ namespace boost { namespace archive { -typedef detail::polymorphic_oarchive_route< - text_oarchive_impl -> polymorphic_text_oarchive; +class BOOST_SYMBOL_VISIBLE polymorphic_text_oarchive : + public detail::polymorphic_oarchive_route +{ +public: + polymorphic_text_oarchive(std::ostream & os, unsigned int flags = 0) : + detail::polymorphic_oarchive_route(os, flags) + {} + ~polymorphic_text_oarchive(){} +}; } // namespace archive } // namespace boost diff --git a/linx64/include/boost/archive/polymorphic_text_wiarchive.hpp b/linx64/include/boost/archive/polymorphic_text_wiarchive.hpp index 8466f05d..96afe0eb 100644 --- a/linx64/include/boost/archive/polymorphic_text_wiarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_text_wiarchive.hpp @@ -32,7 +32,7 @@ namespace boost { namespace archive { -class polymorphic_text_wiarchive : +class BOOST_SYMBOL_VISIBLE polymorphic_text_wiarchive : public detail::polymorphic_iarchive_route { public: diff --git a/linx64/include/boost/archive/polymorphic_text_woarchive.hpp b/linx64/include/boost/archive/polymorphic_text_woarchive.hpp index 295625d1..fa0a3aec 100644 --- a/linx64/include/boost/archive/polymorphic_text_woarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_text_woarchive.hpp @@ -27,9 +27,15 @@ namespace boost { namespace archive { -typedef detail::polymorphic_oarchive_route< - text_woarchive_impl -> polymorphic_text_woarchive; +class BOOST_SYMBOL_VISIBLE polymorphic_text_woarchive : + public detail::polymorphic_oarchive_route +{ +public: + polymorphic_text_woarchive(std::wostream & os, unsigned int flags = 0) : + detail::polymorphic_oarchive_route(os, flags) + {} + ~polymorphic_text_woarchive(){} +}; } // namespace archive } // namespace boost diff --git a/linx64/include/boost/archive/polymorphic_xml_iarchive.hpp b/linx64/include/boost/archive/polymorphic_xml_iarchive.hpp index 4dc3f894..0b17b551 100644 --- a/linx64/include/boost/archive/polymorphic_xml_iarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_xml_iarchive.hpp @@ -28,7 +28,7 @@ namespace boost { namespace archive { -class polymorphic_xml_iarchive : +class BOOST_SYMBOL_VISIBLE polymorphic_xml_iarchive : public detail::polymorphic_iarchive_route { public: diff --git a/linx64/include/boost/archive/polymorphic_xml_oarchive.hpp b/linx64/include/boost/archive/polymorphic_xml_oarchive.hpp index 514f9e53..a9fc8242 100644 --- a/linx64/include/boost/archive/polymorphic_xml_oarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_xml_oarchive.hpp @@ -23,10 +23,15 @@ namespace boost { namespace archive { -typedef detail::polymorphic_oarchive_route< - xml_oarchive_impl -> polymorphic_xml_oarchive; - +class BOOST_SYMBOL_VISIBLE polymorphic_xml_oarchive : + public detail::polymorphic_oarchive_route +{ +public: + polymorphic_xml_oarchive(std::ostream & os, unsigned int flags = 0) : + detail::polymorphic_oarchive_route(os, flags) + {} + ~polymorphic_xml_oarchive(){} +}; } // namespace archive } // namespace boost diff --git a/linx64/include/boost/archive/polymorphic_xml_wiarchive.hpp b/linx64/include/boost/archive/polymorphic_xml_wiarchive.hpp index d4ab7312..688ff4d0 100644 --- a/linx64/include/boost/archive/polymorphic_xml_wiarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_xml_wiarchive.hpp @@ -27,7 +27,7 @@ namespace boost { namespace archive { -class polymorphic_xml_wiarchive : +class BOOST_SYMBOL_VISIBLE polymorphic_xml_wiarchive : public detail::polymorphic_iarchive_route { public: diff --git a/linx64/include/boost/archive/polymorphic_xml_woarchive.hpp b/linx64/include/boost/archive/polymorphic_xml_woarchive.hpp index dd8963fb..2606010d 100644 --- a/linx64/include/boost/archive/polymorphic_xml_woarchive.hpp +++ b/linx64/include/boost/archive/polymorphic_xml_woarchive.hpp @@ -7,7 +7,7 @@ #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_xml_oarchive.hpp +// polymorphic_xml_woarchive.hpp // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software @@ -27,9 +27,15 @@ namespace boost { namespace archive { -typedef detail::polymorphic_oarchive_route< - xml_woarchive_impl -> polymorphic_xml_woarchive; +class BOOST_SYMBOL_VISIBLE polymorphic_xml_woarchive : + public detail::polymorphic_oarchive_route +{ +public: + polymorphic_xml_woarchive(std::wostream & os, unsigned int flags = 0) : + detail::polymorphic_oarchive_route(os, flags) + {} + ~polymorphic_xml_woarchive(){} +}; } // namespace archive } // namespace boost diff --git a/linx64/include/boost/archive/text_oarchive.hpp b/linx64/include/boost/archive/text_oarchive.hpp index 9ba0daff..e4c6d466 100644 --- a/linx64/include/boost/archive/text_oarchive.hpp +++ b/linx64/include/boost/archive/text_oarchive.hpp @@ -65,10 +65,10 @@ protected: basic_text_oprimitive::save(t); } void save(const version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } BOOST_ARCHIVE_DECL void save(const char * t); diff --git a/linx64/include/boost/archive/text_woarchive.hpp b/linx64/include/boost/archive/text_woarchive.hpp index b6b4f8ed..beba62f7 100644 --- a/linx64/include/boost/archive/text_woarchive.hpp +++ b/linx64/include/boost/archive/text_woarchive.hpp @@ -78,10 +78,10 @@ protected: basic_text_oprimitive::save(t); } void save(const version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } BOOST_WARCHIVE_DECL void save(const char * t); diff --git a/linx64/include/boost/archive/wcslen.hpp b/linx64/include/boost/archive/wcslen.hpp index 2a3d6351..0b60004f 100644 --- a/linx64/include/boost/archive/wcslen.hpp +++ b/linx64/include/boost/archive/wcslen.hpp @@ -44,7 +44,9 @@ inline std::size_t wcslen(const wchar_t * ws) #else +#ifndef BOOST_NO_CWCHAR #include +#endif #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ using ::wcslen; } #endif diff --git a/linx64/include/boost/archive/xml_oarchive.hpp b/linx64/include/boost/archive/xml_oarchive.hpp index eea12680..d0fa8b21 100644 --- a/linx64/include/boost/archive/xml_oarchive.hpp +++ b/linx64/include/boost/archive/xml_oarchive.hpp @@ -65,11 +65,11 @@ protected: } void save(const version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } BOOST_ARCHIVE_DECL void save(const char * t); diff --git a/linx64/include/boost/archive/xml_wiarchive.hpp b/linx64/include/boost/archive/xml_wiarchive.hpp index ac24289a..2ca3e559 100644 --- a/linx64/include/boost/archive/xml_wiarchive.hpp +++ b/linx64/include/boost/archive/xml_wiarchive.hpp @@ -62,6 +62,7 @@ protected: friend class basic_xml_iarchive; friend class load_access; #endif + std::locale archive_locale; boost::scoped_ptr gimpl; std::wistream & get_is(){ return is; diff --git a/linx64/include/boost/archive/xml_woarchive.hpp b/linx64/include/boost/archive/xml_woarchive.hpp index cb7ce68c..e6ac50de 100644 --- a/linx64/include/boost/archive/xml_woarchive.hpp +++ b/linx64/include/boost/archive/xml_woarchive.hpp @@ -74,11 +74,11 @@ protected: } void save(const version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); + save(static_cast(t)); } BOOST_WARCHIVE_DECL void save(const char * t); diff --git a/linx64/include/boost/array.hpp b/linx64/include/boost/array.hpp index 210c0721..99dc2c6d 100644 --- a/linx64/include/boost/array.hpp +++ b/linx64/include/boost/array.hpp @@ -183,7 +183,7 @@ namespace boost { // check range (may be private because it is static) static BOOST_CONSTEXPR bool rangecheck (size_type i) { - return i > size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; + return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; } }; diff --git a/linx64/include/boost/asio.hpp b/linx64/include/boost/asio.hpp index 114d871c..1ee7e12f 100644 --- a/linx64/include/boost/asio.hpp +++ b/linx64/include/boost/asio.hpp @@ -2,7 +2,7 @@ // asio.hpp // ~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,7 +17,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include +#include #include +#include #include #include #include @@ -25,12 +28,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -39,13 +44,19 @@ #include #include #include +#include #include +#include #include #include -#include -#include #include +#include +#include +#include #include +#include +#include +#include #include #include #include @@ -54,11 +65,21 @@ #include #include #include -#include +#include +#include +#include #include +#include #include #include +#include +#include #include +#include +#include +#include +#include +#include #include #include #include @@ -67,54 +88,58 @@ #include #include #include +#include #include -#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include +#include #include #include -#include -#include +#include #include #include #include -#include +#include #include #include -#include #include -#include -#include #include +#include #include -#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include -#include -#include #include +#include #include #include #include -#include +#include #include #include -#include #include -#include #include #include diff --git a/linx64/include/boost/asio/associated_allocator.hpp b/linx64/include/boost/asio/associated_allocator.hpp new file mode 100644 index 00000000..c70852b5 --- /dev/null +++ b/linx64/include/boost/asio/associated_allocator.hpp @@ -0,0 +1,133 @@ +// +// associated_allocator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP +#define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +struct associated_allocator_check +{ + typedef void type; +}; + +template +struct associated_allocator_impl +{ + typedef E type; + + static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_allocator_impl::type> +{ + typedef typename T::allocator_type type; + + static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT + { + return t.get_allocator(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the allocator associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Allocator shall be a type meeting the Allocator requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c a is an object of type @c + * Allocator. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Allocator requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,a) and with return type @c type. + */ +template > +struct associated_allocator +{ + /// If @c T has a nested type @c allocator_type, T::allocator_type. + /// Otherwise @c Allocator. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_allocator_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c allocator_type, returns + /// t.get_allocator(). Otherwise returns @c a. + static type get(const T& t, + const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT + { + return detail::associated_allocator_impl::get(t, a); + } +}; + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT +{ + return associated_allocator::get(t); +} + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t, a) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT +{ + return associated_allocator::get(t, a); +} + +#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) + +template > +using associated_allocator_t + = typename associated_allocator::type; + +#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP diff --git a/linx64/include/boost/asio/associated_executor.hpp b/linx64/include/boost/asio/associated_executor.hpp new file mode 100644 index 00000000..a44190b5 --- /dev/null +++ b/linx64/include/boost/asio/associated_executor.hpp @@ -0,0 +1,151 @@ +// +// associated_executor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP +#define BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +struct associated_executor_check +{ + typedef void type; +}; + +template +struct associated_executor_impl +{ + typedef E type; + + static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_executor_impl::type> +{ + typedef typename T::executor_type type; + + static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT + { + return t.get_executor(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the executor associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Executor shall be a type meeting the Executor requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c e is an object of type @c + * Executor. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Executor requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,e) and with return type @c type. + */ +template +struct associated_executor +{ + /// If @c T has a nested type @c executor_type, T::executor_type. + /// Otherwise @c Executor. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_executor_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c executor_type, returns + /// t.get_executor(). Otherwise returns @c ex. + static type get(const T& t, + const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT + { + return detail::associated_executor_impl::get(t, ex); + } +}; + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT +{ + return associated_executor::get(t); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ex) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, const Executor& ex, + typename enable_if::value>::type* = 0) BOOST_ASIO_NOEXCEPT +{ + return associated_executor::get(t, ex); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ctx.get_executor()) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, ExecutionContext& ctx, + typename enable_if::value>::type* = 0) BOOST_ASIO_NOEXCEPT +{ + return associated_executor::get(t, ctx.get_executor()); +} + +#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) + +template +using associated_executor_t = typename associated_executor::type; + +#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP diff --git a/linx64/include/boost/asio/async_result.hpp b/linx64/include/boost/asio/async_result.hpp index 6290b846..4f3bb1ec 100644 --- a/linx64/include/boost/asio/async_result.hpp +++ b/linx64/include/boost/asio/async_result.hpp @@ -2,7 +2,7 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,7 +16,8 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include +#include +#include #include @@ -25,72 +26,333 @@ namespace asio { /// An interface for customising the behaviour of an initiating function. /** - * This template may be specialised for user-defined handler types. + * The async_result traits class is used for determining: + * + * @li the concrete completion handler type to be called at the end of the + * asynchronous operation; + * + * @li the initiating function return type; and + * + * @li how the return value of the initiating function is obtained. + * + * The trait allows the handler and return types to be determined at the point + * where the specific completion handler signature is known. + * + * This template may be specialised for user-defined completion token types. + * The primary template assumes that the CompletionToken is the completion + * handler. */ -template +template class async_result { public: + /// The concrete completion handler type for the specific signature. + typedef CompletionToken completion_handler_type; + /// The return type of the initiating function. - typedef void type; + typedef void return_type; /// Construct an async result from a given handler. /** * When using a specalised async_result, the constructor has an opportunity - * to initialise some state associated with the handler, which is then - * returned from the initiating function. + * to initialise some state associated with the completion handler, which is + * then returned from the initiating function. */ - explicit async_result(Handler&) + explicit async_result(completion_handler_type& h) { + (void)h; } /// Obtain the value to be returned from the initiating function. - type get() + return_type get() { } + +#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \ + || defined(GENERATING_DOCUMENTATION) + + /// Initiate the asynchronous operation that will produce the result, and + /// obtain the value to be returned from the initiating function. + template + static return_type initiate( + BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, + BOOST_ASIO_MOVE_ARG(Args)... args) + { + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( + BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), + BOOST_ASIO_MOVE_CAST(Args)(args)...); + } + +#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) + + template + static return_type initiate( + BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_MOVE_ARG(RawCompletionToken) token) + { + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( + BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token)); + } + +#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ + template \ + static return_type initiate( \ + BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ + BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \ + BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \ + BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \ + BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF) +#undef BOOST_ASIO_PRIVATE_INITIATE_DEF + +#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) + +private: + async_result(const async_result&) BOOST_ASIO_DELETED; + async_result& operator=(const async_result&) BOOST_ASIO_DELETED; +}; + +/// Helper template to deduce the handler type from a CompletionToken, capture +/// a local copy of the handler, and then create an async_result for the +/// handler. +template +struct async_completion +{ + /// The real handler type to be used for the asynchronous operation. + typedef typename boost::asio::async_result< + typename decay::type, + Signature>::completion_handler_type completion_handler_type; + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Constructor. + /** + * The constructor creates the concrete completion handler and makes the link + * between the handler and the asynchronous result. + */ + explicit async_completion(CompletionToken& token) + : completion_handler(static_cast::value, + completion_handler_type&, CompletionToken&&>::type>(token)), + result(completion_handler) + { + } +#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + explicit async_completion(typename decay::type& token) + : completion_handler(token), + result(completion_handler) + { + } + + explicit async_completion(const typename decay::type& token) + : completion_handler(token), + result(completion_handler) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// A copy of, or reference to, a real handler object. +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + typename conditional< + is_same::value, + completion_handler_type&, completion_handler_type>::type completion_handler; +#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + completion_handler_type completion_handler; +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// The result of the asynchronous operation's initiating function. + async_result::type, Signature> result; }; namespace detail { -// Helper template to deduce the true type of a handler, capture a local copy -// of the handler, and then create an async_result for the handler. -template -struct async_result_init +template +struct async_result_helper + : async_result::type, Signature> { - explicit async_result_init(BOOST_ASIO_MOVE_ARG(Handler) orig_handler) - : handler(BOOST_ASIO_MOVE_CAST(Handler)(orig_handler)), - result(handler) - { - } - - typename handler_type::type handler; - async_result::type> result; }; -template -struct async_result_type_helper +struct async_result_memfns_base +{ + void initiate(); +}; + +template +struct async_result_memfns_derived + : T, async_result_memfns_base +{ +}; + +template +struct async_result_memfns_check +{ +}; + +template +char (&async_result_initiate_memfn_helper(...))[2]; + +template +char async_result_initiate_memfn_helper( + async_result_memfns_check< + void (async_result_memfns_base::*)(), + &async_result_memfns_derived::initiate>*); + +template +struct async_result_has_initiate_memfn + : integral_constant::type, Signature> + >(0)) != 1> { - typedef typename async_result< - typename handler_type::type - >::type type; }; } // namespace detail + +#if defined(GENERATING_DOCUMENTATION) +# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ + void_or_deduced +#elif defined(_MSC_VER) && (_MSC_VER < 1500) +# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::boost::asio::detail::async_result_helper< \ + ct, sig>::return_type +#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ + typename ::boost::asio::detail::async_result_helper< \ + ct, sig>::completion_handler_type +#else +# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::boost::asio::async_result< \ + typename ::boost::asio::decay::type, sig>::return_type +#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ + typename ::boost::asio::async_result< \ + typename ::boost::asio::decay::type, sig>::completion_handler_type +#endif + +#if defined(GENERATING_DOCUMENTATION) + +template +BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) +async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken), + BOOST_ASIO_MOVE_ARG(Args)... args); + +#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline typename enable_if< + detail::async_result_has_initiate_memfn::value, + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, + BOOST_ASIO_MOVE_ARG(Args)... args) +{ + return async_result::type, + Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), + BOOST_ASIO_MOVE_CAST(CompletionToken)(token), + BOOST_ASIO_MOVE_CAST(Args)(args)...); +} + +template +inline typename enable_if< + !detail::async_result_has_initiate_memfn::value, + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, + BOOST_ASIO_MOVE_ARG(Args)... args) +{ + async_completion completion(token); + + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( + BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, + Signature))(completion.completion_handler), + BOOST_ASIO_MOVE_CAST(Args)(args)...); + + return completion.result.get(); +} + +#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline typename enable_if< + detail::async_result_has_initiate_memfn::value, + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) +{ + return async_result::type, + Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), + BOOST_ASIO_MOVE_CAST(CompletionToken)(token)); +} + +template +inline typename enable_if< + !detail::async_result_has_initiate_memfn::value, + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) +{ + async_completion completion(token); + + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( + BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, + Signature))(completion.completion_handler)); + + return completion.result.get(); +} + +#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ + template \ + inline typename enable_if< \ + detail::async_result_has_initiate_memfn< \ + CompletionToken, Signature>::value, \ + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ + async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ + BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + return async_result::type, \ + Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \ + BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \ + BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + \ + template \ + inline typename enable_if< \ + !detail::async_result_has_initiate_memfn< \ + CompletionToken, Signature>::value, \ + BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ + async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ + BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ + BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + async_completion completion(token); \ + \ + BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \ + BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \ + Signature))(completion.completion_handler), \ + BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ + \ + return completion.result.get(); \ + } \ + /**/ + BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF) +#undef BOOST_ASIO_PRIVATE_INITIATE_DEF + +#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) + } // namespace asio } // namespace boost #include -#if defined(GENERATING_DOCUMENTATION) -# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \ - void_or_deduced -#elif defined(_MSC_VER) && (_MSC_VER < 1500) -# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \ - typename ::boost::asio::detail::async_result_type_helper::type -#else -# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \ - typename ::boost::asio::async_result< \ - typename ::boost::asio::handler_type::type>::type -#endif - #endif // BOOST_ASIO_ASYNC_RESULT_HPP diff --git a/linx64/include/boost/asio/awaitable.hpp b/linx64/include/boost/asio/awaitable.hpp new file mode 100644 index 00000000..83f8647c --- /dev/null +++ b/linx64/include/boost/asio/awaitable.hpp @@ -0,0 +1,125 @@ +// +// awaitable.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_AWAITABLE_HPP +#define BOOST_ASIO_AWAITABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +using std::experimental::coroutine_handle; +using std::experimental::suspend_always; + +template class awaitable_thread; +template class awaitable_frame; + +} // namespace detail + +/// The return type of a coroutine or asynchronous operation. +template +class awaitable +{ +public: + /// The type of the awaited value. + typedef T value_type; + + /// The executor type that will be used for the coroutine. + typedef Executor executor_type; + + /// Default constructor. + constexpr awaitable() noexcept + : frame_(nullptr) + { + } + + /// Move constructor. + awaitable(awaitable&& other) noexcept + : frame_(std::exchange(other.frame_, nullptr)) + { + } + + /// Destructor + ~awaitable() + { + if (frame_) + frame_->destroy(); + } + + /// Checks if the awaitable refers to a future result. + bool valid() const noexcept + { + return !!frame_; + } + +#if !defined(GENERATING_DOCUMENTATION) + + // Support for co_await keyword. + bool await_ready() const noexcept + { + return false; + } + + // Support for co_await keyword. + template + void await_suspend( + detail::coroutine_handle> h) + { + frame_->push_frame(&h.promise()); + } + + // Support for co_await keyword. + T await_resume() + { + return frame_->get(); + } + +#endif // !defined(GENERATING_DOCUMENTATION) + +private: + template friend class detail::awaitable_thread; + template friend class detail::awaitable_frame; + + // Not copy constructible or copy assignable. + awaitable(const awaitable&) = delete; + awaitable& operator=(const awaitable&) = delete; + + // Construct the awaitable from a coroutine's frame object. + explicit awaitable(detail::awaitable_frame* a) + : frame_(a) + { + } + + detail::awaitable_frame* frame_; +}; + +} // namespace asio +} // namespace boost + +#include + +#include + +#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#endif // BOOST_ASIO_AWAITABLE_HPP diff --git a/linx64/include/boost/asio/basic_datagram_socket.hpp b/linx64/include/boost/asio/basic_datagram_socket.hpp index 22801ee0..b058f78c 100644 --- a/linx64/include/boost/asio/basic_datagram_socket.hpp +++ b/linx64/include/boost/asio/basic_datagram_socket.hpp @@ -2,7 +2,7 @@ // basic_datagram_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -29,6 +29,15 @@ namespace boost { namespace asio { +#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) +#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_datagram_socket; + +#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) + /// Provides datagram-oriented socket functionality. /** * The basic_datagram_socket class template provides asynchronous and blocking @@ -38,18 +47,29 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_datagram_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename DatagramSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_datagram_socket other; + }; /// The native representation of a socket. - typedef typename DatagramSocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -62,12 +82,29 @@ public: * This constructor creates a datagram socket without opening it. The open() * function must be called before data can be sent or received on the socket. * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. */ - explicit basic_datagram_socket(boost::asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_datagram_socket(const executor_type& ex) + : basic_socket(ex) + { + } + + /// Construct a basic_datagram_socket without opening it. + /** + * This constructor creates a datagram socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + */ + template + explicit basic_datagram_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -75,17 +112,37 @@ public: /** * This constructor creates and opens a datagram socket. * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws boost::system::system_error Thrown on failure. */ - basic_datagram_socket(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol) + : basic_socket(ex, protocol) + { + } + + /// Construct and open a basic_datagram_socket. + /** + * This constructor creates and opens a datagram socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_datagram_socket(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -96,18 +153,42 @@ public: * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the datagram * socket will be bound. * * @throws boost::system::system_error Thrown on failure. */ - basic_datagram_socket(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint) + : basic_socket(ex, endpoint) + { + } + + /// Construct a basic_datagram_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a datagram socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the datagram + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_datagram_socket(ExecutionContext& context, + const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -116,9 +197,8 @@ public: * This constructor creates a datagram socket object to hold an existing * native socket. * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * @@ -126,10 +206,34 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_datagram_socket(boost::asio::io_service& io_service, + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(ex, protocol, native_socket) + { + } + + /// Construct a basic_datagram_socket on an existing native socket. + /** + * This constructor creates a datagram socket object to hold an existing + * native socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_datagram_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -142,11 +246,11 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ basic_datagram_socket(basic_datagram_socket&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other)) + : basic_socket(std::move(other)) { } @@ -159,12 +263,12 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ basic_datagram_socket& operator=(basic_datagram_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other)); + basic_socket::operator=(std::move(other)); return *this; } @@ -177,15 +281,16 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ - template - basic_datagram_socket( - basic_datagram_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket< - Protocol1, DatagramSocketService1>)(other)) + template + basic_datagram_socket(basic_datagram_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -199,20 +304,30 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_datagram_socket>::type& operator=( - basic_datagram_socket&& other) + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_datagram_socket& + >::type operator=(basic_datagram_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket< - Protocol1, DatagramSocketService1>)(other)); + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_datagram_socket() + { + } + /// Send some data on a connected socket. /** * This function is used to send data on the datagram socket. The function @@ -239,8 +354,8 @@ public: std::size_t send(const ConstBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); + std::size_t s = this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, 0, ec); boost::asio::detail::throw_error(ec, "send"); return s; } @@ -267,8 +382,8 @@ public: socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); + std::size_t s = this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); boost::asio::detail::throw_error(ec, "send"); return s; } @@ -294,8 +409,8 @@ public: std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); + return this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send on a connected socket. @@ -316,9 +431,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected datagram @@ -339,12 +454,10 @@ public: async_send(const ConstBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. @@ -367,9 +480,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected datagram @@ -382,12 +495,9 @@ public: socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Send a datagram to the specified endpoint. @@ -420,8 +530,8 @@ public: const endpoint_type& destination) { boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); + std::size_t s = this->impl_.get_service().send_to( + this->impl_.get_implementation(), buffers, destination, 0, ec); boost::asio::detail::throw_error(ec, "send_to"); return s; } @@ -447,8 +557,8 @@ public: const endpoint_type& destination, socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); + std::size_t s = this->impl_.get_service().send_to( + this->impl_.get_implementation(), buffers, destination, flags, ec); boost::asio::detail::throw_error(ec, "send_to"); return s; } @@ -474,7 +584,7 @@ public: const endpoint_type& destination, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().send_to(this->get_implementation(), + return this->impl_.get_service().send_to(this->impl_.get_implementation(), buffers, destination, flags, ec); } @@ -499,9 +609,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -522,13 +632,10 @@ public: const endpoint_type& destination, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, + destination, socket_base::message_flags(0)); } /// Start an asynchronous send. @@ -554,9 +661,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, @@ -565,13 +672,9 @@ public: const endpoint_type& destination, socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, destination, flags); } /// Receive some data on a connected socket. @@ -602,8 +705,8 @@ public: std::size_t receive(const MutableBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); + std::size_t s = this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, 0, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -631,8 +734,8 @@ public: socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); + std::size_t s = this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, flags, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -659,8 +762,8 @@ public: std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); + return this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous receive on a connected socket. @@ -681,9 +784,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected @@ -705,12 +808,10 @@ public: async_receive(const MutableBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. @@ -733,9 +834,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected @@ -748,12 +849,9 @@ public: socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, buffers, flags); } /// Receive a datagram with the endpoint of the sender. @@ -787,8 +885,8 @@ public: endpoint_type& sender_endpoint) { boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); + std::size_t s = this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); boost::asio::detail::throw_error(ec, "receive_from"); return s; } @@ -814,8 +912,8 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); + std::size_t s = this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); boost::asio::detail::throw_error(ec, "receive_from"); return s; } @@ -841,8 +939,8 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); + return this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); } /// Start an asynchronous receive. @@ -868,9 +966,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -888,13 +986,10 @@ public: endpoint_type& sender_endpoint, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, this, buffers, + &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. @@ -922,9 +1017,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, @@ -933,14 +1028,85 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, + this, buffers, &sender_endpoint, flags); } + +private: + struct initiate_async_send + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_datagram_socket* self, const ConstBufferSequence& buffers, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_send_to + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_datagram_socket* self, const ConstBufferSequence& buffers, + const endpoint_type& destination, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send_to( + self->impl_.get_implementation(), buffers, destination, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_receive + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_datagram_socket* self, const MutableBufferSequence& buffers, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_receive( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_receive_from + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_datagram_socket* self, const MutableBufferSequence& buffers, + endpoint_type* sender_endpoint, socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_receive_from( + self->impl_.get_implementation(), buffers, *sender_endpoint, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_deadline_timer.hpp b/linx64/include/boost/asio/basic_deadline_timer.hpp index 93037004..75f0fcd8 100644 --- a/linx64/include/boost/asio/basic_deadline_timer.hpp +++ b/linx64/include/boost/asio/basic_deadline_timer.hpp @@ -2,7 +2,7 @@ // basic_deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -21,11 +21,15 @@ || defined(GENERATING_DOCUMENTATION) #include -#include -#include +#include #include +#include +#include #include #include +#include +#include +#include #include @@ -51,7 +55,7 @@ namespace asio { * Performing a blocking wait: * @code * // Construct a timer without setting an expiry time. - * boost::asio::deadline_timer timer(io_service); + * boost::asio::deadline_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_from_now(boost::posix_time::seconds(5)); @@ -74,7 +78,7 @@ namespace asio { * ... * * // Construct a timer with an absolute expiry time. - * boost::asio::deadline_timer timer(io_service, + * boost::asio::deadline_timer timer(my_context, * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); * * // Start an asynchronous wait. @@ -122,11 +126,13 @@ namespace asio { */ template , - typename TimerService = deadline_timer_service > + typename Executor = executor> class basic_deadline_timer - : public basic_io_object { public: + /// The type of the executor associated with the object. + typedef Executor executor_type; + /// The time traits type. typedef TimeTraits traits_type; @@ -142,11 +148,30 @@ public: * expires_at() or expires_from_now() functions must be called to set an * expiry time before the timer can be waited on. * - * @param io_service The io_service object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param ex The I/O executor that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. */ - explicit basic_deadline_timer(boost::asio::io_service& io_service) - : basic_io_object(io_service) + explicit basic_deadline_timer(const executor_type& ex) + : impl_(ex) + { + } + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_from_now() functions must be called to set an + * expiry time before the timer can be waited on. + * + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. + */ + template + explicit basic_deadline_timer(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -154,18 +179,40 @@ public: /** * This constructor creates a timer and sets the expiry time. * - * @param io_service The io_service object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param ex The I/O executor that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ - basic_deadline_timer(boost::asio::io_service& io_service, - const time_type& expiry_time) - : basic_io_object(io_service) + basic_deadline_timer(const executor_type& ex, const time_type& expiry_time) + : impl_(ex) { boost::system::error_code ec; - this->service.expires_at(this->implementation, expiry_time, ec); + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); + boost::asio::detail::throw_error(ec, "expires_at"); + } + + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + template + basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_at"); } @@ -173,21 +220,98 @@ public: /** * This constructor creates a timer and sets the expiry time. * - * @param io_service The io_service object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param ex The I/O executor that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ - basic_deadline_timer(boost::asio::io_service& io_service, + basic_deadline_timer(const executor_type& ex, const duration_type& expiry_time) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; - this->service.expires_from_now(this->implementation, expiry_time, ec); + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_from_now"); } + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + template + basic_deadline_timer(ExecutionContext& context, + const duration_type& expiry_time, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); + boost::asio::detail::throw_error(ec, "expires_from_now"); + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_deadline_timer from another. + /** + * This constructor moves a timer from one object to another. + * + * @param other The other basic_deadline_timer object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_deadline_timer(const executor_type&) + * constructor. + */ + basic_deadline_timer(basic_deadline_timer&& other) + : impl_(std::move(other.impl_)) + { + } + + /// Move-assign a basic_deadline_timer from another. + /** + * This assignment operator moves a timer from one object to another. Cancels + * any outstanding asynchronous operations associated with the target object. + * + * @param other The other basic_deadline_timer object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_deadline_timer(const executor_type&) + * constructor. + */ + basic_deadline_timer& operator=(basic_deadline_timer&& other) + { + impl_ = std::move(other.impl_); + return *this; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the timer. + /** + * This function destroys the timer, cancelling any outstanding asynchronous + * wait operations associated with the timer as if by calling @c cancel. + */ + ~basic_deadline_timer() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Cancel any asynchronous operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait @@ -213,7 +337,7 @@ public: std::size_t cancel() { boost::system::error_code ec; - std::size_t s = this->service.cancel(this->implementation, ec); + std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); return s; } @@ -242,7 +366,7 @@ public: */ std::size_t cancel(boost::system::error_code& ec) { - return this->service.cancel(this->implementation, ec); + return impl_.get_service().cancel(impl_.get_implementation(), ec); } /// Cancels one asynchronous operation that is waiting on the timer. @@ -272,7 +396,8 @@ public: std::size_t cancel_one() { boost::system::error_code ec; - std::size_t s = this->service.cancel_one(this->implementation, ec); + std::size_t s = impl_.get_service().cancel_one( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel_one"); return s; } @@ -303,7 +428,7 @@ public: */ std::size_t cancel_one(boost::system::error_code& ec) { - return this->service.cancel_one(this->implementation, ec); + return impl_.get_service().cancel_one(impl_.get_implementation(), ec); } /// Get the timer's expiry time as an absolute time. @@ -313,7 +438,7 @@ public: */ time_type expires_at() const { - return this->service.expires_at(this->implementation); + return impl_.get_service().expires_at(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. @@ -341,8 +466,8 @@ public: std::size_t expires_at(const time_type& expiry_time) { boost::system::error_code ec; - std::size_t s = this->service.expires_at( - this->implementation, expiry_time, ec); + std::size_t s = impl_.get_service().expires_at( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_at"); return s; } @@ -372,7 +497,8 @@ public: std::size_t expires_at(const time_type& expiry_time, boost::system::error_code& ec) { - return this->service.expires_at(this->implementation, expiry_time, ec); + return impl_.get_service().expires_at( + impl_.get_implementation(), expiry_time, ec); } /// Get the timer's expiry time relative to now. @@ -382,7 +508,7 @@ public: */ duration_type expires_from_now() const { - return this->service.expires_from_now(this->implementation); + return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// Set the timer's expiry time relative to now. @@ -410,8 +536,8 @@ public: std::size_t expires_from_now(const duration_type& expiry_time) { boost::system::error_code ec; - std::size_t s = this->service.expires_from_now( - this->implementation, expiry_time, ec); + std::size_t s = impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_from_now"); return s; } @@ -441,8 +567,8 @@ public: std::size_t expires_from_now(const duration_type& expiry_time, boost::system::error_code& ec) { - return this->service.expires_from_now( - this->implementation, expiry_time, ec); + return impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); } /// Perform a blocking wait on the timer. @@ -455,7 +581,7 @@ public: void wait() { boost::system::error_code ec; - this->service.wait(this->implementation, ec); + impl_.get_service().wait(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "wait"); } @@ -468,7 +594,7 @@ public: */ void wait(boost::system::error_code& ec) { - this->service.wait(this->implementation, ec); + impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the timer. @@ -491,22 +617,44 @@ public: * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, void (boost::system::error_code)) async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - return this->service.async_wait(this->implementation, - BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); + return async_initiate( + initiate_async_wait(), handler, this); } + +private: + // Disallow copying and assignment. + basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED; + basic_deadline_timer& operator=( + const basic_deadline_timer&) BOOST_ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, + basic_deadline_timer* self) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WaitHandler. + BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + detail::io_object_impl< + detail::deadline_timer_service, Executor> impl_; }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_io_object.hpp b/linx64/include/boost/asio/basic_io_object.hpp index d490a161..a9f44d1f 100644 --- a/linx64/include/boost/asio/basic_io_object.hpp +++ b/linx64/include/boost/asio/basic_io_object.hpp @@ -2,7 +2,7 @@ // basic_io_object.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,7 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include +#include #include @@ -68,17 +68,43 @@ public: /// The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; - /// Get the io_service associated with the object. +#if !defined(BOOST_ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. /** - * This function may be used to obtain the io_service object that the I/O + * This function may be used to obtain the io_context object that the I/O * object uses to dispatch handlers for asynchronous operations. * - * @return A reference to the io_service object that the I/O object will use + * @return A reference to the io_context object that the I/O object will use * to dispatch handlers. Ownership is not transferred to the caller. */ - boost::asio::io_service& get_io_service() + boost::asio::io_context& get_io_context() { - return service.get_io_service(); + return service_.get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + boost::asio::io_context& get_io_service() + { + return service_.get_io_context(); + } +#endif // !defined(BOOST_ASIO_NO_DEPRECATED) + + /// The type of the executor associated with the object. + typedef boost::asio::io_context::executor_type executor_type; + + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return service_.get_io_context().get_executor(); } protected: @@ -87,10 +113,10 @@ protected: * Performs: * @code get_service().construct(get_implementation()); @endcode */ - explicit basic_io_object(boost::asio::io_service& io_service) - : service(boost::asio::use_service(io_service)) + explicit basic_io_object(boost::asio::io_context& io_context) + : service_(boost::asio::use_service(io_context)) { - service.construct(implementation); + service_.construct(implementation_); } #if defined(GENERATING_DOCUMENTATION) @@ -127,47 +153,42 @@ protected: */ ~basic_io_object() { - service.destroy(implementation); + service_.destroy(implementation_); } /// Get the service associated with the I/O object. service_type& get_service() { - return service; + return service_; } /// Get the service associated with the I/O object. const service_type& get_service() const { - return service; + return service_; } - /// (Deprecated: Use get_service().) The service associated with the I/O - /// object. - /** - * @note Available only for services that do not support movability. - */ - service_type& service; - /// Get the underlying implementation of the I/O object. implementation_type& get_implementation() { - return implementation; + return implementation_; } /// Get the underlying implementation of the I/O object. const implementation_type& get_implementation() const { - return implementation; + return implementation_; } - /// (Deprecated: Use get_implementation().) The underlying implementation of - /// the I/O object. - implementation_type implementation; - private: basic_io_object(const basic_io_object&); basic_io_object& operator=(const basic_io_object&); + + // The service associated with the I/O object. + service_type& service_; + + /// The underlying implementation of the I/O object. + implementation_type implementation_; }; #if defined(BOOST_ASIO_HAS_MOVE) @@ -179,43 +200,57 @@ public: typedef IoObjectService service_type; typedef typename service_type::implementation_type implementation_type; - boost::asio::io_service& get_io_service() +#if !defined(BOOST_ASIO_NO_DEPRECATED) + boost::asio::io_context& get_io_context() { - return service_->get_io_service(); + return service_->get_io_context(); + } + + boost::asio::io_context& get_io_service() + { + return service_->get_io_context(); + } +#endif // !defined(BOOST_ASIO_NO_DEPRECATED) + + typedef boost::asio::io_context::executor_type executor_type; + + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return service_->get_io_context().get_executor(); } protected: - explicit basic_io_object(boost::asio::io_service& io_service) - : service_(&boost::asio::use_service(io_service)) + explicit basic_io_object(boost::asio::io_context& io_context) + : service_(&boost::asio::use_service(io_context)) { - service_->construct(implementation); + service_->construct(implementation_); } basic_io_object(basic_io_object&& other) : service_(&other.get_service()) { - service_->move_construct(implementation, other.implementation); + service_->move_construct(implementation_, other.implementation_); } template basic_io_object(IoObjectService1& other_service, typename IoObjectService1::implementation_type& other_implementation) : service_(&boost::asio::use_service( - other_service.get_io_service())) + other_service.get_io_context())) { - service_->converting_move_construct(implementation, + service_->converting_move_construct(implementation_, other_service, other_implementation); } ~basic_io_object() { - service_->destroy(implementation); + service_->destroy(implementation_); } basic_io_object& operator=(basic_io_object&& other) { - service_->move_assign(implementation, - *other.service_, other.implementation); + service_->move_assign(implementation_, + *other.service_, other.implementation_); service_ = other.service_; return *this; } @@ -232,21 +267,20 @@ protected: implementation_type& get_implementation() { - return implementation; + return implementation_; } const implementation_type& get_implementation() const { - return implementation; + return implementation_; } - implementation_type implementation; - private: basic_io_object(const basic_io_object&); void operator=(const basic_io_object&); IoObjectService* service_; + implementation_type implementation_; }; #endif // defined(BOOST_ASIO_HAS_MOVE) diff --git a/linx64/include/boost/asio/basic_raw_socket.hpp b/linx64/include/boost/asio/basic_raw_socket.hpp index 85f8f426..cc45d372 100644 --- a/linx64/include/boost/asio/basic_raw_socket.hpp +++ b/linx64/include/boost/asio/basic_raw_socket.hpp @@ -2,7 +2,7 @@ // basic_raw_socket.hpp // ~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,16 +19,25 @@ #include #include #include +#include #include #include #include -#include #include namespace boost { namespace asio { +#if !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL) +#define BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_raw_socket; + +#endif // !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL) + /// Provides raw-oriented socket functionality. /** * The basic_raw_socket class template provides asynchronous and blocking @@ -38,18 +47,29 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_raw_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename RawSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_raw_socket other; + }; /// The native representation of a socket. - typedef typename RawSocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -62,12 +82,29 @@ public: * This constructor creates a raw socket without opening it. The open() * function must be called before data can be sent or received on the socket. * - * @param io_service The io_service object that the raw socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. */ - explicit basic_raw_socket(boost::asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_raw_socket(const executor_type& ex) + : basic_socket(ex) + { + } + + /// Construct a basic_raw_socket without opening it. + /** + * This constructor creates a raw socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + */ + template + explicit basic_raw_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -75,17 +112,36 @@ public: /** * This constructor creates and opens a raw socket. * - * @param io_service The io_service object that the raw socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws boost::system::system_error Thrown on failure. */ - basic_raw_socket(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) + basic_raw_socket(const executor_type& ex, const protocol_type& protocol) + : basic_socket(ex, protocol) + { + } + + /// Construct and open a basic_raw_socket. + /** + * This constructor creates and opens a raw socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -96,18 +152,41 @@ public: * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * - * @param io_service The io_service object that the raw socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the raw * socket will be bound. * * @throws boost::system::system_error Thrown on failure. */ - basic_raw_socket(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint) + : basic_socket(ex, endpoint) + { + } + + /// Construct a basic_raw_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a raw socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the raw + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -116,9 +195,8 @@ public: * This constructor creates a raw socket object to hold an existing * native socket. * - * @param io_service The io_service object that the raw socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * @@ -126,10 +204,34 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_raw_socket(boost::asio::io_service& io_service, + basic_raw_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(ex, protocol, native_socket) + { + } + + /// Construct a basic_raw_socket on an existing native socket. + /** + * This constructor creates a raw socket object to hold an existing + * native socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -142,11 +244,11 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_raw_socket(io_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ basic_raw_socket(basic_raw_socket&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other)) + : basic_socket(std::move(other)) { } @@ -158,31 +260,34 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_raw_socket(io_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ basic_raw_socket& operator=(basic_raw_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_raw_socket)(other)); + basic_socket::operator=(std::move(other)); return *this; } - /// Move-construct a basic_raw_socket from a socket of another protocol type. + /// Move-construct a basic_raw_socket from a socket of another protocol + /// type. /** * This constructor moves a raw socket from one object to another. * - * @param other The other basic_raw_socket object from which the move will - * occur. + * @param other The other basic_raw_socket object from which the move + * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_raw_socket(io_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ - template - basic_raw_socket(basic_raw_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_raw_socket< - Protocol1, RawSocketService1>)(other)) + template + basic_raw_socket(basic_raw_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -194,20 +299,30 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_raw_socket(io_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_raw_socket>::type& operator=( - basic_raw_socket&& other) + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_raw_socket& + >::type operator=(basic_raw_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_raw_socket< - Protocol1, RawSocketService1>)(other)); + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_raw_socket() + { + } + /// Send some data on a connected socket. /** * This function is used to send data on the raw socket. The function call @@ -233,8 +348,8 @@ public: std::size_t send(const ConstBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); + std::size_t s = this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, 0, ec); boost::asio::detail::throw_error(ec, "send"); return s; } @@ -260,8 +375,8 @@ public: socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); + std::size_t s = this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); boost::asio::detail::throw_error(ec, "send"); return s; } @@ -286,8 +401,8 @@ public: std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); + return this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send on a connected socket. @@ -308,9 +423,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected raw @@ -331,12 +446,10 @@ public: async_send(const ConstBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. @@ -359,9 +472,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_send operation can only be used with a connected socket. * Use the async_send_to function to send data on an unconnected raw @@ -374,12 +487,9 @@ public: socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Send raw data to the specified endpoint. @@ -412,8 +522,8 @@ public: const endpoint_type& destination) { boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); + std::size_t s = this->impl_.get_service().send_to( + this->impl_.get_implementation(), buffers, destination, 0, ec); boost::asio::detail::throw_error(ec, "send_to"); return s; } @@ -439,8 +549,8 @@ public: const endpoint_type& destination, socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); + std::size_t s = this->impl_.get_service().send_to( + this->impl_.get_implementation(), buffers, destination, flags, ec); boost::asio::detail::throw_error(ec, "send_to"); return s; } @@ -466,7 +576,7 @@ public: const endpoint_type& destination, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().send_to(this->get_implementation(), + return this->impl_.get_service().send_to(this->impl_.get_implementation(), buffers, destination, flags, ec); } @@ -491,9 +601,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -514,12 +624,10 @@ public: const endpoint_type& destination, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to(this->get_implementation(), - buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, + destination, socket_base::message_flags(0)); } /// Start an asynchronous send. @@ -545,9 +653,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, @@ -556,13 +664,9 @@ public: const endpoint_type& destination, socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, destination, flags); } /// Receive some data on a connected socket. @@ -593,8 +697,8 @@ public: std::size_t receive(const MutableBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); + std::size_t s = this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, 0, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -622,8 +726,8 @@ public: socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); + std::size_t s = this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, flags, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -650,8 +754,8 @@ public: std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); + return this->impl_.get_service().receive( + this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous receive on a connected socket. @@ -672,9 +776,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected @@ -696,12 +800,10 @@ public: async_receive(const MutableBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. @@ -724,9 +826,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The async_receive operation can only be used with a connected socket. * Use the async_receive_from function to receive data on an unconnected @@ -739,12 +841,9 @@ public: socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, buffers, flags); } /// Receive raw data with the endpoint of the sender. @@ -778,8 +877,8 @@ public: endpoint_type& sender_endpoint) { boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); + std::size_t s = this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); boost::asio::detail::throw_error(ec, "receive_from"); return s; } @@ -805,8 +904,8 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); + std::size_t s = this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); boost::asio::detail::throw_error(ec, "receive_from"); return s; } @@ -832,8 +931,8 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); + return this->impl_.get_service().receive_from( + this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); } /// Start an asynchronous receive. @@ -859,9 +958,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -879,13 +978,10 @@ public: endpoint_type& sender_endpoint, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, this, buffers, + &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. @@ -913,9 +1009,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, @@ -924,14 +1020,85 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, + this, buffers, &sender_endpoint, flags); } + +private: + struct initiate_async_send + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_raw_socket* self, const ConstBufferSequence& buffers, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_send_to + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_raw_socket* self, const ConstBufferSequence& buffers, + const endpoint_type& destination, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send_to( + self->impl_.get_implementation(), buffers, destination, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_receive + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_raw_socket* self, const MutableBufferSequence& buffers, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_receive( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_receive_from + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_raw_socket* self, const MutableBufferSequence& buffers, + endpoint_type* sender_endpoint, socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_receive_from( + self->impl_.get_implementation(), buffers, *sender_endpoint, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_seq_packet_socket.hpp b/linx64/include/boost/asio/basic_seq_packet_socket.hpp index c8e43f77..7c3903ea 100644 --- a/linx64/include/boost/asio/basic_seq_packet_socket.hpp +++ b/linx64/include/boost/asio/basic_seq_packet_socket.hpp @@ -2,7 +2,7 @@ // basic_seq_packet_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -21,13 +21,21 @@ #include #include #include -#include #include namespace boost { namespace asio { +#if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) +#define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_seq_packet_socket; + +#endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) + /// Provides sequenced packet socket functionality. /** * The basic_seq_packet_socket class template provides asynchronous and blocking @@ -37,19 +45,29 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_seq_packet_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename SeqPacketSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_seq_packet_socket other; + }; /// The native representation of a socket. - typedef typename SeqPacketSocketService::native_handle_type - native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -63,12 +81,30 @@ public: * socket needs to be opened and then connected or accepted before data can * be sent or received on it. * - * @param io_service The io_service object that the sequenced packet socket - * will use to dispatch handlers for any asynchronous operations performed on - * the socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. */ - explicit basic_seq_packet_socket(boost::asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_seq_packet_socket(const executor_type& ex) + : basic_socket(ex) + { + } + + /// Construct a basic_seq_packet_socket without opening it. + /** + * This constructor creates a sequenced packet socket without opening it. The + * socket needs to be opened and then connected or accepted before data can + * be sent or received on it. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + */ + template + explicit basic_seq_packet_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -78,17 +114,40 @@ public: * needs to be connected or accepted before data can be sent or received on * it. * - * @param io_service The io_service object that the sequenced packet socket - * will use to dispatch handlers for any asynchronous operations performed on - * the socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws boost::system::system_error Thrown on failure. */ - basic_seq_packet_socket(boost::asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol) - : basic_socket(io_service, protocol) + : basic_socket(ex, protocol) + { + } + + /// Construct and open a basic_seq_packet_socket. + /** + * This constructor creates and opens a sequenced_packet socket. The socket + * needs to be connected or accepted before data can be sent or received on + * it. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -99,18 +158,43 @@ public: * it bound to the specified endpoint on the local machine. The protocol used * is the protocol associated with the given endpoint. * - * @param io_service The io_service object that the sequenced packet socket - * will use to dispatch handlers for any asynchronous operations performed on - * the socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the sequenced * packet socket will be bound. * * @throws boost::system::system_error Thrown on failure. */ - basic_seq_packet_socket(boost::asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + : basic_socket(ex, endpoint) + { + } + + /// Construct a basic_seq_packet_socket, opening it and binding it to the + /// given local endpoint. + /** + * This constructor creates a sequenced packet socket and automatically opens + * it bound to the specified endpoint on the local machine. The protocol used + * is the protocol associated with the given endpoint. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the sequenced + * packet socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -119,9 +203,8 @@ public: * This constructor creates a sequenced packet socket object to hold an * existing native socket. * - * @param io_service The io_service object that the sequenced packet socket - * will use to dispatch handlers for any asynchronous operations performed on - * the socket. + * @param ex The I/O executor that the socket will use, by default, to + * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * @@ -129,10 +212,34 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_seq_packet_socket(boost::asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(ex, protocol, native_socket) + { + } + + /// Construct a basic_seq_packet_socket on an existing native socket. + /** + * This constructor creates a sequenced packet socket object to hold an + * existing native socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -146,11 +253,11 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_seq_packet_socket(io_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ basic_seq_packet_socket(basic_seq_packet_socket&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other)) + : basic_socket(std::move(other)) { } @@ -163,12 +270,12 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_seq_packet_socket(io_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other)); + basic_socket::operator=(std::move(other)); return *this; } @@ -182,15 +289,16 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_seq_packet_socket(io_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ - template - basic_seq_packet_socket( - basic_seq_packet_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket< - Protocol1, SeqPacketSocketService1>)(other)) + template + basic_seq_packet_socket(basic_seq_packet_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -204,20 +312,30 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_seq_packet_socket(io_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_seq_packet_socket>::type& operator=( - basic_seq_packet_socket&& other) + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_seq_packet_socket& + >::type operator=(basic_seq_packet_socket&& other) { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket< - Protocol1, SeqPacketSocketService1>)(other)); + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_seq_packet_socket() + { + } + /// Send some data on the socket. /** * This function is used to send data on the sequenced packet socket. The @@ -246,8 +364,8 @@ public: socket_base::message_flags flags) { boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); + std::size_t s = this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); boost::asio::detail::throw_error(ec, "send"); return s; } @@ -274,8 +392,8 @@ public: std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, boost::system::error_code& ec) { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); + return this->impl_.get_service().send( + this->impl_.get_implementation(), buffers, flags, ec); } /// Start an asynchronous send. @@ -298,9 +416,9 @@ public: * std::size_t bytes_transferred // Number of bytes sent. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -318,12 +436,9 @@ public: socket_base::message_flags flags, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Receive some data on the socket. @@ -360,8 +475,8 @@ public: socket_base::message_flags& out_flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, out_flags, ec); + std::size_t s = this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, 0, out_flags, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -407,8 +522,8 @@ public: socket_base::message_flags& out_flags) { boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, in_flags, out_flags, ec); + std::size_t s = this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); boost::asio::detail::throw_error(ec, "receive"); return s; } @@ -441,8 +556,8 @@ public: socket_base::message_flags in_flags, socket_base::message_flags& out_flags, boost::system::error_code& ec) { - return this->get_service().receive(this->get_implementation(), - buffers, in_flags, out_flags, ec); + return this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); } /// Start an asynchronous receive. @@ -469,9 +584,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -490,13 +605,10 @@ public: socket_base::message_flags& out_flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive( - this->get_implementation(), buffers, 0, out_flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_with_flags(), handler, this, + buffers, socket_base::message_flags(0), &out_flags); } /// Start an asynchronous receive. @@ -525,9 +637,9 @@ public: * std::size_t bytes_transferred // Number of bytes received. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -549,14 +661,49 @@ public: socket_base::message_flags& out_flags, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive( - this->get_implementation(), buffers, in_flags, out_flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_with_flags(), handler, + this, buffers, in_flags, &out_flags); } + +private: + struct initiate_async_send + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_seq_packet_socket* self, const ConstBufferSequence& buffers, + socket_base::message_flags flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_receive_with_flags + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_seq_packet_socket* self, const MutableBufferSequence& buffers, + socket_base::message_flags in_flags, + socket_base::message_flags* out_flags) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_receive_with_flags( + self->impl_.get_implementation(), buffers, in_flags, *out_flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_serial_port.hpp b/linx64/include/boost/asio/basic_serial_port.hpp index bfc78afa..88a195a4 100644 --- a/linx64/include/boost/asio/basic_serial_port.hpp +++ b/linx64/include/boost/asio/basic_serial_port.hpp @@ -2,7 +2,7 @@ // basic_serial_port.hpp // ~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -22,12 +22,25 @@ || defined(GENERATING_DOCUMENTATION) #include -#include +#include #include +#include +#include #include +#include #include +#include +#include #include -#include +#if defined(BOOST_ASIO_HAS_IOCP) +# include +#else +# include +#endif + +#if defined(BOOST_ASIO_HAS_MOVE) +# include +#endif // defined(BOOST_ASIO_HAS_MOVE) #include @@ -36,38 +49,63 @@ namespace asio { /// Provides serial port functionality. /** - * The basic_serial_port class template provides functionality that is common - * to all serial ports. + * The basic_serial_port class provides a wrapper over serial port + * functionality. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template +template class basic_serial_port - : public basic_io_object, - public serial_port_base + : public serial_port_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// serial port. - typedef typename SerialPortService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; /// The native representation of a serial port. - typedef typename SerialPortService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_serial_port_service::native_handle_type + native_handle_type; +#else + typedef detail::reactive_serial_port_service::native_handle_type + native_handle_type; +#endif - /// A basic_serial_port is always the lowest layer. - typedef basic_serial_port lowest_layer_type; + /// A basic_basic_serial_port is always the lowest layer. + typedef basic_serial_port lowest_layer_type; /// Construct a basic_serial_port without opening it. /** * This constructor creates a serial port without opening it. * - * @param io_service The io_service object that the serial port will use to - * dispatch handlers for any asynchronous operations performed on the port. + * @param ex The I/O executor that the serial port will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * serial port. */ - explicit basic_serial_port(boost::asio::io_service& io_service) - : basic_io_object(io_service) + explicit basic_serial_port(const executor_type& ex) + : impl_(ex) + { + } + + /// Construct a basic_serial_port without opening it. + /** + * This constructor creates a serial port without opening it. + * + * @param context An execution context which provides the I/O executor that + * the serial port will use, by default, to dispatch handlers for any + * asynchronous operations performed on the serial port. + */ + template + explicit basic_serial_port(ExecutionContext& context, + typename enable_if< + is_convertible::value, + basic_serial_port + >::type* = 0) + : impl_(context) { } @@ -76,18 +114,18 @@ public: * This constructor creates and opens a serial port for the specified device * name. * - * @param io_service The io_service object that the serial port will use to - * dispatch handlers for any asynchronous operations performed on the port. + * @param ex The I/O executor that the serial port will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * serial port. * * @param device The platform-specific device name for this serial * port. */ - explicit basic_serial_port(boost::asio::io_service& io_service, - const char* device) - : basic_io_object(io_service) + basic_serial_port(const executor_type& ex, const char* device) + : impl_(ex) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -96,18 +134,66 @@ public: * This constructor creates and opens a serial port for the specified device * name. * - * @param io_service The io_service object that the serial port will use to - * dispatch handlers for any asynchronous operations performed on the port. + * @param context An execution context which provides the I/O executor that + * the serial port will use, by default, to dispatch handlers for any + * asynchronous operations performed on the serial port. * * @param device The platform-specific device name for this serial * port. */ - explicit basic_serial_port(boost::asio::io_service& io_service, - const std::string& device) - : basic_io_object(io_service) + template + basic_serial_port(ExecutionContext& context, const char* device, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param ex The I/O executor that the serial port will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * serial port. + * + * @param device The platform-specific device name for this serial + * port. + */ + basic_serial_port(const executor_type& ex, const std::string& device) + : impl_(ex) + { + boost::system::error_code ec; + impl_.get_service().open(impl_.get_implementation(), device, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param context An execution context which provides the I/O executor that + * the serial port will use, by default, to dispatch handlers for any + * asynchronous operations performed on the serial port. + * + * @param device The platform-specific device name for this serial + * port. + */ + template + basic_serial_port(ExecutionContext& context, const std::string& device, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().open(impl_.get_implementation(), device, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -116,19 +202,47 @@ public: * This constructor creates a serial port object to hold an existing native * serial port. * - * @param io_service The io_service object that the serial port will use to - * dispatch handlers for any asynchronous operations performed on the port. + * @param ex The I/O executor that the serial port will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * serial port. * * @param native_serial_port A native serial port. * * @throws boost::system::system_error Thrown on failure. */ - basic_serial_port(boost::asio::io_service& io_service, + basic_serial_port(const executor_type& ex, const native_handle_type& native_serial_port) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + native_serial_port, ec); + boost::asio::detail::throw_error(ec, "assign"); + } + + /// Construct a basic_serial_port on an existing native serial port. + /** + * This constructor creates a serial port object to hold an existing native + * serial port. + * + * @param context An execution context which provides the I/O executor that + * the serial port will use, by default, to dispatch handlers for any + * asynchronous operations performed on the serial port. + * + * @param native_serial_port A native serial port. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_serial_port(ExecutionContext& context, + const native_handle_type& native_serial_port, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -142,11 +256,11 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_serial_port(io_service&) constructor. + * constructed using the @c basic_serial_port(const executor_type&) + * constructor. */ basic_serial_port(basic_serial_port&& other) - : basic_io_object( - BOOST_ASIO_MOVE_CAST(basic_serial_port)(other)) + : impl_(std::move(other.impl_)) { } @@ -158,16 +272,32 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_serial_port(io_service&) constructor. + * constructed using the @c basic_serial_port(const executor_type&) + * constructor. */ basic_serial_port& operator=(basic_serial_port&& other) { - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_serial_port)(other)); + impl_ = std::move(other.impl_); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the serial port. + /** + * This function destroys the serial port, cancelling any outstanding + * asynchronous wait operations associated with the serial port as if by + * calling @c cancel. + */ + ~basic_serial_port() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of @@ -207,7 +337,7 @@ public: void open(const std::string& device) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -220,10 +350,11 @@ public: * * @param ec Set the indicate what error occurred, if any. */ - boost::system::error_code open(const std::string& device, + BOOST_ASIO_SYNC_OP_VOID open(const std::string& device, boost::system::error_code& ec) { - return this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native serial port to the serial port. @@ -237,7 +368,7 @@ public: void assign(const native_handle_type& native_serial_port) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -250,17 +381,18 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code assign(const native_handle_type& native_serial_port, + BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, boost::system::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the serial port is open. bool is_open() const { - return this->get_service().is_open(this->get_implementation()); + return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the serial port. @@ -274,7 +406,7 @@ public: void close() { boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "close"); } @@ -286,21 +418,10 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code close(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) { - return this->get_service().close(this->get_implementation(), ec); - } - - /// (Deprecated: Use native_handle().) Get the native serial port - /// representation. - /** - * This function may be used to obtain the underlying representation of the - * serial port. This is intended to allow access to native serial port - * functionality that is not otherwise provided. - */ - native_type native() - { - return this->get_service().native_handle(this->get_implementation()); + impl_.get_service().close(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native serial port representation. @@ -311,7 +432,7 @@ public: */ native_handle_type native_handle() { - return this->get_service().native_handle(this->get_implementation()); + return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the serial port. @@ -325,7 +446,7 @@ public: void cancel() { boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); } @@ -337,9 +458,10 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code cancel(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Send a break sequence to the serial port. @@ -352,7 +474,7 @@ public: void send_break() { boost::system::error_code ec; - this->get_service().send_break(this->get_implementation(), ec); + impl_.get_service().send_break(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "send_break"); } @@ -363,9 +485,10 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code send_break(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec) { - return this->get_service().send_break(this->get_implementation(), ec); + impl_.get_service().send_break(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the serial port. @@ -387,7 +510,7 @@ public: void set_option(const SettableSerialPortOption& option) { boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "set_option"); } @@ -407,11 +530,11 @@ public: * boost::asio::serial_port_base::character_size */ template - boost::system::error_code set_option(const SettableSerialPortOption& option, + BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, boost::system::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the serial port. @@ -434,7 +557,7 @@ public: void get_option(GettableSerialPortOption& option) { boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "get_option"); } @@ -455,11 +578,11 @@ public: * boost::asio::serial_port_base::character_size */ template - boost::system::error_code get_option(GettableSerialPortOption& option, + BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, boost::system::error_code& ec) { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Write some data to the serial port. @@ -483,7 +606,7 @@ public: * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code - * serial_port.write_some(boost::asio::buffer(data, size)); + * basic_serial_port.write_some(boost::asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or @@ -493,8 +616,8 @@ public: std::size_t write_some(const ConstBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().write_some( - this->get_implementation(), buffers, ec); + std::size_t s = impl_.get_service().write_some( + impl_.get_implementation(), buffers, ec); boost::asio::detail::throw_error(ec, "write_some"); return s; } @@ -519,8 +642,8 @@ public: std::size_t write_some(const ConstBufferSequence& buffers, boost::system::error_code& ec) { - return this->get_service().write_some( - this->get_implementation(), buffers, ec); + return impl_.get_service().write_some( + impl_.get_implementation(), buffers, ec); } /// Start an asynchronous write. @@ -541,9 +664,9 @@ public: * std::size_t bytes_transferred // Number of bytes written. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The write operation may not transmit all of the data to the peer. * Consider using the @ref async_write function if you need to ensure that all @@ -552,7 +675,8 @@ public: * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code - * serial_port.async_write_some(boost::asio::buffer(data, size), handler); + * basic_serial_port.async_write_some( + * boost::asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on writing multiple * buffers in one go, and how to use it with arrays, boost::array or @@ -564,12 +688,9 @@ public: async_write_some(const ConstBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_write_some(this->get_implementation(), - buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_write_some(), handler, this, buffers); } /// Read some data from the serial port. @@ -594,7 +715,7 @@ public: * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code - * serial_port.read_some(boost::asio::buffer(data, size)); + * basic_serial_port.read_some(boost::asio::buffer(data, size)); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or @@ -604,8 +725,8 @@ public: std::size_t read_some(const MutableBufferSequence& buffers) { boost::system::error_code ec; - std::size_t s = this->get_service().read_some( - this->get_implementation(), buffers, ec); + std::size_t s = impl_.get_service().read_some( + impl_.get_implementation(), buffers, ec); boost::asio::detail::throw_error(ec, "read_some"); return s; } @@ -631,8 +752,8 @@ public: std::size_t read_some(const MutableBufferSequence& buffers, boost::system::error_code& ec) { - return this->get_service().read_some( - this->get_implementation(), buffers, ec); + return impl_.get_service().read_some( + impl_.get_implementation(), buffers, ec); } /// Start an asynchronous read. @@ -653,9 +774,9 @@ public: * std::size_t bytes_transferred // Number of bytes read. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @note The read operation may not read all of the requested number of bytes. * Consider using the @ref async_read function if you need to ensure that the @@ -665,7 +786,8 @@ public: * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code - * serial_port.async_read_some(boost::asio::buffer(data, size), handler); + * basic_serial_port.async_read_some( + * boost::asio::buffer(data, size), handler); * @endcode * See the @ref buffer documentation for information on reading into multiple * buffers in one go, and how to use it with arrays, boost::array or @@ -677,13 +799,55 @@ public: async_read_some(const MutableBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_read_some(this->get_implementation(), - buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_read_some(), handler, this, buffers); } + +private: + // Disallow copying and assignment. + basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED; + basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED; + + struct initiate_async_write_some + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, + basic_serial_port* self, const ConstBufferSequence& buffers) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_write_some( + self->impl_.get_implementation(), buffers, handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_read_some + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, + basic_serial_port* self, const MutableBufferSequence& buffers) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_read_some( + self->impl_.get_implementation(), buffers, handler2.value, + self->impl_.get_implementation_executor()); + } + }; + +#if defined(BOOST_ASIO_HAS_IOCP) + detail::io_object_impl impl_; +#else + detail::io_object_impl impl_; +#endif }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_signal_set.hpp b/linx64/include/boost/asio/basic_signal_set.hpp index 608bc0a6..175b4f48 100644 --- a/linx64/include/boost/asio/basic_signal_set.hpp +++ b/linx64/include/boost/asio/basic_signal_set.hpp @@ -2,7 +2,7 @@ // basic_signal_set.hpp // ~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,23 +17,24 @@ #include -#include +#include #include +#include +#include +#include #include +#include #include -#include - -#include +#include +#include namespace boost { namespace asio { /// Provides signal functionality. /** - * The basic_signal_set class template provides the ability to perform an - * asynchronous wait for one or more signals to occur. - * - * Most applications will use the boost::asio::signal_set typedef. + * The basic_signal_set class provides the ability to perform an asynchronous + * wait for one or more signals to occur. * * @par Thread Safety * @e Distinct @e objects: Safe.@n @@ -55,7 +56,7 @@ namespace asio { * ... * * // Construct a signal set registered for process termination. - * boost::asio::signal_set signals(io_service, SIGINT, SIGTERM); + * boost::asio::signal_set signals(my_context, SIGINT, SIGTERM); * * // Start an asynchronous wait for one of the signals to occur. * signals.async_wait(handler); @@ -90,20 +91,40 @@ namespace asio { * that any signals registered using signal_set objects are unblocked in at * least one thread. */ -template +template class basic_signal_set - : public basic_io_object { public: + /// The type of the executor associated with the object. + typedef Executor executor_type; + /// Construct a signal set without adding any signals. /** * This constructor creates a signal set without registering for any signals. * - * @param io_service The io_service object that the signal set will use to - * dispatch handlers for any asynchronous operations performed on the set. + * @param ex The I/O executor that the signal set will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * signal set. */ - explicit basic_signal_set(boost::asio::io_service& io_service) - : basic_io_object(io_service) + explicit basic_signal_set(const executor_type& ex) + : impl_(ex) + { + } + + /// Construct a signal set without adding any signals. + /** + * This constructor creates a signal set without registering for any signals. + * + * @param context An execution context which provides the I/O executor that + * the signal set will use, by default, to dispatch handlers for any + * asynchronous operations performed on the signal set. + */ + template + explicit basic_signal_set(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -111,20 +132,47 @@ public: /** * This constructor creates a signal set and registers for one signal. * - * @param io_service The io_service object that the signal set will use to - * dispatch handlers for any asynchronous operations performed on the set. + * @param ex The I/O executor that the signal set will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * signal set. * * @param signal_number_1 The signal number to be added. * * @note This constructor is equivalent to performing: - * @code boost::asio::signal_set signals(io_service); + * @code boost::asio::signal_set signals(ex); * signals.add(signal_number_1); @endcode */ - basic_signal_set(boost::asio::io_service& io_service, int signal_number_1) - : basic_io_object(io_service) + basic_signal_set(const executor_type& ex, int signal_number_1) + : impl_(ex) { boost::system::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + boost::asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add one signal. + /** + * This constructor creates a signal set and registers for one signal. + * + * @param context An execution context which provides the I/O executor that + * the signal set will use, by default, to dispatch handlers for any + * asynchronous operations performed on the signal set. + * + * @param signal_number_1 The signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code boost::asio::signal_set signals(context); + * signals.add(signal_number_1); @endcode + */ + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); boost::asio::detail::throw_error(ec, "add"); } @@ -132,26 +180,59 @@ public: /** * This constructor creates a signal set and registers for two signals. * - * @param io_service The io_service object that the signal set will use to - * dispatch handlers for any asynchronous operations performed on the set. + * @param ex The I/O executor that the signal set will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * signal set. * * @param signal_number_1 The first signal number to be added. * * @param signal_number_2 The second signal number to be added. * * @note This constructor is equivalent to performing: - * @code boost::asio::signal_set signals(io_service); + * @code boost::asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); @endcode */ - basic_signal_set(boost::asio::io_service& io_service, int signal_number_1, + basic_signal_set(const executor_type& ex, int signal_number_1, int signal_number_2) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); boost::asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_2, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); + boost::asio::detail::throw_error(ec, "add"); + } + + /// Construct a signal set and add two signals. + /** + * This constructor creates a signal set and registers for two signals. + * + * @param context An execution context which provides the I/O executor that + * the signal set will use, by default, to dispatch handlers for any + * asynchronous operations performed on the signal set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code boost::asio::signal_set signals(context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); @endcode + */ + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + int signal_number_2, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + boost::asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); boost::asio::detail::throw_error(ec, "add"); } @@ -159,8 +240,9 @@ public: /** * This constructor creates a signal set and registers for three signals. * - * @param io_service The io_service object that the signal set will use to - * dispatch handlers for any asynchronous operations performed on the set. + * @param ex The I/O executor that the signal set will use, by default, to + * dispatch handlers for any asynchronous operations performed on the + * signal set. * * @param signal_number_1 The first signal number to be added. * @@ -169,24 +251,77 @@ public: * @param signal_number_3 The third signal number to be added. * * @note This constructor is equivalent to performing: - * @code boost::asio::signal_set signals(io_service); + * @code boost::asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); * signals.add(signal_number_3); @endcode */ - basic_signal_set(boost::asio::io_service& io_service, int signal_number_1, + basic_signal_set(const executor_type& ex, int signal_number_1, int signal_number_2, int signal_number_3) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); boost::asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_2, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); boost::asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_3, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); boost::asio::detail::throw_error(ec, "add"); } + /// Construct a signal set and add three signals. + /** + * This constructor creates a signal set and registers for three signals. + * + * @param context An execution context which provides the I/O executor that + * the signal set will use, by default, to dispatch handlers for any + * asynchronous operations performed on the signal set. + * + * @param signal_number_1 The first signal number to be added. + * + * @param signal_number_2 The second signal number to be added. + * + * @param signal_number_3 The third signal number to be added. + * + * @note This constructor is equivalent to performing: + * @code boost::asio::signal_set signals(context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); + * signals.add(signal_number_3); @endcode + */ + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + int signal_number_2, int signal_number_3, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + boost::asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); + boost::asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); + boost::asio::detail::throw_error(ec, "add"); + } + + /// Destroys the signal set. + /** + * This function destroys the signal set, cancelling any outstanding + * asynchronous wait operations associated with the signal set as if by + * calling @c cancel. + */ + ~basic_signal_set() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Add a signal to a signal_set. /** * This function adds the specified signal to the set. It has no effect if the @@ -199,7 +334,7 @@ public: void add(int signal_number) { boost::system::error_code ec; - this->service.add(this->implementation, signal_number, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number, ec); boost::asio::detail::throw_error(ec, "add"); } @@ -212,10 +347,11 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code add(int signal_number, + BOOST_ASIO_SYNC_OP_VOID add(int signal_number, boost::system::error_code& ec) { - return this->service.add(this->implementation, signal_number, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove a signal from a signal_set. @@ -233,7 +369,7 @@ public: void remove(int signal_number) { boost::system::error_code ec; - this->service.remove(this->implementation, signal_number, ec); + impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); boost::asio::detail::throw_error(ec, "remove"); } @@ -249,10 +385,11 @@ public: * @note Removes any notifications that have been queued for the specified * signal number. */ - boost::system::error_code remove(int signal_number, + BOOST_ASIO_SYNC_OP_VOID remove(int signal_number, boost::system::error_code& ec) { - return this->service.remove(this->implementation, signal_number, ec); + impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove all signals from a signal_set. @@ -267,7 +404,7 @@ public: void clear() { boost::system::error_code ec; - this->service.clear(this->implementation, ec); + impl_.get_service().clear(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "clear"); } @@ -280,9 +417,10 @@ public: * * @note Removes all queued notifications. */ - boost::system::error_code clear(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec) { - return this->service.clear(this->implementation, ec); + impl_.get_service().clear(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Cancel all operations associated with the signal set. @@ -309,7 +447,7 @@ public: void cancel() { boost::system::error_code ec; - this->service.cancel(this->implementation, ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); } @@ -334,9 +472,10 @@ public: * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ - boost::system::error_code cancel(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) { - return this->service.cancel(this->implementation, ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous operation to wait for a signal to be delivered. @@ -360,27 +499,45 @@ public: * int signal_number // Indicates which signal occurred. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler, void (boost::system::error_code, int)) async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a SignalHandler. - BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; - - return this->service.async_wait(this->implementation, - BOOST_ASIO_MOVE_CAST(SignalHandler)(handler)); + return async_initiate( + initiate_async_wait(), handler, this); } + +private: + // Disallow copying and assignment. + basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED; + basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler, + basic_signal_set* self) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a SignalHandler. + BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + detail::io_object_impl impl_; }; } // namespace asio } // namespace boost -#include - #endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP diff --git a/linx64/include/boost/asio/basic_socket.hpp b/linx64/include/boost/asio/basic_socket.hpp index 777f6a9c..4f15f58a 100644 --- a/linx64/include/boost/asio/basic_socket.hpp +++ b/linx64/include/boost/asio/basic_socket.hpp @@ -2,7 +2,7 @@ // basic_socket.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,18 +17,43 @@ #include #include -#include #include +#include +#include #include #include #include +#include +#include +#include #include +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +#elif defined(BOOST_ASIO_HAS_IOCP) +# include +#else +# include +#endif + +#if defined(BOOST_ASIO_HAS_MOVE) +# include +#endif // defined(BOOST_ASIO_HAS_MOVE) + #include namespace boost { namespace asio { +#if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL) +#define BOOST_ASIO_BASIC_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_socket; + +#endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL) + /// Provides socket functionality. /** * The basic_socket class template provides functionality that is common to both @@ -38,18 +63,35 @@ namespace asio { * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template +template class basic_socket - : public basic_io_object, - public socket_base + : public socket_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename SocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_socket other; + }; /// The native representation of a socket. - typedef typename SocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) + typedef typename detail::null_socket_service< + Protocol>::native_handle_type native_handle_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef typename detail::win_iocp_socket_service< + Protocol>::native_handle_type native_handle_type; +#else + typedef typename detail::reactive_socket_service< + Protocol>::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -57,18 +99,37 @@ public: /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; +#if !defined(BOOST_ASIO_NO_EXTENSIONS) /// A basic_socket is always the lowest layer. - typedef basic_socket lowest_layer_type; + typedef basic_socket lowest_layer_type; +#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) /// Construct a basic_socket without opening it. /** * This constructor creates a socket without opening it. * - * @param io_service The io_service object that the socket will use to + * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. */ - explicit basic_socket(boost::asio::io_service& io_service) - : basic_io_object(io_service) + explicit basic_socket(const executor_type& ex) + : impl_(ex) + { + } + + /// Construct a basic_socket without opening it. + /** + * This constructor creates a socket without opening it. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + */ + template + explicit basic_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -76,19 +137,42 @@ public: /** * This constructor creates and opens a socket. * - * @param io_service The io_service object that the socket will use to + * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. * * @throws boost::system::system_error Thrown on failure. */ - basic_socket(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const protocol_type& protocol) + : impl_(ex) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Construct and open a basic_socket. + /** + * This constructor creates and opens a socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -99,7 +183,7 @@ public: * specified endpoint on the local machine. The protocol used is the protocol * associated with the given endpoint. * - * @param io_service The io_service object that the socket will use to + * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param endpoint An endpoint on the local machine to which the socket will @@ -107,15 +191,45 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_socket(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const endpoint_type& endpoint) + : impl_(ex) { boost::system::error_code ec; const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + boost::asio::detail::throw_error(ec, "bind"); + } + + /// Construct a basic_socket, opening it and binding it to the given local + /// endpoint. + /** + * This constructor creates a socket and automatically opens it bound to the + * specified endpoint on the local machine. The protocol used is the protocol + * associated with the given endpoint. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + const protocol_type protocol = endpoint.protocol(); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); boost::asio::detail::throw_error(ec, "bind"); } @@ -123,7 +237,7 @@ public: /** * This constructor creates a socket object to hold an existing native socket. * - * @param io_service The io_service object that the socket will use to + * @param ex The I/O executor that the socket will use, by default, to * dispatch handlers for any asynchronous operations performed on the socket. * * @param protocol An object specifying protocol parameters to be used. @@ -132,12 +246,40 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_socket(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const protocol_type& protocol, + const native_handle_type& native_socket) + : impl_(ex) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + protocol, native_socket, ec); + boost::asio::detail::throw_error(ec, "assign"); + } + + /// Construct a basic_socket on an existing native socket. + /** + * This constructor creates a socket object to hold an existing native socket. + * + * @param context An execution context which provides the I/O executor that + * the socket will use, by default, to dispatch handlers for any asynchronous + * operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket A native socket. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const protocol_type& protocol, + const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -151,11 +293,10 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket(basic_socket&& other) - : basic_io_object( - BOOST_ASIO_MOVE_CAST(basic_socket)(other)) + : impl_(std::move(other.impl_)) { } @@ -167,17 +308,16 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket& operator=(basic_socket&& other) { - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket)(other)); + impl_ = std::move(other.impl_); return *this; } // All sockets have access to each other's implementations. - template + template friend class basic_socket; /// Move-construct a basic_socket from a socket of another protocol type. @@ -188,13 +328,15 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ - template - basic_socket(basic_socket&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) + template + basic_socket(basic_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : impl_(std::move(other.impl_)) { } @@ -206,21 +348,28 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ - template - typename enable_if::value, - basic_socket>::type& operator=( - basic_socket&& other) + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_socket& + >::type operator=(basic_socket && other) { - basic_socket tmp(BOOST_ASIO_MOVE_CAST2(basic_socket< - Protocol1, SocketService1>)(other)); - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket)(tmp)); + basic_socket tmp(std::move(other)); + impl_ = std::move(tmp.impl_); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + +#if !defined(BOOST_ASIO_NO_EXTENSIONS) /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of @@ -248,6 +397,7 @@ public: { return *this; } +#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) /// Open the socket using the specified protocol. /** @@ -259,14 +409,14 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * socket.open(boost::asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -280,7 +430,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::system::error_code ec; * socket.open(boost::asio::ip::tcp::v4(), ec); * if (ec) @@ -289,10 +439,11 @@ public: * } * @endcode */ - boost::system::error_code open(const protocol_type& protocol, + BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, boost::system::error_code& ec) { - return this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native socket to the socket. @@ -309,7 +460,7 @@ public: const native_handle_type& native_socket) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -324,17 +475,18 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code assign(const protocol_type& protocol, + BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_socket, boost::system::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the socket is open. bool is_open() const { - return this->get_service().is_open(this->get_implementation()); + return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the socket. @@ -352,7 +504,7 @@ public: void close() { boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "close"); } @@ -367,7 +519,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::system::error_code ec; * socket.close(ec); @@ -380,20 +532,62 @@ public: * @note For portable behaviour with respect to graceful closure of a * connected socket, call shutdown() before closing the socket. */ - boost::system::error_code close(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) { - return this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } - /// (Deprecated: Use native_handle().) Get the native socket representation. + /// Release ownership of the underlying native socket. /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. Ownership + * of the native socket is then transferred to the caller. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with boost::asio::error::operation_not_supported on + * these platforms. */ - native_type native() +#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release() { - return this->get_service().native_handle(this->get_implementation()); + boost::system::error_code ec; + native_handle_type s = impl_.get_service().release( + impl_.get_implementation(), ec); + boost::asio::detail::throw_error(ec, "release"); + return s; + } + + /// Release ownership of the underlying native socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. Ownership + * of the native socket is then transferred to the caller. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with boost::asio::error::operation_not_supported on + * these platforms. + */ +#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release(boost::system::error_code& ec) + { + return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native socket representation. @@ -404,7 +598,7 @@ public: */ native_handle_type native_handle() { - return this->get_service().native_handle(this->get_implementation()); + return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the socket. @@ -451,7 +645,7 @@ public: void cancel() { boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); } @@ -496,9 +690,10 @@ public: "operation_not_supported when used on Windows XP, Windows Server 2003, " "or earlier. Consult documentation for details.")) #endif - boost::system::error_code cancel(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the socket is at the out-of-band data mark. @@ -514,7 +709,7 @@ public: bool at_mark() const { boost::system::error_code ec; - bool b = this->get_service().at_mark(this->get_implementation(), ec); + bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "at_mark"); return b; } @@ -531,7 +726,7 @@ public: */ bool at_mark(boost::system::error_code& ec) const { - return this->get_service().at_mark(this->get_implementation(), ec); + return impl_.get_service().at_mark(impl_.get_implementation(), ec); } /// Determine the number of bytes available for reading. @@ -547,8 +742,8 @@ public: std::size_t available() const { boost::system::error_code ec; - std::size_t s = this->get_service().available( - this->get_implementation(), ec); + std::size_t s = impl_.get_service().available( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "available"); return s; } @@ -565,7 +760,7 @@ public: */ std::size_t available(boost::system::error_code& ec) const { - return this->get_service().available(this->get_implementation(), ec); + return impl_.get_service().available(impl_.get_implementation(), ec); } /// Bind the socket to the given local endpoint. @@ -580,7 +775,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * socket.open(boost::asio::ip::tcp::v4()); * socket.bind(boost::asio::ip::tcp::endpoint( * boost::asio::ip::tcp::v4(), 12345)); @@ -589,7 +784,7 @@ public: void bind(const endpoint_type& endpoint) { boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); boost::asio::detail::throw_error(ec, "bind"); } @@ -605,7 +800,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * socket.open(boost::asio::ip::tcp::v4()); * boost::system::error_code ec; * socket.bind(boost::asio::ip::tcp::endpoint( @@ -616,10 +811,11 @@ public: * } * @endcode */ - boost::system::error_code bind(const endpoint_type& endpoint, + BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, boost::system::error_code& ec) { - return this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Connect the socket to the specified endpoint. @@ -639,7 +835,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::asio::ip::tcp::endpoint endpoint( * boost::asio::ip::address::from_string("1.2.3.4"), 12345); * socket.connect(endpoint); @@ -650,11 +846,11 @@ public: boost::system::error_code ec; if (!is_open()) { - this->get_service().open(this->get_implementation(), + impl_.get_service().open(impl_.get_implementation(), peer_endpoint.protocol(), ec); boost::asio::detail::throw_error(ec, "connect"); } - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); + impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); boost::asio::detail::throw_error(ec, "connect"); } @@ -675,7 +871,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::asio::ip::tcp::endpoint endpoint( * boost::asio::ip::address::from_string("1.2.3.4"), 12345); * boost::system::error_code ec; @@ -686,20 +882,21 @@ public: * } * @endcode */ - boost::system::error_code connect(const endpoint_type& peer_endpoint, + BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, boost::system::error_code& ec) { if (!is_open()) { - if (this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec)) + impl_.get_service().open(impl_.get_implementation(), + peer_endpoint.protocol(), ec); + if (ec) { - return ec; + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } } - return this->get_service().connect( - this->get_implementation(), peer_endpoint, ec); + impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous connect. @@ -721,9 +918,9 @@ public: * const boost::system::error_code& error // Result of operation * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * @code @@ -737,7 +934,7 @@ public: * * ... * - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::asio::ip::tcp::endpoint endpoint( * boost::asio::ip::address::from_string("1.2.3.4"), 12345); * socket.async_connect(endpoint, connect_handler); @@ -749,32 +946,15 @@ public: async_connect(const endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - + boost::system::error_code open_ec; if (!is_open()) { - boost::system::error_code ec; const protocol_type protocol = peer_endpoint.protocol(); - if (this->get_service().open(this->get_implementation(), protocol, ec)) - { - detail::async_result_init< - ConnectHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); - - this->get_io_service().post( - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( - ConnectHandler, void (boost::system::error_code)))( - init.handler), ec)); - - return init.result.get(); - } + impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); } - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); + return async_initiate( + initiate_async_connect(), handler, this, peer_endpoint, open_ec); } /// Set an option on the socket. @@ -805,7 +985,7 @@ public: * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::no_delay option(true); * socket.set_option(option); @@ -815,7 +995,7 @@ public: void set_option(const SettableSocketOption& option) { boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "set_option"); } @@ -847,7 +1027,7 @@ public: * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::no_delay option(true); * boost::system::error_code ec; @@ -859,11 +1039,11 @@ public: * @endcode */ template - boost::system::error_code set_option(const SettableSocketOption& option, + BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, boost::system::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the socket. @@ -894,7 +1074,7 @@ public: * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::socket::keep_alive option; * socket.get_option(option); @@ -905,7 +1085,7 @@ public: void get_option(GettableSocketOption& option) const { boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "get_option"); } @@ -937,7 +1117,7 @@ public: * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::socket::keep_alive option; * boost::system::error_code ec; @@ -950,11 +1130,11 @@ public: * @endcode */ template - boost::system::error_code get_option(GettableSocketOption& option, + BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, boost::system::error_code& ec) const { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the socket. @@ -972,7 +1152,7 @@ public: * @par Example * Getting the number of bytes ready to read: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::socket::bytes_readable command; * socket.io_control(command); @@ -983,7 +1163,7 @@ public: void io_control(IoControlCommand& command) { boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); boost::asio::detail::throw_error(ec, "io_control"); } @@ -1002,7 +1182,7 @@ public: * @par Example * Getting the number of bytes ready to read: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::socket::bytes_readable command; * boost::system::error_code ec; @@ -1015,11 +1195,11 @@ public: * @endcode */ template - boost::system::error_code io_control(IoControlCommand& command, + BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, boost::system::error_code& ec) { - return this->get_service().io_control( - this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the socket. @@ -1035,7 +1215,7 @@ public: */ bool non_blocking() const { - return this->get_service().non_blocking(this->get_implementation()); + return impl_.get_service().non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the socket. @@ -1054,7 +1234,7 @@ public: void non_blocking(bool mode) { boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); boost::asio::detail::throw_error(ec, "non_blocking"); } @@ -1071,11 +1251,11 @@ public: * operations. Asynchronous operations will never fail with the error * boost::asio::error::would_block. */ - boost::system::error_code non_blocking( + BOOST_ASIO_SYNC_OP_VOID non_blocking( bool mode, boost::system::error_code& ec) { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native socket implementation. @@ -1135,7 +1315,7 @@ public: * || ec == boost::asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(boost::asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1159,12 +1339,12 @@ public: * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(boost::asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ bool native_non_blocking() const { - return this->get_service().native_non_blocking(this->get_implementation()); + return impl_.get_service().native_non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the native socket implementation. @@ -1225,7 +1405,7 @@ public: * || ec == boost::asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(boost::asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1249,14 +1429,14 @@ public: * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(boost::asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ void native_non_blocking(bool mode) { boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); boost::asio::detail::throw_error(ec, "native_non_blocking"); } @@ -1318,7 +1498,7 @@ public: * || ec == boost::asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(boost::asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1342,14 +1522,15 @@ public: * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(boost::asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ - boost::system::error_code native_non_blocking( + BOOST_ASIO_SYNC_OP_VOID native_non_blocking( bool mode, boost::system::error_code& ec) { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the socket. @@ -1362,7 +1543,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); * @endcode @@ -1370,8 +1551,8 @@ public: endpoint_type local_endpoint() const { boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); + endpoint_type ep = impl_.get_service().local_endpoint( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "local_endpoint"); return ep; } @@ -1387,7 +1568,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::system::error_code ec; * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); @@ -1399,7 +1580,7 @@ public: */ endpoint_type local_endpoint(boost::system::error_code& ec) const { - return this->get_service().local_endpoint(this->get_implementation(), ec); + return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); } /// Get the remote endpoint of the socket. @@ -1412,7 +1593,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); * @endcode @@ -1420,8 +1601,8 @@ public: endpoint_type remote_endpoint() const { boost::system::error_code ec; - endpoint_type ep = this->get_service().remote_endpoint( - this->get_implementation(), ec); + endpoint_type ep = impl_.get_service().remote_endpoint( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "remote_endpoint"); return ep; } @@ -1437,7 +1618,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::system::error_code ec; * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); @@ -1449,7 +1630,7 @@ public: */ endpoint_type remote_endpoint(boost::system::error_code& ec) const { - return this->get_service().remote_endpoint(this->get_implementation(), ec); + return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); } /// Disable sends or receives on the socket. @@ -1464,7 +1645,7 @@ public: * @par Example * Shutting down the send side of the socket: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); * @endcode @@ -1472,7 +1653,7 @@ public: void shutdown(shutdown_type what) { boost::system::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); + impl_.get_service().shutdown(impl_.get_implementation(), what, ec); boost::asio::detail::throw_error(ec, "shutdown"); } @@ -1488,7 +1669,7 @@ public: * @par Example * Shutting down the send side of the socket: * @code - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * ... * boost::system::error_code ec; * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); @@ -1498,17 +1679,175 @@ public: * } * @endcode */ - boost::system::error_code shutdown(shutdown_type what, + BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, boost::system::error_code& ec) { - return this->get_service().shutdown(this->get_implementation(), what, ec); + impl_.get_service().shutdown(impl_.get_implementation(), what, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + /** + * This function is used to perform a blocking wait for a socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket state. + * + * @par Example + * Waiting for a socket to become readable. + * @code + * boost::asio::ip::tcp::socket socket(my_context); + * ... + * socket.wait(boost::asio::ip::tcp::socket::wait_read); + * @endcode + */ + void wait(wait_type w) + { + boost::system::error_code ec; + impl_.get_service().wait(impl_.get_implementation(), w, ec); + boost::asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the socket to become ready to read, ready to write, or to have + /// pending error conditions. + /** + * This function is used to perform a blocking wait for a socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for a socket to become readable. + * @code + * boost::asio::ip::tcp::socket socket(my_context); + * ... + * boost::system::error_code ec; + * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); + * @endcode + */ + BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) + { + impl_.get_service().wait(impl_.get_implementation(), w, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously wait for the socket to become ready to read, ready to + /// write, or to have pending error conditions. + /** + * This function is used to perform an asynchronous wait for a socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket state. + * + * @param handler The handler to be called when the wait operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void wait_handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::socket socket(my_context); + * ... + * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (boost::system::error_code)) + async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) + { + return async_initiate( + initiate_async_wait(), handler, this, w); } protected: /// Protected destructor to prevent deletion through this type. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ ~basic_socket() { } + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + detail::io_object_impl< + detail::null_socket_service, Executor> impl_; +#elif defined(BOOST_ASIO_HAS_IOCP) + detail::io_object_impl< + detail::win_iocp_socket_service, Executor> impl_; +#else + detail::io_object_impl< + detail::reactive_socket_service, Executor> impl_; +#endif + +private: + // Disallow copying and assignment. + basic_socket(const basic_socket&) BOOST_ASIO_DELETED; + basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED; + + struct initiate_async_connect + { + template + void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, + basic_socket* self, const endpoint_type& peer_endpoint, + const boost::system::error_code& open_ec) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ConnectHandler. + BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; + + if (open_ec) + { + boost::asio::post(self->impl_.get_executor(), + boost::asio::detail::bind_handler( + BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); + } + else + { + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_connect( + self->impl_.get_implementation(), peer_endpoint, + handler2.value, self->impl_.get_implementation_executor()); + } + } + }; + + struct initiate_async_wait + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, + basic_socket* self, wait_type w) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WaitHandler. + BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), w, handler2.value, + self->impl_.get_implementation_executor()); + } + }; }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_socket_acceptor.hpp b/linx64/include/boost/asio/basic_socket_acceptor.hpp index f1d2b8e7..12613b82 100644 --- a/linx64/include/boost/asio/basic_socket_acceptor.hpp +++ b/linx64/include/boost/asio/basic_socket_acceptor.hpp @@ -2,7 +2,7 @@ // basic_socket_acceptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,20 +16,43 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include #include #include +#include +#include #include #include #include -#include +#include +#include #include +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +#elif defined(BOOST_ASIO_HAS_IOCP) +# include +#else +# include +#endif + +#if defined(BOOST_ASIO_HAS_MOVE) +# include +#endif // defined(BOOST_ASIO_HAS_MOVE) + #include namespace boost { namespace asio { +#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) +#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_socket_acceptor; + +#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) + /// Provides the ability to accept new connections. /** * The basic_socket_acceptor class template is used for accepting new socket @@ -42,7 +65,7 @@ namespace asio { * @par Example * Opening a socket acceptor with the SO_REUSEADDR option enabled: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); * acceptor.open(endpoint.protocol()); * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); @@ -50,19 +73,27 @@ namespace asio { * acceptor.listen(); * @endcode */ -template > +template class basic_socket_acceptor - : public basic_io_object, - public socket_base + : public socket_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of an - /// acceptor. - typedef typename SocketAcceptorService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; /// The native representation of an acceptor. - typedef typename SocketAcceptorService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) + typedef typename detail::null_socket_service< + Protocol>::native_handle_type native_handle_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef typename detail::win_iocp_socket_service< + Protocol>::native_handle_type native_handle_type; +#else + typedef typename detail::reactive_socket_service< + Protocol>::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -76,12 +107,31 @@ public: * connections. The open() function must be called before the acceptor can * accept new socket connections. * - * @param io_service The io_service object that the acceptor will use to + * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. */ - explicit basic_socket_acceptor(boost::asio::io_service& io_service) - : basic_io_object(io_service) + explicit basic_socket_acceptor(const executor_type& ex) + : impl_(ex) + { + } + + /// Construct an acceptor without opening it. + /** + * This constructor creates an acceptor without opening it to listen for new + * connections. The open() function must be called before the acceptor can + * accept new socket connections. + * + * @param context An execution context which provides the I/O executor that + * the acceptor will use, by default, to dispatch handlers for any + * asynchronous operations performed on the acceptor. + */ + template + explicit basic_socket_acceptor(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -89,7 +139,7 @@ public: /** * This constructor creates an acceptor and automatically opens it. * - * @param io_service The io_service object that the acceptor will use to + * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * @@ -97,12 +147,36 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_socket_acceptor(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) + : impl_(ex) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Construct an open acceptor. + /** + * This constructor creates an acceptor and automatically opens it. + * + * @param context An execution context which provides the I/O executor that + * the acceptor will use, by default, to dispatch handlers for any + * asynchronous operations performed on the acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_socket_acceptor(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -111,7 +185,7 @@ public: * This constructor creates an acceptor and automatically opens it to listen * for new connections on the specified endpoint. * - * @param io_service The io_service object that the acceptor will use to + * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * @@ -125,32 +199,84 @@ public: * * @note This constructor is equivalent to the following code: * @code - * basic_socket_acceptor acceptor(io_service); + * basic_socket_acceptor acceptor(my_context); * acceptor.open(endpoint.protocol()); * if (reuse_addr) * acceptor.set_option(socket_base::reuse_address(true)); * acceptor.bind(endpoint); - * acceptor.listen(listen_backlog); + * acceptor.listen(); * @endcode */ - basic_socket_acceptor(boost::asio::io_service& io_service, + basic_socket_acceptor(const executor_type& ex, const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); if (reuse_addr) { - this->get_service().set_option(this->get_implementation(), + impl_.get_service().set_option(impl_.get_implementation(), socket_base::reuse_address(true), ec); boost::asio::detail::throw_error(ec, "set_option"); } - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); boost::asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_connections, ec); + impl_.get_service().listen(impl_.get_implementation(), + socket_base::max_listen_connections, ec); + boost::asio::detail::throw_error(ec, "listen"); + } + + /// Construct an acceptor opened on the given endpoint. + /** + * This constructor creates an acceptor and automatically opens it to listen + * for new connections on the specified endpoint. + * + * @param context An execution context which provides the I/O executor that + * the acceptor will use, by default, to dispatch handlers for any + * asynchronous operations performed on the acceptor. + * + * @param endpoint An endpoint on the local machine on which the acceptor + * will listen for new connections. + * + * @param reuse_addr Whether the constructor should set the socket option + * socket_base::reuse_address. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor acceptor(my_context); + * acceptor.open(endpoint.protocol()); + * if (reuse_addr) + * acceptor.set_option(socket_base::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(); + * @endcode + */ + template + basic_socket_acceptor(ExecutionContext& context, + const endpoint_type& endpoint, bool reuse_addr = true, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + const protocol_type protocol = endpoint.protocol(); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + if (reuse_addr) + { + impl_.get_service().set_option(impl_.get_implementation(), + socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "set_option"); + } + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + boost::asio::detail::throw_error(ec, "bind"); + impl_.get_service().listen(impl_.get_implementation(), + socket_base::max_listen_connections, ec); boost::asio::detail::throw_error(ec, "listen"); } @@ -159,7 +285,7 @@ public: * This constructor creates an acceptor object to hold an existing native * acceptor. * - * @param io_service The io_service object that the acceptor will use to + * @param ex The I/O executor that the acceptor will use, by default, to * dispatch handlers for any asynchronous operations performed on the * acceptor. * @@ -169,12 +295,41 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - basic_socket_acceptor(boost::asio::io_service& io_service, + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_service) + : impl_(ex) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec, "assign"); + } + + /// Construct a basic_socket_acceptor on an existing native acceptor. + /** + * This constructor creates an acceptor object to hold an existing native + * acceptor. + * + * @param context An execution context which provides the I/O executor that + * the acceptor will use, by default, to dispatch handlers for any + * asynchronous operations performed on the acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + basic_socket_acceptor(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_acceptor, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -188,11 +343,11 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ basic_socket_acceptor(basic_socket_acceptor&& other) - : basic_io_object( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other)) + : impl_(std::move(other.impl_)) { } @@ -204,17 +359,17 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ basic_socket_acceptor& operator=(basic_socket_acceptor&& other) { - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(other)); + impl_ = std::move(other.impl_); return *this; } // All socket acceptors have access to each other's implementations. - template + template friend class basic_socket_acceptor; /// Move-construct a basic_socket_acceptor from an acceptor of another @@ -226,14 +381,16 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ - template - basic_socket_acceptor( - basic_socket_acceptor&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) + template + basic_socket_acceptor(basic_socket_acceptor&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : impl_(std::move(other.impl_)) { } @@ -246,21 +403,38 @@ public: * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_socket_acceptor>::type& operator=( - basic_socket_acceptor&& other) + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_socket_acceptor& + >::type operator=(basic_socket_acceptor&& other) { - basic_socket_acceptor tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor< - Protocol1, SocketAcceptorService1>)(other)); - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor)(tmp)); + basic_socket_acceptor tmp(std::move(other)); + impl_ = std::move(tmp.impl_); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the acceptor. + /** + * This function destroys the acceptor, cancelling any outstanding + * asynchronous operations associated with the acceptor as if by calling + * @c cancel. + */ + ~basic_socket_acceptor() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() BOOST_ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Open the acceptor using the specified protocol. /** * This function opens the socket acceptor so that it will use the specified @@ -272,14 +446,14 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * acceptor.open(boost::asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); boost::asio::detail::throw_error(ec, "open"); } @@ -294,7 +468,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * boost::system::error_code ec; * acceptor.open(boost::asio::ip::tcp::v4(), ec); * if (ec) @@ -303,10 +477,11 @@ public: * } * @endcode */ - boost::system::error_code open(const protocol_type& protocol, + BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, boost::system::error_code& ec) { - return this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assigns an existing native acceptor to the acceptor. @@ -323,7 +498,7 @@ public: const native_handle_type& native_acceptor) { boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); boost::asio::detail::throw_error(ec, "assign"); } @@ -338,17 +513,18 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code assign(const protocol_type& protocol, + BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_acceptor, boost::system::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the acceptor is open. bool is_open() const { - return this->get_service().is_open(this->get_implementation()); + return impl_.get_service().is_open(impl_.get_implementation()); } /// Bind the acceptor to the given local endpoint. @@ -363,7 +539,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * acceptor.bind(endpoint); @@ -372,7 +548,7 @@ public: void bind(const endpoint_type& endpoint) { boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); boost::asio::detail::throw_error(ec, "bind"); } @@ -388,7 +564,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * boost::system::error_code ec; @@ -399,10 +575,11 @@ public: * } * @endcode */ - boost::system::error_code bind(const endpoint_type& endpoint, + BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, boost::system::error_code& ec) { - return this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Place the acceptor into the state where it will listen for new @@ -415,10 +592,10 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - void listen(int backlog = socket_base::max_connections) + void listen(int backlog = socket_base::max_listen_connections) { boost::system::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); + impl_.get_service().listen(impl_.get_implementation(), backlog, ec); boost::asio::detail::throw_error(ec, "listen"); } @@ -434,19 +611,20 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_connections, ec); + * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); * if (ec) * { * // An error occurred. * } * @endcode */ - boost::system::error_code listen(int backlog, boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) { - return this->get_service().listen(this->get_implementation(), backlog, ec); + impl_.get_service().listen(impl_.get_implementation(), backlog, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Close the acceptor. @@ -462,7 +640,7 @@ public: void close() { boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "close"); } @@ -478,7 +656,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::system::error_code ec; * acceptor.close(ec); @@ -488,20 +666,62 @@ public: * } * @endcode */ - boost::system::error_code close(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) { - return this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } - /// (Deprecated: Use native_handle().) Get the native acceptor representation. + /// Release ownership of the underlying native acceptor. /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. + * This function causes all outstanding asynchronous accept operations to + * finish immediately, and the handlers for cancelled operations will be + * passed the boost::asio::error::operation_aborted error. Ownership of the + * native acceptor is then transferred to the caller. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with boost::asio::error::operation_not_supported on + * these platforms. */ - native_type native() +#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release() { - return this->get_service().native_handle(this->get_implementation()); + boost::system::error_code ec; + native_handle_type s = impl_.get_service().release( + impl_.get_implementation(), ec); + boost::asio::detail::throw_error(ec, "release"); + return s; + } + + /// Release ownership of the underlying native acceptor. + /** + * This function causes all outstanding asynchronous accept operations to + * finish immediately, and the handlers for cancelled operations will be + * passed the boost::asio::error::operation_aborted error. Ownership of the + * native acceptor is then transferred to the caller. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with boost::asio::error::operation_not_supported on + * these platforms. + */ +#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release(boost::system::error_code& ec) + { + return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native acceptor representation. @@ -512,7 +732,7 @@ public: */ native_handle_type native_handle() { - return this->get_service().native_handle(this->get_implementation()); + return impl_.get_service().native_handle(impl_.get_implementation()); } /// Cancel all asynchronous operations associated with the acceptor. @@ -526,7 +746,7 @@ public: void cancel() { boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); } @@ -538,9 +758,10 @@ public: * * @param ec Set to indicate what error occurred, if any. */ - boost::system::error_code cancel(boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the acceptor. @@ -558,7 +779,7 @@ public: * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::reuse_address option(true); * acceptor.set_option(option); @@ -568,7 +789,7 @@ public: void set_option(const SettableSocketOption& option) { boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "set_option"); } @@ -587,7 +808,7 @@ public: * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::reuse_address option(true); * boost::system::error_code ec; @@ -599,11 +820,11 @@ public: * @endcode */ template - boost::system::error_code set_option(const SettableSocketOption& option, + BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, boost::system::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the acceptor. @@ -621,7 +842,7 @@ public: * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::reuse_address option; * acceptor.get_option(option); @@ -629,10 +850,10 @@ public: * @endcode */ template - void get_option(GettableSocketOption& option) + void get_option(GettableSocketOption& option) const { boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); boost::asio::detail::throw_error(ec, "get_option"); } @@ -651,7 +872,7 @@ public: * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::reuse_address option; * boost::system::error_code ec; @@ -664,11 +885,11 @@ public: * @endcode */ template - boost::system::error_code get_option(GettableSocketOption& option, - boost::system::error_code& ec) + BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, + boost::system::error_code& ec) const { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the acceptor. @@ -685,7 +906,7 @@ public: * @par Example * Getting the number of bytes ready to read: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); * socket.io_control(command); @@ -695,7 +916,7 @@ public: void io_control(IoControlCommand& command) { boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); boost::asio::detail::throw_error(ec, "io_control"); } @@ -713,7 +934,7 @@ public: * @par Example * Getting the number of bytes ready to read: * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); * boost::system::error_code ec; @@ -725,11 +946,11 @@ public: * @endcode */ template - boost::system::error_code io_control(IoControlCommand& command, + BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, boost::system::error_code& ec) { - return this->get_service().io_control( - this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the acceptor. @@ -745,7 +966,7 @@ public: */ bool non_blocking() const { - return this->get_service().non_blocking(this->get_implementation()); + return impl_.get_service().non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the acceptor. @@ -764,7 +985,7 @@ public: void non_blocking(bool mode) { boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); boost::asio::detail::throw_error(ec, "non_blocking"); } @@ -781,11 +1002,11 @@ public: * operations. Asynchronous operations will never fail with the error * boost::asio::error::would_block. */ - boost::system::error_code non_blocking( + BOOST_ASIO_SYNC_OP_VOID non_blocking( bool mode, boost::system::error_code& ec) { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native acceptor implementation. @@ -804,7 +1025,7 @@ public: */ bool native_non_blocking() const { - return this->get_service().native_non_blocking(this->get_implementation()); + return impl_.get_service().native_non_blocking(impl_.get_implementation()); } /// Sets the non-blocking mode of the native acceptor implementation. @@ -825,8 +1046,8 @@ public: void native_non_blocking(bool mode) { boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); boost::asio::detail::throw_error(ec, "native_non_blocking"); } @@ -845,11 +1066,12 @@ public: * function fails with boost::asio::error::invalid_argument, as the * combination does not make sense. */ - boost::system::error_code native_non_blocking( + BOOST_ASIO_SYNC_OP_VOID native_non_blocking( bool mode, boost::system::error_code& ec) { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the acceptor. @@ -862,7 +1084,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); * @endcode @@ -870,8 +1092,8 @@ public: endpoint_type local_endpoint() const { boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); + endpoint_type ep = impl_.get_service().local_endpoint( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "local_endpoint"); return ep; } @@ -888,7 +1110,7 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... * boost::system::error_code ec; * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); @@ -900,9 +1122,105 @@ public: */ endpoint_type local_endpoint(boost::system::error_code& ec) const { - return this->get_service().local_endpoint(this->get_implementation(), ec); + return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); } + /// Wait for the acceptor to become ready to read, ready to write, or to have + /// pending error conditions. + /** + * This function is used to perform a blocking wait for an acceptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor state. + * + * @par Example + * Waiting for an acceptor to become readable. + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); + * @endcode + */ + void wait(wait_type w) + { + boost::system::error_code ec; + impl_.get_service().wait(impl_.get_implementation(), w, ec); + boost::asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the acceptor to become ready to read, ready to write, or to have + /// pending error conditions. + /** + * This function is used to perform a blocking wait for an acceptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for an acceptor to become readable. + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::system::error_code ec; + * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); + * @endcode + */ + BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) + { + impl_.get_service().wait(impl_.get_implementation(), w, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously wait for the acceptor to become ready to read, ready to + /// write, or to have pending error conditions. + /** + * This function is used to perform an asynchronous wait for an acceptor to + * enter a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor state. + * + * @param handler The handler to be called when the wait operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void wait_handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_wait( + * boost::asio::ip::tcp::acceptor::wait_read, + * wait_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (boost::system::error_code)) + async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) + { + return async_initiate( + initiate_async_wait(), handler, this, w); + } + +#if !defined(BOOST_ASIO_NO_EXTENSIONS) /// Accept a new connection. /** * This function is used to accept a new connection from a peer into the @@ -915,18 +1233,20 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * acceptor.accept(socket); * @endcode */ - template - void accept(basic_socket& peer, - typename enable_if::value>::type* = 0) + template + void accept(basic_socket& peer, + typename enable_if< + is_convertible::value + >::type* = 0) { boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); boost::asio::detail::throw_error(ec, "accept"); } @@ -943,9 +1263,9 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... - * boost::asio::ip::tcp::soocket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::system::error_code ec; * acceptor.accept(socket, ec); * if (ec) @@ -954,14 +1274,16 @@ public: * } * @endcode */ - template - boost::system::error_code accept( - basic_socket& peer, - boost::system::error_code& ec, - typename enable_if::value>::type* = 0) + template + BOOST_ASIO_SYNC_OP_VOID accept( + basic_socket& peer, boost::system::error_code& ec, + typename enable_if< + is_convertible::value + >::type* = 0) { - return this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. @@ -980,9 +1302,9 @@ public: * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). * * @par Example * @code @@ -996,26 +1318,24 @@ public: * * ... * - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * acceptor.async_accept(socket, accept_handler); * @endcode */ - template + template BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (boost::system::error_code)) - async_accept(basic_socket& peer, + async_accept(basic_socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) + typename enable_if< + is_convertible::value + >::type* = 0) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); + return async_initiate( + initiate_async_accept(), handler, this, + &peer, static_cast(0)); } /// Accept a new connection and obtain the endpoint of the peer @@ -1034,19 +1354,19 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::asio::ip::tcp::endpoint endpoint; * acceptor.accept(socket, endpoint); * @endcode */ - template - void accept(basic_socket& peer, + template + void accept(basic_socket& peer, endpoint_type& peer_endpoint) { boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); boost::asio::detail::throw_error(ec, "accept"); } @@ -1067,9 +1387,9 @@ public: * * @par Example * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::acceptor acceptor(my_context); * ... - * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::socket socket(my_context); * boost::asio::ip::tcp::endpoint endpoint; * boost::system::error_code ec; * acceptor.accept(socket, endpoint, ec); @@ -1079,13 +1399,13 @@ public: * } * @endcode */ - template - boost::system::error_code accept( - basic_socket& peer, + template + BOOST_ASIO_SYNC_OP_VOID accept(basic_socket& peer, endpoint_type& peer_endpoint, boost::system::error_code& ec) { - return this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); + impl_.get_service().accept( + impl_.get_implementation(), peer, &peer_endpoint, ec); + BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. @@ -1110,23 +1430,946 @@ public: * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ - template + template BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (boost::system::error_code)) - async_accept(basic_socket& peer, + async_accept(basic_socket& peer, endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); + return async_initiate( + initiate_async_accept(), handler, this, &peer, &peer_endpoint); } +#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + typename Protocol::socket accept() + { + boost::system::error_code ec; + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept(boost::system::error_code& ec) + { + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + return peer; + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket peer // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, typename Protocol::socket)) + async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) + { + return async_initiate( + initiate_async_move_accept(), handler, this, + impl_.get_executor(), static_cast(0), + static_cast(0)); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly + * accepted socket. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, + typename enable_if< + is_executor::value + >::type* = 0) + { + boost::system::error_code ec; + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + { + boost::system::error_code ec; + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other peer(context); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly accepted + * socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, boost::system::error_code& ec, + typename enable_if< + is_executor::value + >::type* = 0) + { + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, boost::system::error_code& ec, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other peer(context); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + return peer; + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly accepted + * socket. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket::template rebind_executor< + * Executor1>::other peer // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(my_context2, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, + typename Protocol::socket::template rebind_executor< + Executor1>::other)) + async_accept(const Executor1& ex, + BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_executor::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + Executor1>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + ex, static_cast(0), + static_cast(0)); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket::template rebind_executor< + * typename ExecutionContext::executor_type>::other peer + * // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(my_context2, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other)) + async_accept(ExecutionContext& context, + BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + context.get_executor(), static_cast(0), + static_cast(0)); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); + * @endcode + */ + typename Protocol::socket accept(endpoint_type& peer_endpoint) + { + boost::system::error_code ec; + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept( + endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + return peer; + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket peer // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(endpoint, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, typename Protocol::socket)) + async_accept(endpoint_type& peer_endpoint, + BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) + { + return async_initiate( + initiate_async_move_accept(), handler, this, + impl_.get_executor(), &peer_endpoint, + static_cast(0)); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly accepted + * socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint)); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, endpoint_type& peer_endpoint, + typename enable_if< + is_executor::value + >::type* = 0) + { + boost::system::error_code ec; + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint)); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, endpoint_type& peer_endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + { + boost::system::error_code ec; + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other peer(context); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + boost::asio::detail::throw_error(ec, "accept"); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly accepted + * socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const executor_type& ex, + endpoint_type& peer_endpoint, boost::system::error_code& ec, + typename enable_if< + is_executor::value + >::type* = 0) + { + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + return peer; + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer. The function + * call will block until a new connection has been accepted successfully or + * an error occurs. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns On success, a socket object representing the newly accepted + * connection. On error, a socket object where is_open() is false. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * boost::asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, + endpoint_type& peer_endpoint, boost::system::error_code& ec, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other peer(context); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + return peer; + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param ex The I/O executor object to be used for the newly accepted + * socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket::template rebind_executor< + * Executor1>::other peer // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(my_context2, endpoint, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, + typename Protocol::socket::template rebind_executor< + Executor1>::other)) + async_accept(const Executor1& ex, endpoint_type& peer_endpoint, + BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_executor::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + Executor1>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + ex, &peer_endpoint, + static_cast(0)); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection. The + * function call always returns immediately. + * + * This overload requires that the Protocol template parameter satisfy the + * AcceptableProtocol type requirements. + * + * @param context The I/O execution context object to be used for the newly + * accepted socket. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * typename Protocol::socket::template rebind_executor< + * typename ExecutionContext::executor_type>::other peer + * // On success, the newly accepted socket. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error, + * boost::asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(my_context); + * ... + * boost::asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(my_context2, endpoint, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (boost::system::error_code, + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other)) + async_accept(ExecutionContext& context, + endpoint_type& peer_endpoint, + BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + context.get_executor(), &peer_endpoint, + static_cast(0)); + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +private: + // Disallow copying and assignment. + basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED; + basic_socket_acceptor& operator=( + const basic_socket_acceptor&) BOOST_ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, + basic_socket_acceptor* self, wait_type w) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WaitHandler. + BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), w, handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_accept + { + template + void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, + basic_socket_acceptor* self, basic_socket* peer, + endpoint_type* peer_endpoint) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a AcceptHandler. + BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_accept( + self->impl_.get_implementation(), *peer, peer_endpoint, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_move_accept + { + template + void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, + basic_socket_acceptor* self, const Executor1& peer_ex, + endpoint_type* peer_endpoint, Socket*) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a MoveAcceptHandler. + BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( + MoveAcceptHandler, handler, Socket) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_move_accept( + self->impl_.get_implementation(), peer_ex, peer_endpoint, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + detail::io_object_impl< + detail::null_socket_service, Executor> impl_; +#elif defined(BOOST_ASIO_HAS_IOCP) + detail::io_object_impl< + detail::win_iocp_socket_service, Executor> impl_; +#else + detail::io_object_impl< + detail::reactive_socket_service, Executor> impl_; +#endif }; } // namespace asio diff --git a/linx64/include/boost/asio/basic_socket_iostream.hpp b/linx64/include/boost/asio/basic_socket_iostream.hpp index 6ed71f7b..b6d449d6 100644 --- a/linx64/include/boost/asio/basic_socket_iostream.hpp +++ b/linx64/include/boost/asio/basic_socket_iostream.hpp @@ -2,7 +2,7 @@ // basic_socket_iostream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -22,7 +22,6 @@ #include #include #include -#include #if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) @@ -33,8 +32,7 @@ // explicit basic_socket_iostream(T1 x1, ..., Tn xn) // : std::basic_iostream( // &this->detail::socket_iostream_base< -// Protocol, StreamSocketService, Time, -// TimeTraits, TimerService>::streambuf_) +// Protocol, Clock, WaitTraits>::streambuf_) // { // if (rdbuf()->connect(x1, ..., xn) == 0) // this->setstate(std::ios_base::failbit); @@ -43,14 +41,13 @@ # define BOOST_ASIO_PRIVATE_CTR_DEF(n) \ template \ - explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_PARAMS(n)) \ + explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \ : std::basic_iostream( \ &this->detail::socket_iostream_base< \ - Protocol, StreamSocketService, Time, \ - TimeTraits, TimerService>::streambuf_) \ + Protocol, Clock, WaitTraits>::streambuf_) \ { \ this->setf(std::ios_base::unitbuf); \ - if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \ + if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ @@ -66,9 +63,9 @@ # define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \ template \ - void connect(BOOST_ASIO_VARIADIC_PARAMS(n)) \ + void connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \ { \ - if (rdbuf()->connect(BOOST_ASIO_VARIADIC_ARGS(n)) == 0) \ + if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ @@ -83,69 +80,156 @@ namespace detail { // A separate base class is used to ensure that the streambuf is initialised // prior to the basic_socket_iostream's basic_iostream base class. -template +template class socket_iostream_base { protected: - basic_socket_streambuf streambuf_; + socket_iostream_base() + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + socket_iostream_base(socket_iostream_base&& other) + : streambuf_(std::move(other.streambuf_)) + { + } + + socket_iostream_base(basic_stream_socket s) + : streambuf_(std::move(s)) + { + } + + socket_iostream_base& operator=(socket_iostream_base&& other) + { + streambuf_ = std::move(other.streambuf_); + return *this; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + basic_socket_streambuf streambuf_; }; -} +} // namespace detail + +#if !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) +#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL + +// Forward declaration with defaulted arguments. +template > +#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) + typename Clock = chrono::steady_clock, + typename WaitTraits = wait_traits > +#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) +class basic_socket_iostream; + +#endif // !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) /// Iostream interface for a socket. +#if defined(GENERATING_DOCUMENTATION) template , -#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ - || defined(GENERATING_DOCUMENTATION) - typename Time = boost::posix_time::ptime, - typename TimeTraits = boost::asio::time_traits