update boost on linux

This commit is contained in:
Bassem Girgis
2019-08-10 16:06:25 -05:00
parent 76ad52be58
commit 861b918727
5363 changed files with 483306 additions and 116507 deletions

View File

@@ -99,11 +99,9 @@ namespace boost { namespace numeric
}; \ }; \
template<typename Arg, typename EnableIf> \ template<typename Arg, typename EnableIf> \
struct Name ## _base \ struct Name ## _base \
: std::unary_function< \
typename remove_const<Arg>::type \
, typename result_of_ ## Name<Arg>::type \
> \
{ \ { \
typedef typename remove_const<Arg>::type argument_type; \
typedef typename result_of_ ## Name<Arg>::type result_type; \
typename result_of_ ## Name<Arg>::type operator ()(Arg &arg) const \ typename result_of_ ## Name<Arg>::type operator ()(Arg &arg) const \
{ \ { \
return Op arg; \ return Op arg; \
@@ -138,12 +136,10 @@ namespace boost { namespace numeric
}; \ }; \
template<typename Left, typename Right, typename EnableIf> \ template<typename Left, typename Right, typename EnableIf> \
struct Name ## _base \ struct Name ## _base \
: std::binary_function< \
typename remove_const<Left>::type \
, typename remove_const<Right>::type \
, typename result_of_ ## Name<Left, Right>::type \
> \
{ \ { \
typedef typename remove_const<Left>::type first_argument_type; \
typedef typename remove_const<Right>::type second_argument_type; \
typedef typename result_of_ ## Name<Left, Right>::type result_type; \
typename result_of_ ## Name<Left, Right>::type \ typename result_of_ ## Name<Left, Right>::type \
operator ()(Left &left, Right &right) const \ operator ()(Left &left, Right &right) const \
{ \ { \
@@ -220,8 +216,11 @@ namespace boost { namespace numeric
{ {
template<typename Left, typename Right, typename EnableIf> template<typename Left, typename Right, typename EnableIf>
struct min_assign_base struct min_assign_base
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
if(numeric::less(right, left)) if(numeric::less(right, left))
@@ -233,8 +232,11 @@ namespace boost { namespace numeric
template<typename Left, typename Right, typename EnableIf> template<typename Left, typename Right, typename EnableIf>
struct max_assign_base struct max_assign_base
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
if(numeric::greater(right, left)) if(numeric::greater(right, left))
@@ -258,8 +260,10 @@ namespace boost { namespace numeric
template<typename To, typename From, typename EnableIf> template<typename To, typename From, typename EnableIf>
struct promote_base struct promote_base
: std::unary_function<From, To>
{ {
typedef From argument_type;
typedef To result_type;
To operator ()(From &from) const To operator ()(From &from) const
{ {
return from; return from;
@@ -268,8 +272,10 @@ namespace boost { namespace numeric
template<typename ToFrom> template<typename ToFrom>
struct promote_base<ToFrom, ToFrom, void> struct promote_base<ToFrom, ToFrom, void>
: std::unary_function<ToFrom, ToFrom>
{ {
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) ToFrom &operator ()(ToFrom &tofrom)
{ {
return tofrom; return tofrom;
@@ -278,10 +284,12 @@ namespace boost { namespace numeric
template<typename Arg, typename EnableIf> template<typename Arg, typename EnableIf>
struct as_min_base struct as_min_base
: std::unary_function<Arg, typename remove_const<Arg>::type>
{ {
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized); BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const typename remove_const<Arg>::type operator ()(Arg &) const
{ {
return (std::numeric_limits<typename remove_const<Arg>::type>::min)(); return (std::numeric_limits<typename remove_const<Arg>::type>::min)();
@@ -290,10 +298,12 @@ namespace boost { namespace numeric
template<typename Arg> template<typename Arg>
struct as_min_base<Arg, typename enable_if<is_floating_point<Arg> >::type> struct as_min_base<Arg, typename enable_if<is_floating_point<Arg> >::type>
: std::unary_function<Arg, typename remove_const<Arg>::type>
{ {
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized); BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const typename remove_const<Arg>::type operator ()(Arg &) const
{ {
return -(std::numeric_limits<typename remove_const<Arg>::type>::max)(); return -(std::numeric_limits<typename remove_const<Arg>::type>::max)();
@@ -302,10 +312,12 @@ namespace boost { namespace numeric
template<typename Arg, typename EnableIf> template<typename Arg, typename EnableIf>
struct as_max_base struct as_max_base
: std::unary_function<Arg, typename remove_const<Arg>::type>
{ {
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized); BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const typename remove_const<Arg>::type operator ()(Arg &) const
{ {
return (std::numeric_limits<typename remove_const<Arg>::type>::max)(); return (std::numeric_limits<typename remove_const<Arg>::type>::max)();
@@ -314,8 +326,10 @@ namespace boost { namespace numeric
template<typename Arg, typename EnableIf> template<typename Arg, typename EnableIf>
struct as_zero_base struct as_zero_base
: std::unary_function<Arg, typename remove_const<Arg>::type>
{ {
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const typename remove_const<Arg>::type operator ()(Arg &) const
{ {
return numeric::zero<typename remove_const<Arg>::type>::value; return numeric::zero<typename remove_const<Arg>::type>::value;
@@ -324,8 +338,10 @@ namespace boost { namespace numeric
template<typename Arg, typename EnableIf> template<typename Arg, typename EnableIf>
struct as_one_base struct as_one_base
: std::unary_function<Arg, typename remove_const<Arg>::type>
{ {
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const typename remove_const<Arg>::type operator ()(Arg &) const
{ {
return numeric::one<typename remove_const<Arg>::type>::value; return numeric::one<typename remove_const<Arg>::type>::value;

View File

@@ -118,17 +118,9 @@ namespace boost { namespace numeric
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \ #define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \
template<typename Left, typename Right> \ template<typename Left, typename Right> \
struct Name<Left, Right, std_valarray_tag, std_valarray_tag> \ struct Name<Left, Right, std_valarray_tag, std_valarray_tag> \
: 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 Left::value_type left_value_type; \
typedef typename Right::value_type right_value_type; \ typedef typename Right::value_type right_value_type; \
typedef \ typedef \
@@ -145,14 +137,9 @@ namespace boost { namespace numeric
}; \ }; \
template<typename Left, typename Right> \ template<typename Left, typename Right> \
struct Name<Left, Right, std_valarray_tag, void> \ struct Name<Left, Right, std_valarray_tag, void> \
: std::binary_function< \
Left \
, Right \
, std::valarray< \
typename Name<typename Left::value_type, Right>::result_type \
> \
> \
{ \ { \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Left::value_type left_value_type; \ typedef typename Left::value_type left_value_type; \
typedef \ typedef \
std::valarray< \ std::valarray< \
@@ -167,14 +154,9 @@ namespace boost { namespace numeric
}; \ }; \
template<typename Left, typename Right> \ template<typename Left, typename Right> \
struct Name<Left, Right, void, std_valarray_tag> \ struct Name<Left, Right, void, std_valarray_tag> \
: std::binary_function< \
Left \
, Right \
, std::valarray< \
typename Name<Left, typename Right::value_type>::result_type \
> \
> \
{ \ { \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Right::value_type right_value_type; \ typedef typename Right::value_type right_value_type; \
typedef \ typedef \
std::valarray< \ std::valarray< \
@@ -200,8 +182,11 @@ namespace boost { namespace numeric
// element-wise min of std::valarray // element-wise min of std::valarray
template<typename Left, typename Right> template<typename Left, typename Right>
struct min_assign<Left, Right, std_valarray_tag, std_valarray_tag> struct min_assign<Left, Right, std_valarray_tag, std_valarray_tag>
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
BOOST_ASSERT(left.size() == right.size()); BOOST_ASSERT(left.size() == right.size());
@@ -219,8 +204,11 @@ namespace boost { namespace numeric
// element-wise max of std::valarray // element-wise max of std::valarray
template<typename Left, typename Right> template<typename Left, typename Right>
struct max_assign<Left, Right, std_valarray_tag, std_valarray_tag> struct max_assign<Left, Right, std_valarray_tag, std_valarray_tag>
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
BOOST_ASSERT(left.size() == right.size()); BOOST_ASSERT(left.size() == right.size());
@@ -247,8 +235,10 @@ namespace boost { namespace numeric
// promote // promote
template<typename To, typename From> template<typename To, typename From>
struct promote<To, From, std_valarray_tag, std_valarray_tag> struct promote<To, From, std_valarray_tag, std_valarray_tag>
: std::unary_function<From, To>
{ {
typedef From argument_type;
typedef To result_type;
To operator ()(From &arr) const To operator ()(From &arr) const
{ {
typename remove_const<To>::type res(arr.size()); typename remove_const<To>::type res(arr.size());
@@ -262,8 +252,10 @@ namespace boost { namespace numeric
template<typename ToFrom> template<typename ToFrom>
struct promote<ToFrom, ToFrom, std_valarray_tag, std_valarray_tag> struct promote<ToFrom, ToFrom, std_valarray_tag, std_valarray_tag>
: std::unary_function<ToFrom, ToFrom>
{ {
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) const ToFrom &operator ()(ToFrom &tofrom) const
{ {
return tofrom; return tofrom;
@@ -275,8 +267,10 @@ namespace boost { namespace numeric
// if(numeric::promote<bool>(a == b)) // if(numeric::promote<bool>(a == b))
template<typename From> template<typename From>
struct promote<bool, From, void, std_valarray_tag> struct promote<bool, From, void, std_valarray_tag>
: std::unary_function<From, bool>
{ {
typedef From argument_type;
typedef bool result_type;
bool operator ()(From &arr) const bool operator ()(From &arr) const
{ {
BOOST_MPL_ASSERT((is_same<bool, typename From::value_type>)); BOOST_MPL_ASSERT((is_same<bool, typename From::value_type>));
@@ -300,8 +294,10 @@ namespace boost { namespace numeric
// functional::as_min // functional::as_min
template<typename T> template<typename T>
struct as_min<T, std_valarray_tag> struct as_min<T, std_valarray_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -314,8 +310,10 @@ namespace boost { namespace numeric
// functional::as_max // functional::as_max
template<typename T> template<typename T>
struct as_max<T, std_valarray_tag> struct as_max<T, std_valarray_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -328,8 +326,10 @@ namespace boost { namespace numeric
// functional::as_zero // functional::as_zero
template<typename T> template<typename T>
struct as_zero<T, std_valarray_tag> struct as_zero<T, std_valarray_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -342,8 +342,10 @@ namespace boost { namespace numeric
// functional::as_one // functional::as_one
template<typename T> template<typename T>
struct as_one<T, std_valarray_tag> struct as_one<T, std_valarray_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()

View File

@@ -195,8 +195,11 @@ namespace boost { namespace numeric
// element-wise min of std::vector // element-wise min of std::vector
template<typename Left, typename Right> template<typename Left, typename Right>
struct min_assign<Left, Right, std_vector_tag, std_vector_tag> struct min_assign<Left, Right, std_vector_tag, std_vector_tag>
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
BOOST_ASSERT(left.size() == right.size()); BOOST_ASSERT(left.size() == right.size());
@@ -214,8 +217,11 @@ namespace boost { namespace numeric
// element-wise max of std::vector // element-wise max of std::vector
template<typename Left, typename Right> template<typename Left, typename Right>
struct max_assign<Left, Right, std_vector_tag, std_vector_tag> struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
: std::binary_function<Left, Right, void>
{ {
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const void operator ()(Left &left, Right &right) const
{ {
BOOST_ASSERT(left.size() == right.size()); BOOST_ASSERT(left.size() == right.size());
@@ -242,8 +248,10 @@ namespace boost { namespace numeric
// promote // promote
template<typename To, typename From> template<typename To, typename From>
struct promote<To, From, std_vector_tag, std_vector_tag> struct promote<To, From, std_vector_tag, std_vector_tag>
: std::unary_function<From, To>
{ {
typedef From argument_type;
typedef To result_type;
To operator ()(From &arr) const To operator ()(From &arr) const
{ {
typename remove_const<To>::type res(arr.size()); typename remove_const<To>::type res(arr.size());
@@ -257,8 +265,10 @@ namespace boost { namespace numeric
template<typename ToFrom> template<typename ToFrom>
struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag> struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
: std::unary_function<ToFrom, ToFrom>
{ {
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) const ToFrom &operator ()(ToFrom &tofrom) const
{ {
return tofrom; return tofrom;
@@ -269,8 +279,10 @@ namespace boost { namespace numeric
// functional::as_min // functional::as_min
template<typename T> template<typename T>
struct as_min<T, std_vector_tag> struct as_min<T, std_vector_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -283,8 +295,10 @@ namespace boost { namespace numeric
// functional::as_max // functional::as_max
template<typename T> template<typename T>
struct as_max<T, std_vector_tag> struct as_max<T, std_vector_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -297,8 +311,10 @@ namespace boost { namespace numeric
// functional::as_zero // functional::as_zero
template<typename T> template<typename T>
struct as_zero<T, std_vector_tag> struct as_zero<T, std_vector_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()
@@ -311,8 +327,10 @@ namespace boost { namespace numeric
// functional::as_one // functional::as_one
template<typename T> template<typename T>
struct as_one<T, std_vector_tag> struct as_one<T, std_vector_tag>
: std::unary_function<T, typename remove_const<T>::type>
{ {
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const typename remove_const<T>::type operator ()(T &arr) const
{ {
return 0 == arr.size() return 0 == arr.size()

View File

@@ -50,17 +50,9 @@ namespace boost { namespace numeric
template<typename Left, typename Right> template<typename Left, typename Right>
struct outer_product<Left, Right, std_vector_tag, std_vector_tag> struct outer_product<Left, Right, std_vector_tag, std_vector_tag>
: 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 typedef
ublas::matrix< ublas::matrix<
typename functional::multiplies< typename functional::multiplies<

View File

@@ -248,8 +248,11 @@ namespace impl
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
struct indirect_cmp struct indirect_cmp
: std::binary_function<std::size_t, std::size_t, bool>
{ {
typedef std::size_t first_argument_type;
typedef std::size_t second_argument_type;
typedef bool result_type;
indirect_cmp(std::vector<Sample> const &s) indirect_cmp(std::vector<Sample> const &s)
: samples(s) : samples(s)
{ {

View File

@@ -118,7 +118,11 @@ namespace impl
this->tail_means_.begin() this->tail_means_.begin()
, this->tail_means_.end() , this->tail_means_.end()
, this->tail_means_.begin() , this->tail_means_.begin()
#ifdef BOOST_NO_CXX98_BINDERS
, std::bind(std::divides<float_type>(), std::placeholders::_1, factor)
#else
, std::bind2nd(std::divides<float_type>(), factor) , std::bind2nd(std::divides<float_type>(), factor)
#endif
); );
} }
else else

View File

@@ -23,7 +23,11 @@ namespace boost { namespace accumulators
namespace detail namespace detail
{ {
typedef transform_iterator< typedef transform_iterator<
#ifdef BOOST_NO_CXX98_BINDERS
decltype(std::bind(std::multiplies<std::size_t>(), 2, std::placeholders::_1))
#else
std::binder1st<std::multiplies<std::size_t> > std::binder1st<std::multiplies<std::size_t> >
#endif
, counting_iterator<std::size_t> , counting_iterator<std::size_t>
> times2_iterator; > times2_iterator;
@@ -31,7 +35,11 @@ namespace detail
{ {
return make_transform_iterator( return make_transform_iterator(
make_counting_iterator(i) make_counting_iterator(i)
#ifdef BOOST_NO_CXX98_BINDERS
, std::bind(std::multiplies<std::size_t>(), 2, std::placeholders::_1)
#else
, std::bind1st(std::multiplies<std::size_t>(), 2) , std::bind1st(std::multiplies<std::size_t>(), 2)
#endif
); );
} }

View File

@@ -169,7 +169,11 @@ namespace impl
this->tail_means_.begin() this->tail_means_.begin()
, this->tail_means_.end() , this->tail_means_.end()
, this->tail_means_.begin() , this->tail_means_.begin()
#ifdef BOOST_NO_CXX98_BINDERS
, std::bind(numeric::functional::divides<typename array_type::value_type const, float_type const>(), std::placeholders::_1, factor)
#else
, std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor) , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor)
#endif
); );
return make_iterator_range(this->tail_means_); return make_iterator_range(this->tail_means_);

View File

@@ -25,10 +25,10 @@
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
template <typename T> template <typename T>
T identity_operation ( std::multiplies<T> ) { return T(1); } BOOST_CXX14_CONSTEXPR T identity_operation ( std::multiplies<T> ) { return T(1); }
template <typename T> template <typename T>
T identity_operation ( std::plus<T> ) { return T(0); } BOOST_CXX14_CONSTEXPR T identity_operation ( std::plus<T> ) { return T(0); }
/// \fn power ( T x, Integer n ) /// \fn power ( T x, Integer n )
@@ -40,7 +40,7 @@ T identity_operation ( std::plus<T> ) { return T(0); }
// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: // \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3 // Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer> template <typename T, typename Integer>
typename boost::enable_if<boost::is_integral<Integer>, T>::type BOOST_CXX14_CONSTEXPR typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n) { power (T x, Integer n) {
T y = 1; // Should be "T y{1};" T y = 1; // Should be "T y{1};"
if (n == 0) return y; 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: // \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3 // Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer, typename Operation> template <typename T, typename Integer, typename Operation>
typename boost::enable_if<boost::is_integral<Integer>, T>::type BOOST_CXX14_CONSTEXPR typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n, Operation op) { power (T x, Integer n, Operation op) {
T y = identity_operation(op); T y = identity_operation(op);
if (n == 0) return y; if (n == 0) return y;

View File

@@ -0,0 +1,126 @@
/*
Copyright (c) Alexander Zaitsev <zamazan4ik@gmail.com>, 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 <algorithm>
#include <type_traits>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
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<typename RandomAccessIterator1, typename RandomAccessIterator2>
void
apply_permutation(RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end,
RandomAccessIterator2 ind_begin, RandomAccessIterator2 ind_end)
{
typedef typename std::iterator_traits<RandomAccessIterator1>::difference_type Diff;
typedef typename std::iterator_traits<RandomAccessIterator2>::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<typename RandomAccessIterator1, typename RandomAccessIterator2>
void
apply_reverse_permutation(
RandomAccessIterator1 item_begin,
RandomAccessIterator1 item_end,
RandomAccessIterator2 ind_begin,
RandomAccessIterator2 ind_end)
{
typedef typename std::iterator_traits<RandomAccessIterator2>::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<typename Range1, typename Range2>
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<typename Range1, typename Range2>
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

View File

@@ -46,7 +46,7 @@ namespace boost { namespace algorithm {
/// p ( a, b ) returns a boolean. /// p ( a, b ) returns a boolean.
/// ///
template<typename T, typename Pred> template<typename T, typename Pred>
T const & clamp ( T const& val, BOOST_CXX14_CONSTEXPR T const & clamp ( T const& val,
typename boost::mpl::identity<T>::type const & lo, typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi, Pred p ) typename boost::mpl::identity<T>::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 /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename T> template<typename T>
T const& clamp ( const T& val, BOOST_CXX14_CONSTEXPR T const& clamp ( const T& val,
typename boost::mpl::identity<T>::type const & lo, typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi ) typename boost::mpl::identity<T>::type const & hi )
{ {
return (clamp) ( val, lo, hi, std::less<T>()); return boost::algorithm::clamp ( val, lo, hi, std::less<T>());
} }
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, /// \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 /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename InputIterator, typename OutputIterator> template<typename InputIterator, typename OutputIterator>
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<InputIterator>::value_type const & lo, typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi ) typename std::iterator_traits<InputIterator>::value_type const & hi )
{ {
// this could also be written with bind and std::transform // this could also be written with bind and std::transform
while ( first != last ) while ( first != last )
*out++ = clamp ( *first++, lo, hi ); *out++ = boost::algorithm::clamp ( *first++, lo, hi );
return out; return out;
} }
@@ -108,12 +108,12 @@ namespace boost { namespace algorithm {
/// \param hi The upper bound of the range to be clamped to /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename Range, typename OutputIterator> template<typename Range, typename OutputIterator>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out, clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi ) typename std::iterator_traits<typename boost::range_iterator<const Range>::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<typename InputIterator, typename OutputIterator, typename Pred> template<typename InputIterator, typename OutputIterator, typename Pred>
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<InputIterator>::value_type const & lo, typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p ) typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
{ {
// this could also be written with bind and std::transform // this could also be written with bind and std::transform
while ( first != last ) while ( first != last )
*out++ = clamp ( *first++, lo, hi, p ); *out++ = boost::algorithm::clamp ( *first++, lo, hi, p );
return out; return out;
} }
@@ -160,13 +160,13 @@ namespace boost { namespace algorithm {
// Disable this template if the first two parameters are the same type; // Disable this template if the first two parameters are the same type;
// In that case, the user will get the two iterator version. // In that case, the user will get the two iterator version.
template<typename Range, typename OutputIterator, typename Pred> template<typename Range, typename OutputIterator, typename Pred>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out, clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
Pred p ) 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 );
} }

View File

@@ -27,7 +27,7 @@ namespace boost { namespace algorithm {
/// ///
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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 ) for ( ; first != last; ++first )
if ( !p(*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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
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 ); 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 /// \param val A value to compare against
/// ///
template<typename InputIterator, typename T> template<typename InputIterator, typename T>
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 ) for ( ; first != last; ++first )
if ( val != *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 /// \param val A value to compare against
/// ///
template<typename Range, typename T> template<typename Range, typename T>
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 ); return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
} }

View File

@@ -28,7 +28,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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 ) for ( ; first != last; ++first )
if ( p(*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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
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); 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 /// \param val A value to compare against
/// ///
template<typename InputIterator, typename V> template<typename InputIterator, typename V>
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 ) for ( ; first != last; ++first )
if ( val == *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 /// \param val A value to compare against
/// ///
template<typename Range, typename V> template<typename Range, typename V>
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); return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val);
} }

View File

@@ -29,7 +29,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the range /// \param p A predicate for testing the elements of the range
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
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 ) for ( ; first != last; ++first )
if (p(*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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
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); 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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{ {
for ( ; first != last && p(*first); ++first ) 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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_while ( const Range &r, OutputIterator result, Predicate p ) copy_while ( const Range &r, OutputIterator result, Predicate p )
{ {
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, 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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{ {
for ( ; first != last && !p(*first); ++first ) 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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_until ( const Range &r, OutputIterator result, Predicate p ) copy_until ( const Range &r, OutputIterator result, Predicate p )
{ {
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p); return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);

View File

@@ -24,7 +24,7 @@ namespace boost { namespace algorithm {
/// \param result An output iterator to write the results into /// \param result An output iterator to write the results into
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template <typename InputIterator, typename Size, typename OutputIterator> template <typename InputIterator, typename Size, typename OutputIterator>
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 ) for ( ; n > 0; --n, ++first, ++result )
*result = *first; *result = *first;

View File

@@ -26,7 +26,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the range /// \param p A predicate for testing the elements of the range
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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 ) for ( ; first != last; ++first )
if ( !p(*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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p )
{ {
return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p); return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p);
} }

View File

@@ -25,7 +25,7 @@ namespace boost { namespace algorithm {
/// \param value The initial value of the sequence to be generated /// \param value The initial value of the sequence to be generated
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template <typename ForwardIterator, typename T> template <typename ForwardIterator, typename T>
void iota ( ForwardIterator first, ForwardIterator last, T value ) BOOST_CXX14_CONSTEXPR void iota ( ForwardIterator first, ForwardIterator last, T value )
{ {
for ( ; first != last; ++first, ++value ) for ( ; first != last; ++first, ++value )
*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 /// \param value The initial value of the sequence to be generated
/// ///
template <typename Range, typename T> template <typename Range, typename T>
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); 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 /// \param n The number of items to write
/// ///
template <typename OutputIterator, typename T> template <typename OutputIterator, typename T>
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 ) for ( ; n > 0; --n, ++value )
*out++ = value; *out++ = value;

View File

@@ -18,14 +18,15 @@
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) /// \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 first The start of the input sequence
/// \param last One past the end of the input sequence /// \param last One past the end of the input sequence
/// \param p The predicate to test the values with /// \param p The predicate to test the values with
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template <typename InputIterator, typename UnaryPredicate> template <typename InputIterator, typename UnaryPredicate>
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 // Run through the part that satisfy the predicate
for ( ; first != last; ++first ) 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 ) /// \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 r The input range
/// \param p The predicate to test the values with /// \param p The predicate to test the values with
/// ///
template <typename Range, typename UnaryPredicate> template <typename Range, typename UnaryPredicate>
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); return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p);
} }

View File

@@ -34,7 +34,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename ForwardIterator, typename Pred> template <typename ForwardIterator, typename Pred>
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 if ( first == last ) return last; // the empty sequence is ordered
ForwardIterator next = first; ForwardIterator next = first;
@@ -54,7 +54,7 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the sequence /// \param last One past the end of the sequence
/// ///
template <typename ForwardIterator> template <typename ForwardIterator>
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>()); return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
@@ -69,7 +69,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename ForwardIterator, typename Pred> template <typename ForwardIterator, typename Pred>
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; 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 /// \param last One past the end of the sequence
/// ///
template <typename ForwardIterator> template <typename ForwardIterator>
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; 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. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename R, typename Pred> template <typename R, typename Pred>
typename boost::lazy_disable_if_c< BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c<
boost::is_same<R, Pred>::value, boost::is_same<R, Pred>::value,
typename boost::range_iterator<const R> typename boost::range_iterator<const R>
>::type is_sorted_until ( const R &range, Pred p ) >::type is_sorted_until ( const R &range, Pred p )
@@ -113,7 +113,7 @@ namespace boost { namespace algorithm {
/// \param range The range to be tested. /// \param range The range to be tested.
/// ///
template <typename R> template <typename R>
typename boost::range_iterator<const R>::type is_sorted_until ( const R &range ) BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
{ {
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( 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. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename R, typename Pred> template <typename R, typename Pred>
typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
is_sorted ( const R &range, Pred p ) is_sorted ( const R &range, Pred p )
{ {
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), 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. /// \param range The range to be tested.
/// ///
template <typename R> template <typename R>
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 )); 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 /// \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. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_increasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less<value_type>()); return boost::algorithm::is_sorted (first, last, std::less<value_type>());
@@ -175,7 +175,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \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. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename R> template <typename R>
bool is_increasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_increasing ( const R &range )
{ {
return is_increasing ( boost::begin ( range ), boost::end ( 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 /// \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. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_decreasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater<value_type>()); return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
@@ -207,7 +207,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \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. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename R> template <typename R>
bool is_decreasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_decreasing ( const R &range )
{ {
return is_decreasing ( boost::begin ( range ), boost::end ( 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 /// \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. /// equal. If that is not what you intended, you should use is_increasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>()); return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
@@ -239,7 +239,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \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. /// equal. If that is not what you intended, you should use is_increasing instead.
template <typename R> template <typename R>
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 )); 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 /// \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. /// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>()); return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
@@ -270,7 +270,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \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. /// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename R> template <typename R>
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 )); return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
} }

View File

@@ -26,7 +26,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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 ) for ( ; first != last; ++first )
if ( p(*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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
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 ); 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 /// \param val A value to compare against
/// ///
template<typename InputIterator, typename V> template<typename InputIterator, typename V>
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 ) for ( ; first != last; ++first )
if ( val == *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 /// \param val A value to compare against
/// ///
template<typename Range, typename V> template<typename Range, typename V>
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); return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val);
} }

View File

@@ -12,7 +12,6 @@
#ifndef BOOST_ALGORITHM_ONE_OF_HPP #ifndef BOOST_ALGORITHM_ONE_OF_HPP
#define BOOST_ALGORITHM_ONE_OF_HPP #define BOOST_ALGORITHM_ONE_OF_HPP
#include <algorithm> // for std::find and std::find_if
#include <boost/algorithm/cxx11/none_of.hpp> #include <boost/algorithm/cxx11/none_of.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
@@ -28,12 +27,16 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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); // find_if
if (i == last) for (; first != last; ++first)
if (p(*first))
break;
if (first == last)
return false; // Didn't occur at all 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 ) /// \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 /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
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 ); 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 /// \param val A value to compare against
/// ///
template<typename InputIterator, typename V> template<typename InputIterator, typename V>
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' // find
if (i == last) for (; first != last; ++first)
if (*first == val)
break;
if (first == last)
return false; // Didn't occur at all 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 ) /// \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 /// \param val A value to compare against
/// ///
template<typename Range, typename V> template<typename Range, typename V>
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 ); return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val );
} }

View File

@@ -14,6 +14,7 @@
#include <utility> // for std::pair #include <utility> // for std::pair
#include <boost/config.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
@@ -35,7 +36,7 @@ namespace boost { namespace algorithm {
/// \note This function is part of the C++2011 standard library. /// \note This function is part of the C++2011 standard library.
template <typename InputIterator, template <typename InputIterator,
typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate> typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2> BOOST_CXX14_CONSTEXPR std::pair<OutputIterator1, OutputIterator2>
partition_copy ( InputIterator first, InputIterator last, partition_copy ( InputIterator first, InputIterator last,
OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p ) OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
{ {
@@ -57,7 +58,7 @@ partition_copy ( InputIterator first, InputIterator last,
/// ///
template <typename Range, typename OutputIterator1, typename OutputIterator2, template <typename Range, typename OutputIterator1, typename OutputIterator2,
typename UnaryPredicate> typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2> BOOST_CXX14_CONSTEXPR std::pair<OutputIterator1, OutputIterator2>
partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false, partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false,
UnaryPredicate p ) UnaryPredicate p )
{ {

View File

@@ -12,8 +12,6 @@
#ifndef BOOST_ALGORITHM_EQUAL_HPP #ifndef BOOST_ALGORITHM_EQUAL_HPP
#define BOOST_ALGORITHM_EQUAL_HPP #define BOOST_ALGORITHM_EQUAL_HPP
#include <algorithm> // for std::equal
#include <functional> // for std::binary_function
#include <iterator> #include <iterator>
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
@@ -21,11 +19,12 @@ namespace boost { namespace algorithm {
namespace detail { namespace detail {
template <class T1, class T2> template <class T1, class T2>
struct eq : public std::binary_function<T1, T2, bool> { struct eq {
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;} BOOST_CONSTEXPR bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
}; };
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate> template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1, bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
std::random_access_iterator_tag, std::random_access_iterator_tag ) 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 // Random-access iterators let is check the sizes in constant time
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 )) if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
return false; 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 <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1, bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
std::input_iterator_tag, std::input_iterator_tag ) 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 last2 One past the end of the second range.
/// \param pred A predicate for comparing the elements of the ranges /// \param pred A predicate for comparing the elements of the ranges
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1, bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred ) 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 first2 The start of the second range.
/// \param last2 One past the end of the second range. /// \param last2 One past the end of the second range.
template <class InputIterator1, class InputIterator2> template <class InputIterator1, class InputIterator2>
BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1, bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 ) InputIterator2 first2, InputIterator2 last2 )
{ {

View File

@@ -2,7 +2,7 @@
Copyright (c) Marshall Clow 2008-2012. Copyright (c) Marshall Clow 2008-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying 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 /// \file mismatch.hpp
@@ -13,6 +13,7 @@
#define BOOST_ALGORITHM_MISMATCH_HPP #define BOOST_ALGORITHM_MISMATCH_HPP
#include <utility> // for std::pair #include <utility> // for std::pair
#include <boost/config.hpp>
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
@@ -27,7 +28,7 @@ namespace boost { namespace algorithm {
/// \param last2 One past the end of the second range. /// \param last2 One past the end of the second range.
/// \param pred A predicate for comparing the elements of the ranges /// \param pred A predicate for comparing the elements of the ranges
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
std::pair<InputIterator1, InputIterator2> mismatch ( BOOST_CXX14_CONSTEXPR std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1, InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, InputIterator2 first2, InputIterator2 last2,
BinaryPredicate pred ) BinaryPredicate pred )
@@ -47,7 +48,7 @@ std::pair<InputIterator1, InputIterator2> mismatch (
/// \param first2 The start of the second range. /// \param first2 The start of the second range.
/// \param last2 One past the end of the second range. /// \param last2 One past the end of the second range.
template <class InputIterator1, class InputIterator2> template <class InputIterator1, class InputIterator2>
std::pair<InputIterator1, InputIterator2> mismatch ( BOOST_CXX14_CONSTEXPR std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1, InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 ) InputIterator2 first2, InputIterator2 last2 )
{ {

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
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<class InputIterator, class OutputIterator, class T>
OutputIterator exclusive_scan(InputIterator first, InputIterator last,
OutputIterator result, T init)
{
typedef typename std::iterator_traits<InputIterator>::value_type VT;
return boost::algorithm::exclusive_scan(first, last, result, init, std::plus<VT>());
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_EXCLUSIVE_SCAN_HPP

View File

@@ -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 <utility> // 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<class InputIterator, class Size, class Function>
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

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
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<class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation bOp)
{
if (first != last) {
typename std::iterator_traits<InputIterator>::value_type init = *first;
*result++ = init;
if (++first != last)
return boost::algorithm::inclusive_scan(first, last, result, bOp, init);
}
return result;
}
template<class InputIterator, class OutputIterator>
OutputIterator inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result)
{
typedef typename std::iterator_traits<InputIterator>::value_type VT;
return boost::algorithm::inclusive_scan(first, last, result, std::plus<VT>());
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator, class T, class BinaryOperation>
T reduce(InputIterator first, InputIterator last, T init, BinaryOperation bOp)
{
;
for (; first != last; ++first)
init = bOp(init, *first);
return init;
}
template<class InputIterator, class T>
T reduce(InputIterator first, InputIterator last, T init)
{
typedef typename std::iterator_traits<InputIterator>::value_type VT;
return boost::algorithm::reduce(first, last, init, std::plus<VT>());
}
template<class InputIterator>
typename std::iterator_traits<InputIterator>::value_type
reduce(InputIterator first, InputIterator last)
{
return boost::algorithm::reduce(first, last,
typename std::iterator_traits<InputIterator>::value_type());
}
template<class Range>
typename boost::range_value<Range>::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<class Range, class T>
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<class Range, class T, class BinaryOperation>
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

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator, class OutputIterator, class T,
class BinaryOperation, class UnaryOperation>
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

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation, class T>
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<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation>
OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation bOp, UnaryOperation uOp)
{
if (first != last) {
typename std::iterator_traits<InputIterator>::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

View File

@@ -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 <functional> // for std::plus
#include <iterator> // for std::iterator_traits
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
namespace boost { namespace algorithm {
template<class InputIterator1, class InputIterator2, class T,
class BinaryOperation1, class BinaryOperation2>
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<class InputIterator, class T,
class BinaryOperation, class UnaryOperation>
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<class InputIterator1, class InputIterator2, class T>
T transform_reduce(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init)
{
return boost::algorithm::transform_reduce(first1, last1, first2, init,
std::plus<T>(), std::multiplies<T>());
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP

View File

@@ -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 <boost/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <utility>
namespace boost { namespace algorithm {
template<typename BidiIter, typename T>
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<typename Range, typename T>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_backward(Range & range, const T & x)
{
return ::boost::algorithm::find_backward(boost::begin(range), boost::end(range), x);
}
template<typename BidiIter, typename T>
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<typename Range, typename T>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_not_backward(Range & range, const T & x)
{
return ::boost::algorithm::find_not_backward(boost::begin(range), boost::end(range), x);
}
template<typename BidiIter, typename Pred>
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<typename Range, typename Pred>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_if_backward(Range & range, Pred p)
{
return ::boost::algorithm::find_if_backward(boost::begin(range), boost::end(range), p);
}
template<typename BidiIter, typename Pred>
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<typename Range, typename Pred>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::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

View File

@@ -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 <boost/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <utility>
namespace boost { namespace algorithm {
template<typename InputIter, typename Sentinel, typename T>
BOOST_CXX14_CONSTEXPR
InputIter find_not(InputIter first, Sentinel last, const T & x)
{
for (; first != last; ++first) {
if (*first != x)
break;
}
return first;
}
template<typename Range, typename T>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::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

View File

@@ -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 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)); else BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c));
return retval; return static_cast<char>(retval);
} }
// My own iterator_traits class. // My own iterator_traits class.

View File

@@ -71,26 +71,8 @@ bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predi
template <typename BidirectionalIterator> template <typename BidirectionalIterator>
bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end) bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end)
{ {
if(begin == end) return is_palindrome(begin, end,
{ std::equal_to<typename std::iterator_traits<BidirectionalIterator>::value_type> ());
return true;
}
--end;
while(begin != end)
{
if(!(*begin == *end))
{
return false;
}
++begin;
if(begin == end)
{
break;
}
--end;
}
return true;
} }
/// \fn is_palindrome ( const R& range ) /// \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); return is_palindrome(boost::begin(range), boost::end(range), p);
} }
/// \fn is_palindrome ( const char* str ) /// \fn is_palindrome ( const char* str )
/// \return true if the entire sequence is palindrome /// \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)); return is_palindrome(str, str + strlen(str));
} }
/// \fn is_palindrome ( const char* str, Predicate p ) /// \fn is_palindrome ( const char* str, Predicate p )
/// \return true if the entire sequence is palindrome /// \return true if the entire sequence is palindrome
/// ///
@@ -155,7 +135,6 @@ bool is_palindrome(const char* str, Predicate p)
return true; return true;
return is_palindrome(str, str + strlen(str), p); return is_palindrome(str, str + strlen(str), p);
} }
}} }}
#endif // BOOST_ALGORITHM_IS_PALINDROME_HPP #endif // BOOST_ALGORITHM_IS_PALINDROME_HPP

View File

@@ -0,0 +1,63 @@
/*
Copyright (c) Alexander Zaitsev <zamazan4ik@gmail.by>, 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 <boost/range/begin.hpp>
#include <boost/range/end.hpp>
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 <typename InputIterator, typename UnaryPredicate>
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 Range, typename UnaryPredicate>
typename boost::range_iterator<const Range>::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

View File

@@ -152,8 +152,8 @@ Requirements:
template<typename Iter, typename Container> template<typename Iter, typename Container>
void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) { void compute_bm_prefix ( Iter first, Iter last, Container &prefix ) {
const std::size_t count = std::distance ( pat_first, pat_last ); const std::size_t count = std::distance ( first, last );
BOOST_ASSERT ( count > 0 ); BOOST_ASSERT ( count > 0 );
BOOST_ASSERT ( prefix.size () == count ); BOOST_ASSERT ( prefix.size () == count );
@@ -161,26 +161,26 @@ Requirements:
std::size_t k = 0; std::size_t k = 0;
for ( std::size_t i = 1; i < count; ++i ) { for ( std::size_t i = 1; i < count; ++i ) {
BOOST_ASSERT ( k < count ); BOOST_ASSERT ( k < count );
while ( k > 0 && ( pat_first[k] != pat_first[i] )) { while ( k > 0 && ( first[k] != first[i] )) {
BOOST_ASSERT ( k < count ); BOOST_ASSERT ( k < count );
k = prefix [ k - 1 ]; k = prefix [ k - 1 ];
} }
if ( pat_first[k] == pat_first[i] ) if ( first[k] == first[i] )
k++; k++;
prefix [ i ] = k; prefix [ i ] = k;
} }
} }
void build_suffix_table ( patIter pat_first, patIter pat_last ) { void build_suffix_table ( patIter first, patIter last ) {
const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last ); const std::size_t count = (std::size_t) std::distance ( first, last );
if ( count > 0 ) { // empty pattern if ( count > 0 ) { // empty pattern
std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count); std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count);
(void) std::reverse_copy ( pat_first, pat_last, reversed.begin ()); (void) std::reverse_copy ( first, last, reversed.begin ());
std::vector<difference_type> prefix (count); std::vector<difference_type> prefix (count);
compute_bm_prefix ( pat_first, pat_last, prefix ); compute_bm_prefix ( first, last, prefix );
std::vector<difference_type> prefix_reversed (count); std::vector<difference_type> prefix_reversed (count);
compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed ); compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed );

View File

@@ -155,9 +155,9 @@ namespace boost { namespace algorithm {
void preKmp ( patIter first, patIter last ) { 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; i = 0;
j = skip_[0] = -1; j = skip_[0] = -1;
@@ -177,7 +177,7 @@ namespace boost { namespace algorithm {
void init_skip_table ( patIter first, patIter last ) { void init_skip_table ( patIter first, patIter last ) {
const difference_type count = std::distance ( first, last ); const difference_type count = std::distance ( first, last );
int j; difference_type j;
skip_ [ 0 ] = -1; skip_ [ 0 ] = -1;
for ( int i = 1; i <= count; ++i ) { for ( int i = 1; i <= count; ++i ) {
j = skip_ [ i - 1 ]; j = skip_ [ i - 1 ];

View File

@@ -30,8 +30,10 @@ namespace boost {
// a tolower functor // a tolower functor
template<typename CharT> template<typename CharT>
struct to_lowerF : public std::unary_function<CharT, CharT> struct to_lowerF
{ {
typedef CharT argument_type;
typedef CharT result_type;
// Constructor // Constructor
to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {} to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {}
@@ -50,8 +52,10 @@ namespace boost {
// a toupper functor // a toupper functor
template<typename CharT> template<typename CharT>
struct to_upperF : public std::unary_function<CharT, CharT> struct to_upperF
{ {
typedef CharT argument_type;
typedef CharT result_type;
// Constructor // Constructor
to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {} to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {}

View File

@@ -40,7 +40,7 @@ namespace boost {
// Protected construction/destruction // Protected construction/destruction
// Default constructor // Default constructor
find_iterator_base() {}; find_iterator_base() {}
// Copy construction // Copy construction
find_iterator_base( const find_iterator_base& Other ) : find_iterator_base( const find_iterator_base& Other ) :
m_Finder(Other.m_Finder) {} m_Finder(Other.m_Finder) {}

View File

@@ -89,9 +89,10 @@ namespace boost {
template< template<
typename SeqT, typename SeqT,
typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator >
struct copy_iterator_rangeF : struct copy_iterator_rangeF
public std::unary_function< iterator_range<IteratorT>, SeqT >
{ {
typedef iterator_range<IteratorT> argument_type;
typedef SeqT result_type;
SeqT operator()( const iterator_range<IteratorT>& Range ) const SeqT operator()( const iterator_range<IteratorT>& Range ) const
{ {
return copy_range<SeqT>(Range); return copy_range<SeqT>(Range);

View File

@@ -43,7 +43,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match. The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c first_finder object \return An instance of the \c first_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@@ -84,7 +83,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match. The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c last_finder object \return An instance of the \c last_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@@ -124,7 +122,6 @@ namespace boost {
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Nth An index of the match to be find \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 \return An instance of the \c nth_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@@ -230,7 +227,6 @@ namespace boost {
\param Begin Beginning of the range \param Begin Beginning of the range
\param End End of the range \param End End of the range
\param Range The range.
\return An instance of the \c range_finger object \return An instance of the \c range_finger object
*/ */
template< typename ForwardIteratorT > template< typename ForwardIteratorT >

View File

@@ -28,8 +28,7 @@ namespace alignment {
template<class T, std::size_t Alignment> template<class T, std::size_t Alignment>
class aligned_allocator { class aligned_allocator {
BOOST_STATIC_ASSERT(detail:: BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
is_alignment_constant<Alignment>::value);
public: public:
typedef T value_type; typedef T value_type;
@@ -42,13 +41,6 @@ public:
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
private:
enum {
min_align = detail::max_size<Alignment,
alignment_of<value_type>::value>::value
};
public:
template<class U> template<class U>
struct rebind { struct rebind {
typedef aligned_allocator<U, Alignment> other; typedef aligned_allocator<U, Alignment> other;
@@ -73,10 +65,14 @@ public:
} }
pointer allocate(size_type size, const_void_pointer = 0) { pointer allocate(size_type size, const_void_pointer = 0) {
enum {
m = detail::max_size<Alignment,
alignment_of<value_type>::value>::value
};
if (size == 0) { if (size == 0) {
return 0; return 0;
} }
void* p = aligned_alloc(min_align, sizeof(T) * size); void* p = boost::alignment::aligned_alloc(m, sizeof(T) * size);
if (!p) { if (!p) {
boost::throw_exception(std::bad_alloc()); boost::throw_exception(std::bad_alloc());
} }
@@ -124,8 +120,7 @@ public:
template<std::size_t Alignment> template<std::size_t Alignment>
class aligned_allocator<void, Alignment> { class aligned_allocator<void, Alignment> {
BOOST_STATIC_ASSERT(detail:: BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
is_alignment_constant<Alignment>::value);
public: public:
typedef void value_type; typedef void value_type;

View File

@@ -8,13 +8,13 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP #ifndef BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP #define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
#include <boost/align/detail/addressof.hpp>
#include <boost/align/detail/is_alignment_constant.hpp> #include <boost/align/detail/is_alignment_constant.hpp>
#include <boost/align/detail/max_align.hpp> #include <boost/align/detail/max_align.hpp>
#include <boost/align/detail/max_size.hpp> #include <boost/align/detail/max_size.hpp>
#include <boost/align/align.hpp> #include <boost/align/align.hpp>
#include <boost/align/aligned_allocator_adaptor_forward.hpp> #include <boost/align/aligned_allocator_adaptor_forward.hpp>
#include <boost/align/alignment_of.hpp> #include <boost/align/alignment_of.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <new> #include <new>
@@ -32,56 +32,45 @@ namespace alignment {
template<class Allocator, std::size_t Alignment> template<class Allocator, std::size_t Alignment>
class aligned_allocator_adaptor class aligned_allocator_adaptor
: public Allocator { : public Allocator {
BOOST_STATIC_ASSERT(detail:: BOOST_STATIC_ASSERT(detail::is_alignment_constant<Alignment>::value);
is_alignment_constant<Alignment>::value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR) #if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef std::allocator_traits<Allocator> traits; typedef std::allocator_traits<Allocator> traits;
typedef typename traits::template rebind_alloc<char> char_alloc;
typedef typename traits:: typedef typename traits::template rebind_traits<char> char_traits;
template rebind_alloc<char> char_alloc;
typedef typename traits::
template rebind_traits<char> char_traits;
typedef typename char_traits::pointer char_ptr; typedef typename char_traits::pointer char_ptr;
#else #else
typedef typename Allocator:: typedef typename Allocator::template rebind<char>::other char_alloc;
template rebind<char>::other char_alloc;
typedef typename char_alloc::pointer char_ptr; typedef typename char_alloc::pointer char_ptr;
#endif #endif
public: 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::value_type value_type;
typedef typename Allocator::size_type size_type;
#endif
typedef value_type* pointer; typedef value_type* pointer;
typedef const value_type* const_pointer; typedef const value_type* const_pointer;
typedef void* void_pointer; typedef void* void_pointer;
typedef const void* const_void_pointer; typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
private: private:
template<class U>
struct min_align {
enum { enum {
min_align = detail::max_size<Alignment, value = detail::max_size<Alignment,
detail::max_align<value_type, char_ptr>::value>::value detail::max_align<U, char_ptr>::value>::value
};
}; };
public: public:
template<class U> template<class U>
struct rebind { struct rebind {
#if !defined(BOOST_NO_CXX11_ALLOCATOR) #if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef aligned_allocator_adaptor<typename traits:: typedef aligned_allocator_adaptor<typename traits::template
template rebind_alloc<U>, Alignment> other; rebind_alloc<U>, Alignment> other;
#else #else
typedef aligned_allocator_adaptor<typename Allocator:: typedef aligned_allocator_adaptor<typename Allocator::template
template rebind<U>::other, Alignment> other; rebind<U>::other, Alignment> other;
#endif #endif
}; };
@@ -116,20 +105,25 @@ public:
} }
pointer allocate(size_type size) { pointer allocate(size_type size) {
enum {
m = min_align<value_type>::value
};
std::size_t s = size * sizeof(value_type); 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_alloc a(base());
char_ptr p = a.allocate(sizeof p + n); char_ptr p = a.allocate(sizeof p + n);
void* r = detail::addressof(*p) + sizeof p; void* r = boost::to_address(p) + sizeof p;
(void)align(min_align, s, r, n); (void)boost::alignment::align(m, s, r, n);
::new(static_cast<void*>(static_cast<char_ptr*>(r) ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
- 1)) char_ptr(p);
return static_cast<pointer>(r); return static_cast<pointer>(r);
} }
pointer allocate(size_type size, const_void_pointer hint) { pointer allocate(size_type size, const_void_pointer hint) {
enum {
m = min_align<value_type>::value
};
std::size_t s = size * sizeof(value_type); 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(); char_ptr h = char_ptr();
if (hint) { if (hint) {
h = *(static_cast<const char_ptr*>(hint) - 1); h = *(static_cast<const char_ptr*>(hint) - 1);
@@ -140,20 +134,21 @@ public:
#else #else
char_ptr p = a.allocate(sizeof p + n, h); char_ptr p = a.allocate(sizeof p + n, h);
#endif #endif
void* r = detail::addressof(*p) + sizeof p; void* r = boost::to_address(p) + sizeof p;
(void)align(min_align, s, r, n); (void)boost::alignment::align(m, s, r, n);
::new(static_cast<void*>(static_cast<char_ptr*>(r) ::new(static_cast<void*>(static_cast<char_ptr*>(r) - 1)) char_ptr(p);
- 1)) char_ptr(p);
return static_cast<pointer>(r); return static_cast<pointer>(r);
} }
void deallocate(pointer ptr, size_type size) { void deallocate(pointer ptr, size_type size) {
enum {
m = min_align<value_type>::value
};
char_ptr* p = reinterpret_cast<char_ptr*>(ptr) - 1; char_ptr* p = reinterpret_cast<char_ptr*>(ptr) - 1;
char_ptr r = *p; char_ptr r = *p;
p->~char_ptr(); p->~char_ptr();
char_alloc a(base()); char_alloc a(base());
a.deallocate(r, sizeof r + size * sizeof(value_type) + a.deallocate(r, sizeof r + size * sizeof(value_type) + m - 1);
min_align - 1);
} }
}; };

View File

@@ -20,8 +20,8 @@ align(std::size_t alignment, std::size_t size, void*& ptr,
{ {
BOOST_ASSERT(detail::is_alignment(alignment)); BOOST_ASSERT(detail::is_alignment(alignment));
if (size <= space) { if (size <= space) {
char* p = reinterpret_cast<char*>((reinterpret_cast<std:: char* p = reinterpret_cast<char*>(~(alignment - 1) &
size_t>(ptr) + alignment - 1) & ~(alignment - 1)); (reinterpret_cast<std::size_t>(ptr) + alignment - 1));
std::size_t n = space - (p - static_cast<char*>(ptr)); std::size_t n = space - (p - static_cast<char*>(ptr));
if (size <= n) { if (size <= n) {
ptr = p; ptr = p;

View File

@@ -18,8 +18,8 @@ inline void*
align_down(void* ptr, std::size_t alignment) BOOST_NOEXCEPT align_down(void* ptr, std::size_t alignment) BOOST_NOEXCEPT
{ {
BOOST_ASSERT(detail::is_alignment(alignment)); BOOST_ASSERT(detail::is_alignment(alignment));
return reinterpret_cast<void*>(reinterpret_cast<std:: return reinterpret_cast<void*>(~(alignment - 1) &
size_t>(ptr) & ~(alignment - 1)); reinterpret_cast<std::size_t>(ptr));
} }
} /* alignment */ } /* alignment */

View File

@@ -18,8 +18,8 @@ inline void*
align_up(void* ptr, std::size_t alignment) BOOST_NOEXCEPT align_up(void* ptr, std::size_t alignment) BOOST_NOEXCEPT
{ {
BOOST_ASSERT(detail::is_alignment(alignment)); BOOST_ASSERT(detail::is_alignment(alignment));
return reinterpret_cast<void*>((reinterpret_cast<std:: return reinterpret_cast<void*>(~(alignment - 1) &
size_t>(ptr) + alignment - 1) & ~(alignment - 1)); (reinterpret_cast<std::size_t>(ptr) + alignment - 1));
} }
} /* alignment */ } /* alignment */

View File

@@ -31,7 +31,7 @@ aligned_alloc(std::size_t alignment, std::size_t size) BOOST_NOEXCEPT
void* p = std::malloc(sizeof(void*) + n); void* p = std::malloc(sizeof(void*) + n);
if (p) { if (p) {
void* r = static_cast<char*>(p) + sizeof(void*); void* r = static_cast<char*>(p) + sizeof(void*);
(void)align(alignment, size, r, n); (void)boost::alignment::align(alignment, size, r, n);
*(static_cast<void**>(r) - 1) = p; *(static_cast<void**>(r) - 1) = p;
p = r; p = r;
} }

View File

@@ -23,8 +23,7 @@ struct offset_value {
template<class T> template<class T>
struct alignment_of struct alignment_of
: min_size<sizeof(T), : min_size<sizeof(T), sizeof(offset_value<T>) - (sizeof(T) << 1)> { };
sizeof(offset_value<T>) - (sizeof(T) << 1)> { };
} /* detail */ } /* detail */
} /* alignment */ } /* alignment */

View File

@@ -4,7 +4,6 @@ Copyright 2014 Glen Joseph Fernandes
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt) (http://www.boost.org/LICENSE_1_0.txt)
*/ */
#ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP #ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP
#define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP #define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP

View File

@@ -12,7 +12,7 @@
// with features contributed and bugs found by // with features contributed and bugs found by
// Antony Polukhin, Ed Brey, Mark Rodgers, // Antony Polukhin, Ed Brey, Mark Rodgers,
// Peter Dimov, and James Curran // Peter Dimov, and James Curran
// when: July 2001, April 2013 - May 2013 // when: July 2001, April 2013 - 2019
#include <algorithm> #include <algorithm>
@@ -30,7 +30,7 @@
#include <boost/core/addressof.hpp> #include <boost/core/addressof.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp> #include <boost/type_traits/conditional.hpp>
namespace boost namespace boost
{ {
@@ -109,7 +109,7 @@ namespace boost
return *this; return *this;
} }
// move assignement // move assignment
any & operator=(any&& rhs) BOOST_NOEXCEPT any & operator=(any&& rhs) BOOST_NOEXCEPT
{ {
rhs.swap(*this); rhs.swap(*this);
@@ -149,7 +149,7 @@ namespace boost
public: // types (public so any_cast can be non-friend) public: // types (public so any_cast can be non-friend)
#endif #endif
class placeholder class BOOST_SYMBOL_VISIBLE placeholder
{ {
public: // structors public: // structors
@@ -271,8 +271,8 @@ namespace boost
// `ValueType` is not a reference. Example: // `ValueType` is not a reference. Example:
// `static_cast<std::string>(*result);` // `static_cast<std::string>(*result);`
// which is equal to `std::string(*result);` // which is equal to `std::string(*result);`
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_reference<ValueType>, boost::is_reference<ValueType>::value,
ValueType, ValueType,
BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
>::type ref_type; >::type ref_type;
@@ -329,6 +329,7 @@ namespace boost
} }
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
// Copyright Antony Polukhin, 2013-2019.
// //
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at

View File

@@ -127,11 +127,11 @@ public:
} }
// used for text output // used for text output
operator int () const { operator base_type () const {
return t; return t;
} }
// used for text input // used for text input
operator int_least16_t &() { operator base_type &() {
return t; return t;
} }
bool operator==(const class_id_type & rhs) const { bool operator==(const class_id_type & rhs) const {
@@ -151,7 +151,10 @@ private:
public: public:
object_id_type(): t(0) {}; object_id_type(): t(0) {};
// note: presumes that size_t >= unsigned int. // 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<base_type>(t_)){
// make quadriple sure that we haven't lost any real integer
// precision
BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max); BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max);
} }
object_id_type(const object_id_type & t_) : object_id_type(const object_id_type & t_) :
@@ -162,11 +165,11 @@ public:
return *this; return *this;
} }
// used for text output // used for text output
operator uint_least32_t () const { operator base_type () const {
return t; return t;
} }
// used for text input // used for text input
operator uint_least32_t & () { operator base_type & () {
return t; return t;
} }
bool operator==(const object_id_type & rhs) const { bool operator==(const object_id_type & rhs) const {

View File

@@ -102,17 +102,29 @@ protected:
} }
void load_override(class_id_type & t){ void load_override(class_id_type & t){
library_version_type lvt = this->get_library_version(); 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){ if(boost::archive::library_version_type(7) < lvt){
this->detail_common_iarchive::load_override(t); 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{ else{
int x=0; int_least16_t x=0;
* this->This() >> x; * this->This() >> x;
t = boost::archive::class_id_type(x); t = boost::archive::class_id_type(x);
} }

View File

@@ -21,7 +21,7 @@
// //
// note the fact that on libraries without wide characters, ostream is // note the fact that on libraries without wide characters, ostream is
// is not a specialization of basic_ostream which in fact is not defined // is not a specialization of basic_ostream which in fact is not defined
// in such cases. So we can't use basic_ostream<IStream::char_type> but rather // in such cases. So we can't use basic_istream<IStream::char_type> but rather
// use two template parameters // use two template parameters
#include <boost/config.hpp> #include <boost/config.hpp>

View File

@@ -18,8 +18,11 @@
#include <locale> #include <locale>
#include <cstddef> // NULL, size_t #include <cstddef> // NULL, size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // for mbstate_t #include <cwchar> // for mbstate_t
#endif
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/archive/detail/auto_link_archive.hpp> #include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header #include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@@ -60,9 +63,10 @@ public:
}; };
template<> template<>
class BOOST_SYMBOL_VISIBLE codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t> class BOOST_WARCHIVE_DECL codecvt_null<wchar_t> :
public std::codecvt<wchar_t, char, std::mbstate_t>
{ {
virtual BOOST_WARCHIVE_DECL std::codecvt_base::result virtual std::codecvt_base::result
do_out( do_out(
std::mbstate_t & state, std::mbstate_t & state,
const wchar_t * first1, const wchar_t * first1,
@@ -72,7 +76,7 @@ class BOOST_SYMBOL_VISIBLE codecvt_null<wchar_t> : public std::codecvt<wchar_t,
char * last2, char * last2,
char * & next2 char * & next2
) const; ) const;
virtual BOOST_WARCHIVE_DECL std::codecvt_base::result virtual std::codecvt_base::result
do_in( do_in(
std::mbstate_t & state, std::mbstate_t & state,
const char * first1, const char * first1,
@@ -92,7 +96,7 @@ public:
explicit codecvt_null(std::size_t no_locale_manage = 0) : explicit codecvt_null(std::size_t no_locale_manage = 0) :
std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage) std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
{} {}
virtual ~codecvt_null(){}; //virtual ~codecvt_null(){};
}; };
} // namespace archive } // namespace archive

View File

@@ -40,6 +40,7 @@ class BOOST_SYMBOL_VISIBLE common_iarchive :
public interface_iarchive<Archive> public interface_iarchive<Archive>
{ {
friend class interface_iarchive<Archive>; friend class interface_iarchive<Archive>;
friend class basic_iarchive;
private: private:
virtual void vload(version_type & t){ virtual void vload(version_type & t){
* this->This() >> t; * this->This() >> t;

View File

@@ -38,6 +38,7 @@ class BOOST_SYMBOL_VISIBLE common_oarchive :
public interface_oarchive<Archive> public interface_oarchive<Archive>
{ {
friend class interface_oarchive<Archive>; friend class interface_oarchive<Archive>;
friend class basic_oarchive;
private: private:
virtual void vsave(const version_type t){ virtual void vsave(const version_type t){
* this->This() << t; * this->This() << t;

View File

@@ -57,11 +57,10 @@ namespace std{
#include <boost/serialization/assume_abstract.hpp> #include <boost/serialization/assume_abstract.hpp>
#ifndef BOOST_MSVC #if !defined(BOOST_MSVC) && \
#define DONT_USE_HAS_NEW_OPERATOR ( \ (BOOST_WORKAROUND(__IBMCPP__, < 1210) || \
BOOST_WORKAROUND(__IBMCPP__, < 1210) \ defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590))
|| defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ #define DONT_USE_HAS_NEW_OPERATOR 1
)
#else #else
#define DONT_USE_HAS_NEW_OPERATOR 0 #define DONT_USE_HAS_NEW_OPERATOR 0
#endif #endif
@@ -90,6 +89,8 @@ namespace std{
#include <boost/archive/detail/archive_serializer_map.hpp> #include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp> #include <boost/archive/detail/check.hpp>
#include <boost/core/addressof.hpp>
namespace boost { namespace boost {
namespace serialization { namespace serialization {
@@ -122,8 +123,7 @@ private:
virtual void destroy(/*const*/ void *address) const { virtual void destroy(/*const*/ void *address) const {
boost::serialization::access::destroy(static_cast<T *>(address)); boost::serialization::access::destroy(static_cast<T *>(address));
} }
protected: public:
// protected constructor since it's always created by singleton
explicit iserializer() : explicit iserializer() :
basic_iserializer( basic_iserializer(
boost::serialization::singleton< boost::serialization::singleton<
@@ -132,7 +132,6 @@ protected:
>::get_const_instance() >::get_const_instance()
) )
{} {}
public:
virtual BOOST_DLLEXPORT void load_object_data( virtual BOOST_DLLEXPORT void load_object_data(
basic_iarchive & ar, basic_iarchive & ar,
void *x, void *x,
@@ -234,7 +233,7 @@ struct heap_allocation {
// that the class might have class specific new with NO // that the class might have class specific new with NO
// class specific delete at all. Patches (compatible with // class specific delete at all. Patches (compatible with
// C++03) welcome! // C++03) welcome!
delete t; (operator delete)(t);
} }
}; };
struct doesnt_have_new_operator { struct doesnt_have_new_operator {
@@ -243,7 +242,7 @@ struct heap_allocation {
} }
static void invoke_delete(T * t) { static void invoke_delete(T * t) {
// Note: I'm reliance upon automatic conversion from T * to void * here // Note: I'm reliance upon automatic conversion from T * to void * here
delete t; (operator delete)(t);
} }
}; };
static T * invoke_new() { static T * invoke_new() {
@@ -306,7 +305,7 @@ private:
void * x, void * x,
const unsigned int file_version const unsigned int file_version
) const BOOST_USED; ) const BOOST_USED;
protected: public:
// this should alway be a singleton so make the constructor protected // this should alway be a singleton so make the constructor protected
pointer_iserializer(); pointer_iserializer();
~pointer_iserializer(); ~pointer_iserializer();
@@ -406,7 +405,7 @@ struct load_non_pointer_type {
struct load_standard { struct load_standard {
template<class T> template<class T>
static void invoke(Archive &ar, const T & t){ static void invoke(Archive &ar, const T & t){
void * x = & const_cast<T &>(t); void * x = boost::addressof(const_cast<T &>(t));
ar.load_object( ar.load_object(
x, x,
boost::serialization::singleton< boost::serialization::singleton<
@@ -484,7 +483,7 @@ struct load_pointer_type {
}; };
template<class T> template<class T>
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 // there should never be any need to load an abstract polymorphic
// class pointer. Inhibiting code generation for this // class pointer. Inhibiting code generation for this
// permits abstract base classes to be used - note: exception // permits abstract base classes to be used - note: exception
@@ -523,7 +522,7 @@ struct load_pointer_type {
} }
template<class T> template<class T>
static void check_load(T & /* t */){ static void check_load(T * const /* t */){
check_pointer_level< T >(); check_pointer_level< T >();
check_pointer_tracking< T >(); check_pointer_tracking< T >();
} }
@@ -537,8 +536,8 @@ struct load_pointer_type {
template<class Tptr> template<class Tptr>
static void invoke(Archive & ar, Tptr & t){ static void invoke(Archive & ar, Tptr & t){
check_load(*t); check_load(t);
const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); const basic_pointer_iserializer * bpis_ptr = register_type(ar, t);
const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
// note major hack here !!! // note major hack here !!!
// I tried every way to convert Tptr &t (where Tptr might // I tried every way to convert Tptr &t (where Tptr might
@@ -605,7 +604,7 @@ template<class Archive, class T>
inline void load(Archive & ar, T &t){ inline void load(Archive & ar, T &t){
// if this assertion trips. It means we're trying to load a // if this assertion trips. It means we're trying to load a
// const object with a compiler that doesn't have correct // 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. // handled below.
detail::check_const_loading< T >(); detail::check_const_loading< T >();
typedef typedef

View File

@@ -26,6 +26,7 @@
#include <cstddef> // NULL #include <cstddef> // NULL
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
@@ -68,6 +69,8 @@
#include <boost/archive/detail/archive_serializer_map.hpp> #include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp> #include <boost/archive/detail/check.hpp>
#include <boost/core/addressof.hpp>
namespace boost { namespace boost {
namespace serialization { namespace serialization {
@@ -253,7 +256,7 @@ struct save_non_pointer_type {
template<class T> template<class T>
static void invoke(Archive &ar, const T & t){ static void invoke(Archive &ar, const T & t){
ar.save_object( ar.save_object(
& t, boost::addressof(t),
boost::serialization::singleton< boost::serialization::singleton<
oserializer<Archive, T> oserializer<Archive, T>
>::get_const_instance() >::get_const_instance()
@@ -261,6 +264,8 @@ struct save_non_pointer_type {
} }
}; };
// adds class information to the archive. This includes // adds class information to the archive. This includes
// serialization level and class version // serialization level and class version
struct save_conditional { struct save_conditional {
@@ -338,7 +343,7 @@ struct save_pointer_type {
}; };
template<class T> template<class T>
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 // there should never be any need to save an abstract polymorphic
// class pointer. Inhibiting code generation for this // class pointer. Inhibiting code generation for this
// permits abstract base classes to be used - note: exception // 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 // if its not a pointer to a more derived type
const void *vp = static_cast<const void *>(&t); const void *vp = static_cast<const void *>(&t);
if(*this_type == *true_type){ 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); ar.save_pointer(vp, bpos);
return; return;
} }
@@ -464,7 +469,7 @@ struct save_pointer_type {
template<class TPtr> template<class TPtr>
static void invoke(Archive &ar, const TPtr t){ static void invoke(Archive &ar, const TPtr t){
register_type(ar, * t); register_type(ar, t);
if(NULL == t){ if(NULL == t){
basic_oarchive & boa basic_oarchive & boa
= boost::serialization::smart_cast_reference<basic_oarchive &>(ar); = boost::serialization::smart_cast_reference<basic_oarchive &>(ar);

View File

@@ -13,9 +13,6 @@
#error "wide char i/o not supported on this platform" #error "wide char i/o not supported on this platform"
#endif #endif
// std::codecvt_utf8 doesn't seem to work for any versions of msvc
#if defined(_MSC_VER) || defined(BOOST_NO_CXX11_HDR_CODECVT)
// use boost's utf8 codecvt facet // use boost's utf8 codecvt facet
#include <boost/archive/detail/decl.hpp> #include <boost/archive/detail/decl.hpp>
#define BOOST_UTF8_BEGIN_NAMESPACE \ #define BOOST_UTF8_BEGIN_NAMESPACE \
@@ -28,12 +25,5 @@
#undef BOOST_UTF8_END_NAMESPACE #undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL #undef BOOST_UTF8_DECL
#undef BOOST_UTF8_BEGIN_NAMESPACE #undef BOOST_UTF8_BEGIN_NAMESPACE
#else
// use the standard vendor supplied facet
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif
#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP #endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP

View File

@@ -47,6 +47,10 @@ archive_serializer_map<Archive>::insert(const basic_serializer * bs){
template<class Archive> template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void BOOST_ARCHIVE_OR_WARCHIVE_DECL void
archive_serializer_map<Archive>::erase(const basic_serializer * bs){ archive_serializer_map<Archive>::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< if(boost::serialization::singleton<
extra_detail::map<Archive> extra_detail::map<Archive>
>::is_destroyed()) >::is_destroyed())

View File

@@ -84,6 +84,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::init()
); );
} }
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws) basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
@@ -93,6 +95,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); load_binary(ws, l * sizeof(wchar_t) / sizeof(char));
ws[l] = L'\0'; ws[l] = L'\0';
} }
#endif
#endif
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void BOOST_ARCHIVE_OR_WARCHIVE_DECL void
@@ -110,7 +114,6 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(std::string & s)
load_binary(&(*s.begin()), l); load_binary(&(*s.begin()), l);
} }
#ifndef BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s) basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
@@ -120,7 +123,6 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
load_binary(s, l); load_binary(s, l);
s[l] = '\0'; s[l] = '\0';
} }
#endif
#ifndef BOOST_NO_STD_WSTRING #ifndef BOOST_NO_STD_WSTRING
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>

View File

@@ -71,6 +71,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
} }
#ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws) basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
@@ -91,6 +92,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char));
} }
#endif #endif
#endif // BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr> template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_ARCHIVE_OR_WARCHIVE_DECL

View File

@@ -64,7 +64,7 @@ namespace archive {
// XML grammar parsing // XML grammar parsing
template<class CharType> template<class CharType>
class basic_xml_grammar { class BOOST_SYMBOL_VISIBLE basic_xml_grammar {
public: public:
// The following is not necessary according to DR45, but at least // The following is not necessary according to DR45, but at least
// one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise.
@@ -135,7 +135,7 @@ private:
Sch, Sch,
NameChar; NameChar;
BOOST_SYMBOL_VISIBLE void init_chset(); void init_chset();
bool my_parse( bool my_parse(
IStream & is, IStream & is,
@@ -143,7 +143,7 @@ private:
const CharType delimiter = L'>' const CharType delimiter = L'>'
) const ; ) const ;
public: public:
BOOST_SYMBOL_VISIBLE struct return_values { struct return_values {
StringType object_name; StringType object_name;
StringType contents; StringType contents;
//class_id_type class_id; //class_id_type class_id;
@@ -159,12 +159,12 @@ public:
tracking_level(false) tracking_level(false)
{} {}
} rv; } rv;
BOOST_SYMBOL_VISIBLE bool parse_start_tag(IStream & is) /*const*/; bool parse_start_tag(IStream & is) /*const*/;
BOOST_SYMBOL_VISIBLE bool parse_end_tag(IStream & is) const; bool parse_end_tag(IStream & is) const;
BOOST_SYMBOL_VISIBLE bool parse_string(IStream & is, StringType & s) /*const*/; bool parse_string(IStream & is, StringType & s) /*const*/;
BOOST_SYMBOL_VISIBLE void init(IStream & is); void init(IStream & is);
BOOST_SYMBOL_VISIBLE bool windup(IStream & is); bool windup(IStream & is);
BOOST_SYMBOL_VISIBLE basic_xml_grammar(); basic_xml_grammar();
}; };
} // namespace archive } // namespace archive

View File

@@ -56,7 +56,7 @@ text_wiarchive_impl<Archive>::load(std::string &s)
s.resize(0); s.resize(0);
s.reserve(size); s.reserve(size);
while(size-- > 0){ while(size-- > 0){
int x = is.narrow(is.get(), '\0'); char x = is.narrow(is.get(), '\0');
s += x; s += x;
} }
} }

View File

@@ -161,13 +161,13 @@ xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
gimpl(new xml_wgrammar()) gimpl(new xml_wgrammar())
{ {
if(0 == (flags & no_codecvt)){ if(0 == (flags & no_codecvt)){
std::locale l = std::locale( archive_locale = std::locale(
is_.getloc(), is_.getloc(),
new boost::archive::detail::utf8_codecvt_facet new boost::archive::detail::utf8_codecvt_facet
); );
// libstdc++ crashes without this // libstdc++ crashes without this
is_.sync(); is_.sync();
is_.imbue(l); is_.imbue(archive_locale);
} }
if(0 == (flags & no_header)) if(0 == (flags & no_header))
init(); init();

View File

@@ -17,7 +17,9 @@
#include <cstring> // strlen #include <cstring> // strlen
#include <cstdlib> // mbtowc #include <cstdlib> // mbtowc
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // wcslen #include <cwchar> // wcslen
#endif
#include <boost/config.hpp> #include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE) #if defined(BOOST_NO_STDC_NAMESPACE)
@@ -101,7 +103,6 @@ xml_woarchive_impl<Archive>::save(const char * s){
template<class Archive> template<class Archive>
BOOST_WARCHIVE_DECL void BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const wchar_t * ws){ xml_woarchive_impl<Archive>::save(const wchar_t * ws){
os << ws;
typedef iterators::xml_escape<const wchar_t *> xmbtows; typedef iterators::xml_escape<const wchar_t *> xmbtows;
std::copy( std::copy(
xmbtows(ws), xmbtows(ws),
@@ -124,12 +125,12 @@ xml_woarchive_impl<Archive>::xml_woarchive_impl(
basic_xml_oarchive<Archive>(flags) basic_xml_oarchive<Archive>(flags)
{ {
if(0 == (flags & no_codecvt)){ if(0 == (flags & no_codecvt)){
std::locale l = std::locale( archive_locale = std::locale(
os_.getloc(), os_.getloc(),
new boost::archive::detail::utf8_codecvt_facet new boost::archive::detail::utf8_codecvt_facet
); );
os_.flush(); os_.flush();
os_.imbue(l); os_.imbue(archive_locale);
} }
if(0 == (flags & no_header)) if(0 == (flags & no_header))
this->init(); this->init();
@@ -141,7 +142,7 @@ xml_woarchive_impl<Archive>::~xml_woarchive_impl(){
if(std::uncaught_exception()) if(std::uncaught_exception())
return; return;
if(0 == (this->get_flags() & no_header)){ if(0 == (this->get_flags() & no_header)){
save(L"</boost_serialization>\n"); os << L"</boost_serialization>";
} }
} }

View File

@@ -41,7 +41,7 @@ template<class CharType>
struct from_6_bit { struct from_6_bit {
typedef CharType result_type; typedef CharType result_type;
CharType operator()(CharType t) const{ CharType operator()(CharType t) const{
const char * lookup_table = static const char * lookup_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
"0123456789" "0123456789"

View File

@@ -37,7 +37,7 @@ template<class CharType>
struct to_6_bit { struct to_6_bit {
typedef CharType result_type; typedef CharType result_type;
CharType operator()(CharType t) const{ 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,-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, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,

View File

@@ -102,7 +102,8 @@ public:
super_t(base), super_t(base),
m_bnext(NULL), m_bnext(NULL),
m_bend(NULL), m_bend(NULL),
m_full(false) m_full(false),
m_current_value(0)
{ {
} }
}; };

View File

@@ -56,7 +56,7 @@ class istream_iterator :
//Access the value referred to //Access the value referred to
Elem dereference() const { Elem dereference() const {
return m_istream->peek(); return static_cast<Elem>(m_istream->peek());
} }
void increment(){ void increment(){
@@ -75,14 +75,14 @@ public:
} }
istream_iterator() : istream_iterator() :
m_istream(NULL) m_istream(NULL),
m_current_value(NULL)
{} {}
istream_iterator(const istream_iterator<Elem> & rhs) : istream_iterator(const istream_iterator<Elem> & rhs) :
m_istream(rhs.m_istream), m_istream(rhs.m_istream),
m_current_value(rhs.m_current_value) m_current_value(rhs.m_current_value)
{} {}
}; };
} // namespace iterators } // namespace iterators

View File

@@ -18,8 +18,9 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cstddef> // size_t #include <cstddef> // size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // mbstate_t #include <cwchar> // mbstate_t
#endif
#include <boost/config.hpp> #include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE) #if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{ namespace std{
@@ -85,12 +86,15 @@ class mb_from_wchar
wchar_t value = * this->base_reference(); wchar_t value = * this->base_reference();
const wchar_t *wend; const wchar_t *wend;
char *bend; char *bend;
std::codecvt_base::result r = m_codecvt_facet.out( BOOST_VERIFY(
m_codecvt_facet.out(
m_mbs, m_mbs,
& value, & value + 1, wend, & value, & value + 1, wend,
m_buffer, m_buffer + sizeof(m_buffer), bend m_buffer, m_buffer + sizeof(m_buffer), bend
)
==
std::codecvt_base::ok
); );
BOOST_ASSERT(std::codecvt_base::ok == r);
m_bnext = 0; m_bnext = 0;
m_bend = bend - m_buffer; m_bend = bend - m_buffer;
} }

View File

@@ -111,6 +111,7 @@ public:
transform_width(T start) : transform_width(T start) :
super_t(Base(static_cast< T >(start))), super_t(Base(static_cast< T >(start))),
m_buffer_out_full(false), m_buffer_out_full(false),
m_buffer_out(0),
// To disable GCC warning, but not truly necessary // To disable GCC warning, but not truly necessary
//(m_buffer_in will be initialized later before being //(m_buffer_in will be initialized later before being
//used because m_remaining_bits == 0) //used because m_remaining_bits == 0)

View File

@@ -19,7 +19,9 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cctype> #include <cctype>
#include <cstddef> // size_t #include <cstddef> // size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // mbstate_t #include <cwchar> // mbstate_t
#endif
#include <algorithm> // copy #include <algorithm> // copy
#include <boost/config.hpp> #include <boost/config.hpp>

View File

@@ -16,6 +16,8 @@
// See http://www.boost.org for updates, documentation, and revision history. // See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/serialization/throw_exception.hpp> #include <boost/serialization/throw_exception.hpp>
@@ -42,11 +44,11 @@ class xml_unescape
return unescape<xml_unescape<Base>, Base>::dereference(); return unescape<xml_unescape<Base>, Base>::dereference();
} }
public: public:
// workaround msvc 7.1 ICU crash // msvc versions prior to 14.0 crash with and ICE
#if defined(BOOST_MSVC) #if BOOST_WORKAROUND(BOOST_MSVC, < 1900)
typedef int value_type; typedef int value_type;
#else #else
typedef typename this_t::value_type value_type; typedef typename super_t::value_type value_type;
#endif #endif
void drain_residue(const char *literal); void drain_residue(const char *literal);

View File

@@ -28,7 +28,7 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
class polymorphic_binary_iarchive : class BOOST_SYMBOL_VISIBLE polymorphic_binary_iarchive :
public detail::polymorphic_iarchive_route<binary_iarchive> public detail::polymorphic_iarchive_route<binary_iarchive>
{ {
public: public:

View File

@@ -23,13 +23,15 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
typedef detail::polymorphic_oarchive_route< class BOOST_SYMBOL_VISIBLE polymorphic_binary_oarchive :
binary_oarchive_impl< public detail::polymorphic_oarchive_route<binary_oarchive>
binary_oarchive, {
std::ostream::char_type, public:
std::ostream::traits_type polymorphic_binary_oarchive(std::ostream & os, unsigned int flags = 0) :
> detail::polymorphic_oarchive_route<binary_oarchive>(os, flags)
> polymorphic_binary_oarchive; {}
~polymorphic_binary_oarchive(){}
};
} // namespace archive } // namespace archive
} // namespace boost } // namespace boost

View File

@@ -28,7 +28,7 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
class polymorphic_text_iarchive : class BOOST_SYMBOL_VISIBLE polymorphic_text_iarchive :
public detail::polymorphic_iarchive_route<text_iarchive> public detail::polymorphic_iarchive_route<text_iarchive>
{ {
public: public:

View File

@@ -23,9 +23,15 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
typedef detail::polymorphic_oarchive_route< class BOOST_SYMBOL_VISIBLE polymorphic_text_oarchive :
text_oarchive_impl<text_oarchive> public detail::polymorphic_oarchive_route<text_oarchive>
> polymorphic_text_oarchive; {
public:
polymorphic_text_oarchive(std::ostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<text_oarchive>(os, flags)
{}
~polymorphic_text_oarchive(){}
};
} // namespace archive } // namespace archive
} // namespace boost } // namespace boost

View File

@@ -32,7 +32,7 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
class polymorphic_text_wiarchive : class BOOST_SYMBOL_VISIBLE polymorphic_text_wiarchive :
public detail::polymorphic_iarchive_route<text_wiarchive> public detail::polymorphic_iarchive_route<text_wiarchive>
{ {
public: public:

View File

@@ -27,9 +27,15 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
typedef detail::polymorphic_oarchive_route< class BOOST_SYMBOL_VISIBLE polymorphic_text_woarchive :
text_woarchive_impl<text_woarchive> public detail::polymorphic_oarchive_route<text_woarchive>
> polymorphic_text_woarchive; {
public:
polymorphic_text_woarchive(std::wostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<text_woarchive>(os, flags)
{}
~polymorphic_text_woarchive(){}
};
} // namespace archive } // namespace archive
} // namespace boost } // namespace boost

View File

@@ -28,7 +28,7 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
class polymorphic_xml_iarchive : class BOOST_SYMBOL_VISIBLE polymorphic_xml_iarchive :
public detail::polymorphic_iarchive_route<xml_iarchive> public detail::polymorphic_iarchive_route<xml_iarchive>
{ {
public: public:

View File

@@ -23,10 +23,15 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
typedef detail::polymorphic_oarchive_route< class BOOST_SYMBOL_VISIBLE polymorphic_xml_oarchive :
xml_oarchive_impl<xml_oarchive> public detail::polymorphic_oarchive_route<xml_oarchive>
> polymorphic_xml_oarchive; {
public:
polymorphic_xml_oarchive(std::ostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<xml_oarchive>(os, flags)
{}
~polymorphic_xml_oarchive(){}
};
} // namespace archive } // namespace archive
} // namespace boost } // namespace boost

View File

@@ -27,7 +27,7 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
class polymorphic_xml_wiarchive : class BOOST_SYMBOL_VISIBLE polymorphic_xml_wiarchive :
public detail::polymorphic_iarchive_route<xml_wiarchive> public detail::polymorphic_iarchive_route<xml_wiarchive>
{ {
public: public:

View File

@@ -7,7 +7,7 @@
#endif #endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 /////////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 . // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software // Use, modification and distribution is subject to the Boost Software
@@ -27,9 +27,15 @@
namespace boost { namespace boost {
namespace archive { namespace archive {
typedef detail::polymorphic_oarchive_route< class BOOST_SYMBOL_VISIBLE polymorphic_xml_woarchive :
xml_woarchive_impl<xml_woarchive> public detail::polymorphic_oarchive_route<xml_woarchive>
> polymorphic_xml_woarchive; {
public:
polymorphic_xml_woarchive(std::wostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<xml_woarchive>(os, flags)
{}
~polymorphic_xml_woarchive(){}
};
} // namespace archive } // namespace archive
} // namespace boost } // namespace boost

View File

@@ -65,10 +65,10 @@ protected:
basic_text_oprimitive<std::ostream>::save(t); basic_text_oprimitive<std::ostream>::save(t);
} }
void save(const version_type & t){ void save(const version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
void save(const boost::serialization::item_version_type & t){ void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
BOOST_ARCHIVE_DECL void BOOST_ARCHIVE_DECL void
save(const char * t); save(const char * t);

View File

@@ -78,10 +78,10 @@ protected:
basic_text_oprimitive<std::wostream>::save(t); basic_text_oprimitive<std::wostream>::save(t);
} }
void save(const version_type & t){ void save(const version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
void save(const boost::serialization::item_version_type & t){ void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
BOOST_WARCHIVE_DECL void BOOST_WARCHIVE_DECL void
save(const char * t); save(const char * t);

View File

@@ -44,7 +44,9 @@ inline std::size_t wcslen(const wchar_t * ws)
#else #else
#ifndef BOOST_NO_CWCHAR
#include <cwchar> #include <cwchar>
#endif
#ifdef BOOST_NO_STDC_NAMESPACE #ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::wcslen; } namespace std{ using ::wcslen; }
#endif #endif

View File

@@ -65,11 +65,11 @@ protected:
} }
void void
save(const version_type & t){ save(const version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
void void
save(const boost::serialization::item_version_type & t){ save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
BOOST_ARCHIVE_DECL void BOOST_ARCHIVE_DECL void
save(const char * t); save(const char * t);

View File

@@ -62,6 +62,7 @@ protected:
friend class basic_xml_iarchive<Archive>; friend class basic_xml_iarchive<Archive>;
friend class load_access; friend class load_access;
#endif #endif
std::locale archive_locale;
boost::scoped_ptr<xml_wgrammar> gimpl; boost::scoped_ptr<xml_wgrammar> gimpl;
std::wistream & get_is(){ std::wistream & get_is(){
return is; return is;

View File

@@ -74,11 +74,11 @@ protected:
} }
void void
save(const version_type & t){ save(const version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
void void
save(const boost::serialization::item_version_type & t){ save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t)); save(static_cast<unsigned int>(t));
} }
BOOST_WARCHIVE_DECL void BOOST_WARCHIVE_DECL void
save(const char * t); save(const char * t);

View File

@@ -183,7 +183,7 @@ namespace boost {
// check range (may be private because it is static) // check range (may be private because it is static)
static BOOST_CONSTEXPR bool rangecheck (size_type i) { 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;
} }
}; };

View File

@@ -2,7 +2,7 @@
// asio.hpp // 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 // 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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,7 +17,10 @@
# pragma once # pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/async_result.hpp> #include <boost/asio/async_result.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/basic_datagram_socket.hpp> #include <boost/asio/basic_datagram_socket.hpp>
#include <boost/asio/basic_deadline_timer.hpp> #include <boost/asio/basic_deadline_timer.hpp>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/basic_io_object.hpp>
@@ -25,12 +28,14 @@
#include <boost/asio/basic_seq_packet_socket.hpp> #include <boost/asio/basic_seq_packet_socket.hpp>
#include <boost/asio/basic_serial_port.hpp> #include <boost/asio/basic_serial_port.hpp>
#include <boost/asio/basic_signal_set.hpp> #include <boost/asio/basic_signal_set.hpp>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/basic_socket_acceptor.hpp> #include <boost/asio/basic_socket_acceptor.hpp>
#include <boost/asio/basic_socket_iostream.hpp> #include <boost/asio/basic_socket_iostream.hpp>
#include <boost/asio/basic_socket_streambuf.hpp> #include <boost/asio/basic_socket_streambuf.hpp>
#include <boost/asio/basic_stream_socket.hpp> #include <boost/asio/basic_stream_socket.hpp>
#include <boost/asio/basic_streambuf.hpp> #include <boost/asio/basic_streambuf.hpp>
#include <boost/asio/basic_waitable_timer.hpp> #include <boost/asio/basic_waitable_timer.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <boost/asio/buffered_read_stream_fwd.hpp> #include <boost/asio/buffered_read_stream_fwd.hpp>
#include <boost/asio/buffered_read_stream.hpp> #include <boost/asio/buffered_read_stream.hpp>
@@ -39,13 +44,19 @@
#include <boost/asio/buffered_write_stream_fwd.hpp> #include <boost/asio/buffered_write_stream_fwd.hpp>
#include <boost/asio/buffered_write_stream.hpp> #include <boost/asio/buffered_write_stream.hpp>
#include <boost/asio/buffers_iterator.hpp> #include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/completion_condition.hpp> #include <boost/asio/completion_condition.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/connect.hpp> #include <boost/asio/connect.hpp>
#include <boost/asio/coroutine.hpp> #include <boost/asio/coroutine.hpp>
#include <boost/asio/datagram_socket_service.hpp>
#include <boost/asio/deadline_timer_service.hpp>
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/deadline_timer.hpp>
#include <boost/asio/defer.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/generic/basic_endpoint.hpp> #include <boost/asio/generic/basic_endpoint.hpp>
#include <boost/asio/generic/datagram_protocol.hpp> #include <boost/asio/generic/datagram_protocol.hpp>
#include <boost/asio/generic/raw_protocol.hpp> #include <boost/asio/generic/raw_protocol.hpp>
@@ -54,11 +65,21 @@
#include <boost/asio/handler_alloc_hook.hpp> #include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp> #include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp> #include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/handler_type.hpp> #include <boost/asio/high_resolution_timer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_context_strand.hpp>
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>
#include <boost/asio/io_service_strand.hpp>
#include <boost/asio/ip/address.hpp> #include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/address_v4.hpp> #include <boost/asio/ip/address_v4.hpp>
#include <boost/asio/ip/address_v4_iterator.hpp>
#include <boost/asio/ip/address_v4_range.hpp>
#include <boost/asio/ip/address_v6.hpp> #include <boost/asio/ip/address_v6.hpp>
#include <boost/asio/ip/address_v6_iterator.hpp>
#include <boost/asio/ip/address_v6_range.hpp>
#include <boost/asio/ip/network_v4.hpp>
#include <boost/asio/ip/network_v6.hpp>
#include <boost/asio/ip/bad_address_cast.hpp>
#include <boost/asio/ip/basic_endpoint.hpp> #include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/basic_resolver.hpp> #include <boost/asio/ip/basic_resolver.hpp>
#include <boost/asio/ip/basic_resolver_entry.hpp> #include <boost/asio/ip/basic_resolver_entry.hpp>
@@ -67,54 +88,58 @@
#include <boost/asio/ip/host_name.hpp> #include <boost/asio/ip/host_name.hpp>
#include <boost/asio/ip/icmp.hpp> #include <boost/asio/ip/icmp.hpp>
#include <boost/asio/ip/multicast.hpp> #include <boost/asio/ip/multicast.hpp>
#include <boost/asio/ip/resolver_base.hpp>
#include <boost/asio/ip/resolver_query_base.hpp> #include <boost/asio/ip/resolver_query_base.hpp>
#include <boost/asio/ip/resolver_service.hpp>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp> #include <boost/asio/ip/udp.hpp>
#include <boost/asio/ip/unicast.hpp> #include <boost/asio/ip/unicast.hpp>
#include <boost/asio/ip/v6_only.hpp> #include <boost/asio/ip/v6_only.hpp>
#include <boost/asio/is_executor.hpp>
#include <boost/asio/is_read_buffered.hpp> #include <boost/asio/is_read_buffered.hpp>
#include <boost/asio/is_write_buffered.hpp> #include <boost/asio/is_write_buffered.hpp>
#include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/local/basic_endpoint.hpp>
#include <boost/asio/local/connect_pair.hpp> #include <boost/asio/local/connect_pair.hpp>
#include <boost/asio/local/datagram_protocol.hpp> #include <boost/asio/local/datagram_protocol.hpp>
#include <boost/asio/local/stream_protocol.hpp> #include <boost/asio/local/stream_protocol.hpp>
#include <boost/asio/packaged_task.hpp>
#include <boost/asio/placeholders.hpp> #include <boost/asio/placeholders.hpp>
#include <boost/asio/posix/basic_descriptor.hpp> #include <boost/asio/posix/basic_descriptor.hpp>
#include <boost/asio/posix/basic_stream_descriptor.hpp> #include <boost/asio/posix/basic_stream_descriptor.hpp>
#include <boost/asio/posix/descriptor.hpp>
#include <boost/asio/posix/descriptor_base.hpp> #include <boost/asio/posix/descriptor_base.hpp>
#include <boost/asio/posix/stream_descriptor.hpp> #include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/posix/stream_descriptor_service.hpp> #include <boost/asio/post.hpp>
#include <boost/asio/raw_socket_service.hpp>
#include <boost/asio/read.hpp> #include <boost/asio/read.hpp>
#include <boost/asio/read_at.hpp> #include <boost/asio/read_at.hpp>
#include <boost/asio/read_until.hpp> #include <boost/asio/read_until.hpp>
#include <boost/asio/seq_packet_socket_service.hpp> #include <boost/asio/redirect_error.hpp>
#include <boost/asio/serial_port.hpp> #include <boost/asio/serial_port.hpp>
#include <boost/asio/serial_port_base.hpp> #include <boost/asio/serial_port_base.hpp>
#include <boost/asio/serial_port_service.hpp>
#include <boost/asio/signal_set.hpp> #include <boost/asio/signal_set.hpp>
#include <boost/asio/signal_set_service.hpp>
#include <boost/asio/socket_acceptor_service.hpp>
#include <boost/asio/socket_base.hpp> #include <boost/asio/socket_base.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/strand.hpp> #include <boost/asio/strand.hpp>
#include <boost/asio/stream_socket_service.hpp>
#include <boost/asio/streambuf.hpp> #include <boost/asio/streambuf.hpp>
#include <boost/asio/system_context.hpp>
#include <boost/asio/system_executor.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/asio/this_coro.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/time_traits.hpp> #include <boost/asio/time_traits.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/use_future.hpp>
#include <boost/asio/uses_executor.hpp>
#include <boost/asio/version.hpp> #include <boost/asio/version.hpp>
#include <boost/asio/wait_traits.hpp> #include <boost/asio/wait_traits.hpp>
#include <boost/asio/waitable_timer_service.hpp>
#include <boost/asio/windows/basic_handle.hpp>
#include <boost/asio/windows/basic_object_handle.hpp> #include <boost/asio/windows/basic_object_handle.hpp>
#include <boost/asio/windows/basic_overlapped_handle.hpp>
#include <boost/asio/windows/basic_random_access_handle.hpp> #include <boost/asio/windows/basic_random_access_handle.hpp>
#include <boost/asio/windows/basic_stream_handle.hpp> #include <boost/asio/windows/basic_stream_handle.hpp>
#include <boost/asio/windows/object_handle.hpp> #include <boost/asio/windows/object_handle.hpp>
#include <boost/asio/windows/object_handle_service.hpp> #include <boost/asio/windows/overlapped_handle.hpp>
#include <boost/asio/windows/overlapped_ptr.hpp> #include <boost/asio/windows/overlapped_ptr.hpp>
#include <boost/asio/windows/random_access_handle.hpp> #include <boost/asio/windows/random_access_handle.hpp>
#include <boost/asio/windows/random_access_handle_service.hpp>
#include <boost/asio/windows/stream_handle.hpp> #include <boost/asio/windows/stream_handle.hpp>
#include <boost/asio/windows/stream_handle_service.hpp>
#include <boost/asio/write.hpp> #include <boost/asio/write.hpp>
#include <boost/asio/write_at.hpp> #include <boost/asio/write_at.hpp>

View File

@@ -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 <boost/asio/detail/config.hpp>
#include <memory>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
template <typename>
struct associated_allocator_check
{
typedef void type;
};
template <typename T, typename E, typename = void>
struct associated_allocator_impl
{
typedef E type;
static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
{
return e;
}
};
template <typename T, typename E>
struct associated_allocator_impl<T, E,
typename associated_allocator_check<typename T::allocator_type>::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 <typename T, typename Allocator = std::allocator<void> >
struct associated_allocator
{
/// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
/// Otherwise @c Allocator.
#if defined(GENERATING_DOCUMENTATION)
typedef see_below type;
#else // defined(GENERATING_DOCUMENTATION)
typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
#endif // defined(GENERATING_DOCUMENTATION)
/// If @c T has a nested type @c allocator_type, returns
/// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
static type get(const T& t,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return detail::associated_allocator_impl<T, Allocator>::get(t, a);
}
};
/// Helper function to obtain an object's associated allocator.
/**
* @returns <tt>associated_allocator<T>::get(t)</tt>
*/
template <typename T>
inline typename associated_allocator<T>::type
get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T>::get(t);
}
/// Helper function to obtain an object's associated allocator.
/**
* @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
*/
template <typename T, typename Allocator>
inline typename associated_allocator<T, Allocator>::type
get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T, Allocator>::get(t, a);
}
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
template <typename T, typename Allocator = std::allocator<void> >
using associated_allocator_t
= typename associated_allocator<T, Allocator>::type;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP

View File

@@ -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 <boost/asio/detail/config.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/is_executor.hpp>
#include <boost/asio/system_executor.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
template <typename>
struct associated_executor_check
{
typedef void type;
};
template <typename T, typename E, typename = void>
struct associated_executor_impl
{
typedef E type;
static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
{
return e;
}
};
template <typename T, typename E>
struct associated_executor_impl<T, E,
typename associated_executor_check<typename T::executor_type>::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 <typename T, typename Executor = system_executor>
struct associated_executor
{
/// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
/// Otherwise @c Executor.
#if defined(GENERATING_DOCUMENTATION)
typedef see_below type;
#else // defined(GENERATING_DOCUMENTATION)
typedef typename detail::associated_executor_impl<T, Executor>::type type;
#endif // defined(GENERATING_DOCUMENTATION)
/// If @c T has a nested type @c executor_type, returns
/// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
static type get(const T& t,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return detail::associated_executor_impl<T, Executor>::get(t, ex);
}
};
/// Helper function to obtain an object's associated executor.
/**
* @returns <tt>associated_executor<T>::get(t)</tt>
*/
template <typename T>
inline typename associated_executor<T>::type
get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_executor<T>::get(t);
}
/// Helper function to obtain an object's associated executor.
/**
* @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
*/
template <typename T, typename Executor>
inline typename associated_executor<T, Executor>::type
get_associated_executor(const T& t, const Executor& ex,
typename enable_if<is_executor<
Executor>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
{
return associated_executor<T, Executor>::get(t, ex);
}
/// Helper function to obtain an object's associated executor.
/**
* @returns <tt>associated_executor<T, typename
* ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
*/
template <typename T, typename ExecutionContext>
inline typename associated_executor<T,
typename ExecutionContext::executor_type>::type
get_associated_executor(const T& t, ExecutionContext& ctx,
typename enable_if<is_convertible<ExecutionContext&,
execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
{
return associated_executor<T,
typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
}
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
template <typename T, typename Executor = system_executor>
using associated_executor_t = typename associated_executor<T, Executor>::type;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP

View File

@@ -2,7 +2,7 @@
// async_result.hpp // 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 // 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 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) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <boost/asio/handler_type.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/variadic_templates.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@@ -25,72 +26,333 @@ namespace asio {
/// An interface for customising the behaviour of an initiating function. /// 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 <typename Handler> template <typename CompletionToken, typename Signature>
class async_result class async_result
{ {
public: public:
/// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type;
/// The return type of the initiating function. /// The return type of the initiating function.
typedef void type; typedef void return_type;
/// Construct an async result from a given handler. /// Construct an async result from a given handler.
/** /**
* When using a specalised async_result, the constructor has an opportunity * When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the handler, which is then * to initialise some state associated with the completion handler, which is
* returned from the initiating function. * 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. /// 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 <typename Initiation, typename RawCompletionToken, typename... Args>
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 <typename Initiation, typename RawCompletionToken>
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 <typename Initiation, typename RawCompletionToken, \
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
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 <typename CompletionToken, typename Signature>
struct async_completion
{
/// The real handler type to be used for the asynchronous operation.
typedef typename boost::asio::async_result<
typename decay<CompletionToken>::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<typename conditional<
is_same<CompletionToken, completion_handler_type>::value,
completion_handler_type&, CompletionToken&&>::type>(token)),
result(completion_handler)
{
}
#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
explicit async_completion(typename decay<CompletionToken>::type& token)
: completion_handler(token),
result(completion_handler)
{
}
explicit async_completion(const typename decay<CompletionToken>::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<CompletionToken, completion_handler_type>::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<typename decay<CompletionToken>::type, Signature> result;
}; };
namespace detail { namespace detail {
// Helper template to deduce the true type of a handler, capture a local copy template <typename CompletionToken, typename Signature>
// of the handler, and then create an async_result for the handler. struct async_result_helper
template <typename Handler, typename Signature> : async_result<typename decay<CompletionToken>::type, Signature>
struct async_result_init
{ {
explicit async_result_init(BOOST_ASIO_MOVE_ARG(Handler) orig_handler)
: handler(BOOST_ASIO_MOVE_CAST(Handler)(orig_handler)),
result(handler)
{
}
typename handler_type<Handler, Signature>::type handler;
async_result<typename handler_type<Handler, Signature>::type> result;
}; };
template <typename Handler, typename Signature> struct async_result_memfns_base
struct async_result_type_helper {
void initiate();
};
template <typename T>
struct async_result_memfns_derived
: T, async_result_memfns_base
{
};
template <typename T, T>
struct async_result_memfns_check
{
};
template <typename>
char (&async_result_initiate_memfn_helper(...))[2];
template <typename T>
char async_result_initiate_memfn_helper(
async_result_memfns_check<
void (async_result_memfns_base::*)(),
&async_result_memfns_derived<T>::initiate>*);
template <typename CompletionToken, typename Signature>
struct async_result_has_initiate_memfn
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
async_result<typename decay<CompletionToken>::type, Signature>
>(0)) != 1>
{ {
typedef typename async_result<
typename handler_type<Handler, Signature>::type
>::type type;
}; };
} // namespace detail } // 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<ct>::type, sig>::return_type
#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
typename ::boost::asio::async_result< \
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif
#if defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
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 <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
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_MOVE_ARG(Args)... args)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
BOOST_ASIO_MOVE_CAST(CompletionToken)(token),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
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_MOVE_ARG(Args)... args)
{
async_completion<CompletionToken, Signature> 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 <typename CompletionToken, typename Signature, typename Initiation>
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)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
}
template <typename CompletionToken, typename Signature, typename Initiation>
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)
{
async_completion<CompletionToken, Signature> 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 <typename CompletionToken, typename Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
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<typename decay<CompletionToken>::type, \
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
template <typename CompletionToken, typename Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
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<CompletionToken, Signature> 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 asio
} // namespace boost } // namespace boost
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#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<h, sig>::type
#else
# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \
typename ::boost::asio::async_result< \
typename ::boost::asio::handler_type<h, sig>::type>::type
#endif
#endif // BOOST_ASIO_ASYNC_RESULT_HPP #endif // BOOST_ASIO_ASYNC_RESULT_HPP

View File

@@ -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 <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#include <experimental/coroutine>
#include <boost/asio/executor.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
using std::experimental::coroutine_handle;
using std::experimental::suspend_always;
template <typename> class awaitable_thread;
template <typename, typename> class awaitable_frame;
} // namespace detail
/// The return type of a coroutine or asynchronous operation.
template <typename T, typename Executor = executor>
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 <class U>
void await_suspend(
detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
{
frame_->push_frame(&h.promise());
}
// Support for co_await keyword.
T await_resume()
{
return frame_->get();
}
#endif // !defined(GENERATING_DOCUMENTATION)
private:
template <typename> friend class detail::awaitable_thread;
template <typename, typename> 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<T, Executor>* a)
: frame_(a)
{
}
detail::awaitable_frame<T, Executor>* frame_;
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/impl/awaitable.hpp>
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#endif // BOOST_ASIO_AWAITABLE_HPP

View File

@@ -2,7 +2,7 @@
// basic_datagram_socket.hpp // 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 // 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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -18,8 +18,8 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_socket.hpp> #include <boost/asio/basic_socket.hpp>
#include <boost/asio/datagram_socket_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
@@ -29,6 +29,15 @@
namespace boost { namespace boost {
namespace asio { 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 <typename Protocol, typename Executor = executor>
class basic_datagram_socket;
#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
/// Provides datagram-oriented socket functionality. /// Provides datagram-oriented socket functionality.
/** /**
* The basic_datagram_socket class template provides asynchronous and blocking * The basic_datagram_socket class template provides asynchronous and blocking
@@ -38,18 +47,29 @@ namespace asio {
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. * @e Shared @e objects: Unsafe.
*/ */
template <typename Protocol, template <typename Protocol, typename Executor>
typename DatagramSocketService = datagram_socket_service<Protocol> >
class basic_datagram_socket class basic_datagram_socket
: public basic_socket<Protocol, DatagramSocketService> : public basic_socket<Protocol, Executor>
{ {
public: public:
/// (Deprecated: Use native_handle_type.) The native representation of a /// The type of the executor associated with the object.
/// socket. typedef Executor executor_type;
typedef typename DatagramSocketService::native_handle_type native_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_datagram_socket<Protocol, Executor1> other;
};
/// The native representation of a socket. /// 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<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type. /// The protocol type.
typedef Protocol protocol_type; typedef Protocol protocol_type;
@@ -62,12 +82,29 @@ public:
* This constructor creates a datagram socket without opening it. The open() * 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. * 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 * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
*/ */
explicit basic_datagram_socket(boost::asio::io_service& io_service) explicit basic_datagram_socket(const executor_type& ex)
: basic_socket<Protocol, DatagramSocketService>(io_service) : basic_socket<Protocol, Executor>(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 <typename ExecutionContext>
explicit basic_datagram_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{ {
} }
@@ -75,17 +112,37 @@ public:
/** /**
* This constructor creates and opens a datagram socket. * This constructor creates and opens a datagram socket.
* *
* @param io_service The io_service object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
* @throws boost::system::system_error Thrown on failure. * @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 protocol_type& protocol) : basic_socket<Protocol, Executor>(ex, protocol)
: basic_socket<Protocol, DatagramSocketService>(io_service, 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 <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{ {
} }
@@ -96,18 +153,42 @@ public:
* to the specified endpoint on the local machine. The protocol used is the * to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint. * protocol associated with the given endpoint.
* *
* @param io_service The io_service object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param endpoint An endpoint on the local machine to which the datagram * @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound. * socket will be bound.
* *
* @throws boost::system::system_error Thrown on failure. * @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 endpoint_type& endpoint)
const endpoint_type& endpoint) : basic_socket<Protocol, Executor>(ex, endpoint)
: basic_socket<Protocol, DatagramSocketService>(io_service, 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 <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{ {
} }
@@ -116,9 +197,8 @@ public:
* This constructor creates a datagram socket object to hold an existing * This constructor creates a datagram socket object to hold an existing
* native socket. * native socket.
* *
* @param io_service The io_service object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
@@ -126,10 +206,34 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @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) const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol, DatagramSocketService>( : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
io_service, 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 <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{ {
} }
@@ -142,11 +246,11 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @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_datagram_socket(basic_datagram_socket&& other)
: basic_socket<Protocol, DatagramSocketService>( : basic_socket<Protocol, Executor>(std::move(other))
BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other))
{ {
} }
@@ -159,12 +263,12 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @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_datagram_socket& operator=(basic_datagram_socket&& other)
{ {
basic_socket<Protocol, DatagramSocketService>::operator=( basic_socket<Protocol, Executor>::operator=(std::move(other));
BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other));
return *this; return *this;
} }
@@ -177,15 +281,16 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @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 Protocol1, typename DatagramSocketService1> template <typename Protocol1, typename Executor1>
basic_datagram_socket( basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
basic_datagram_socket<Protocol1, DatagramSocketService1>&& other, typename enable_if<
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) is_convertible<Protocol1, Protocol>::value
: basic_socket<Protocol, DatagramSocketService>( && is_convertible<Executor1, Executor>::value
BOOST_ASIO_MOVE_CAST2(basic_datagram_socket< >::type* = 0)
Protocol1, DatagramSocketService1>)(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@@ -199,20 +304,30 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @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 Protocol1, typename DatagramSocketService1> template <typename Protocol1, typename Executor1>
typename enable_if<is_convertible<Protocol1, Protocol>::value, typename enable_if<
basic_datagram_socket>::type& operator=( is_convertible<Protocol1, Protocol>::value
basic_datagram_socket<Protocol1, DatagramSocketService1>&& other) && is_convertible<Executor1, Executor>::value,
basic_datagram_socket&
>::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
{ {
basic_socket<Protocol, DatagramSocketService>::operator=( basic_socket<Protocol, Executor>::operator=(std::move(other));
BOOST_ASIO_MOVE_CAST2(basic_datagram_socket<
Protocol1, DatagramSocketService1>)(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #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. /// Send some data on a connected socket.
/** /**
* This function is used to send data on the datagram socket. The function * 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) std::size_t send(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@@ -267,8 +382,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@@ -294,8 +409,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers, std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().send( return this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@@ -316,9 +431,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @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 * Use the async_send_to function to send data on an unconnected datagram
@@ -339,12 +454,10 @@ public:
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@@ -367,9 +480,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @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 * Use the async_send_to function to send data on an unconnected datagram
@@ -382,12 +495,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this, buffers, flags);
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
/// Send a datagram to the specified endpoint. /// Send a datagram to the specified endpoint.
@@ -420,8 +530,8 @@ public:
const endpoint_type& destination) const endpoint_type& destination)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, 0, ec); this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@@ -447,8 +557,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags) const endpoint_type& destination, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, flags, ec); this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@@ -474,7 +584,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
boost::system::error_code& ec) 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); buffers, destination, flags, ec);
} }
@@ -499,9 +609,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To send a single data buffer use the @ref buffer function as follows: * To send a single data buffer use the @ref buffer function as follows:
@@ -522,13 +632,10 @@ public:
const endpoint_type& destination, const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@@ -554,9 +661,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -565,13 +672,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers, destination, flags);
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
/// Receive some data on a connected socket. /// Receive some data on a connected socket.
@@ -602,8 +705,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers) std::size_t receive(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@@ -631,8 +734,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@@ -659,8 +762,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers, std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().receive( return this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@@ -681,9 +784,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @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 * Use the async_receive_from function to receive data on an unconnected
@@ -705,12 +808,10 @@ public:
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@@ -733,9 +834,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @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 * Use the async_receive_from function to receive data on an unconnected
@@ -748,12 +849,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this, buffers, flags);
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
/// Receive a datagram with the endpoint of the sender. /// Receive a datagram with the endpoint of the sender.
@@ -787,8 +885,8 @@ public:
endpoint_type& sender_endpoint) endpoint_type& sender_endpoint)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, 0, ec); this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@@ -814,8 +912,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags) endpoint_type& sender_endpoint, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@@ -841,8 +939,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().receive_from(this->get_implementation(), return this->impl_.get_service().receive_from(
buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@@ -868,9 +966,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To receive into a single data buffer use the @ref buffer function as * To receive into a single data buffer use the @ref buffer function as
@@ -888,13 +986,10 @@ public:
endpoint_type& sender_endpoint, endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@@ -922,9 +1017,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -933,16 +1028,87 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
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<WriteHandler> 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 <typename WriteHandler, typename ConstBufferSequence>
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<WriteHandler> 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 <typename ReadHandler, typename MutableBufferSequence>
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; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
return this->get_service().async_receive_from( detail::non_const_lvalue<ReadHandler> handler2(handler);
this->get_implementation(), buffers, sender_endpoint, flags, self->impl_.get_service().async_receive(
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
} }
}; };
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
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<ReadHandler> 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 } // namespace asio
} // namespace boost } // namespace boost

View File

@@ -2,7 +2,7 @@
// basic_deadline_timer.hpp // 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 // 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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -21,11 +21,15 @@
|| defined(GENERATING_DOCUMENTATION) || defined(GENERATING_DOCUMENTATION)
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@@ -51,7 +55,7 @@ namespace asio {
* Performing a blocking wait: * Performing a blocking wait:
* @code * @code
* // Construct a timer without setting an expiry time. * // 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. * // Set an expiry time relative to now.
* timer.expires_from_now(boost::posix_time::seconds(5)); * timer.expires_from_now(boost::posix_time::seconds(5));
@@ -74,7 +78,7 @@ namespace asio {
* ... * ...
* *
* // Construct a timer with an absolute expiry time. * // 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")); * boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
* *
* // Start an asynchronous wait. * // Start an asynchronous wait.
@@ -122,11 +126,13 @@ namespace asio {
*/ */
template <typename Time, template <typename Time,
typename TimeTraits = boost::asio::time_traits<Time>, typename TimeTraits = boost::asio::time_traits<Time>,
typename TimerService = deadline_timer_service<Time, TimeTraits> > typename Executor = executor>
class basic_deadline_timer class basic_deadline_timer
: public basic_io_object<TimerService>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// The time traits type. /// The time traits type.
typedef TimeTraits traits_type; typedef TimeTraits traits_type;
@@ -142,11 +148,30 @@ public:
* expires_at() or expires_from_now() functions must be called to set an * expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on. * expiry time before the timer can be waited on.
* *
* @param io_service The io_service object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
*/ */
explicit basic_deadline_timer(boost::asio::io_service& io_service) explicit basic_deadline_timer(const executor_type& ex)
: basic_io_object<TimerService>(io_service) : 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 <typename ExecutionContext>
explicit basic_deadline_timer(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{ {
} }
@@ -154,18 +179,40 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_service The io_service object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, expressed * @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time. * as an absolute time.
*/ */
basic_deadline_timer(boost::asio::io_service& io_service, basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
const time_type& expiry_time) : impl_(ex)
: basic_io_object<TimerService>(io_service)
{ {
boost::system::error_code ec; 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 <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::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"); boost::asio::detail::throw_error(ec, "expires_at");
} }
@@ -173,21 +220,98 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_service The io_service object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, relative to * @param expiry_time The expiry time to be used for the timer, relative to
* now. * now.
*/ */
basic_deadline_timer(boost::asio::io_service& io_service, basic_deadline_timer(const executor_type& ex,
const duration_type& expiry_time) const duration_type& expiry_time)
: basic_io_object<TimerService>(io_service) : impl_(ex)
{ {
boost::system::error_code ec; 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"); 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 <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context,
const duration_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::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. /// Cancel any asynchronous operations that are waiting on the timer.
/** /**
* This function forces the completion of any pending asynchronous wait * This function forces the completion of any pending asynchronous wait
@@ -213,7 +337,7 @@ public:
std::size_t cancel() std::size_t cancel()
{ {
boost::system::error_code ec; 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"); boost::asio::detail::throw_error(ec, "cancel");
return s; return s;
} }
@@ -242,7 +366,7 @@ public:
*/ */
std::size_t cancel(boost::system::error_code& ec) 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. /// Cancels one asynchronous operation that is waiting on the timer.
@@ -272,7 +396,8 @@ public:
std::size_t cancel_one() std::size_t cancel_one()
{ {
boost::system::error_code ec; 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"); boost::asio::detail::throw_error(ec, "cancel_one");
return s; return s;
} }
@@ -303,7 +428,7 @@ public:
*/ */
std::size_t cancel_one(boost::system::error_code& ec) 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. /// Get the timer's expiry time as an absolute time.
@@ -313,7 +438,7 @@ public:
*/ */
time_type expires_at() const 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. /// 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) std::size_t expires_at(const time_type& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->service.expires_at( std::size_t s = impl_.get_service().expires_at(
this->implementation, expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at"); boost::asio::detail::throw_error(ec, "expires_at");
return s; return s;
} }
@@ -372,7 +497,8 @@ public:
std::size_t expires_at(const time_type& expiry_time, std::size_t expires_at(const time_type& expiry_time,
boost::system::error_code& ec) 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. /// Get the timer's expiry time relative to now.
@@ -382,7 +508,7 @@ public:
*/ */
duration_type expires_from_now() const 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. /// 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) std::size_t expires_from_now(const duration_type& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->service.expires_from_now( std::size_t s = impl_.get_service().expires_from_now(
this->implementation, expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now"); boost::asio::detail::throw_error(ec, "expires_from_now");
return s; return s;
} }
@@ -441,8 +567,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time, std::size_t expires_from_now(const duration_type& expiry_time,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->service.expires_from_now( return impl_.get_service().expires_from_now(
this->implementation, expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
} }
/// Perform a blocking wait on the timer. /// Perform a blocking wait on the timer.
@@ -455,7 +581,7 @@ public:
void wait() void wait()
{ {
boost::system::error_code ec; 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"); boost::asio::detail::throw_error(ec, "wait");
} }
@@ -468,7 +594,7 @@ public:
*/ */
void wait(boost::system::error_code& ec) 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. /// Start an asynchronous wait on the timer.
@@ -491,24 +617,46 @@ public:
* const boost::system::error_code& error // Result of operation. * const boost::system::error_code& error // Result of operation.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_service::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WaitHandler, void (boost::system::error_code)>(
// not meet the documented type requirements for a WaitHandler. 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 <typename WaitHandler>
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; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
return this->service.async_wait(this->implementation, detail::non_const_lvalue<WaitHandler> handler2(handler);
BOOST_ASIO_MOVE_CAST(WaitHandler)(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<TimeTraits>, Executor> impl_;
};
} // namespace asio } // namespace asio
} // namespace boost } // namespace boost

View File

@@ -2,7 +2,7 @@
// basic_io_object.hpp // 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 // 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 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) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <boost/asio/io_service.hpp> #include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@@ -68,17 +68,43 @@ public:
/// The underlying implementation type of I/O object. /// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type; 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. * 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. * 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: protected:
@@ -87,10 +113,10 @@ protected:
* Performs: * Performs:
* @code get_service().construct(get_implementation()); @endcode * @code get_service().construct(get_implementation()); @endcode
*/ */
explicit basic_io_object(boost::asio::io_service& io_service) explicit basic_io_object(boost::asio::io_context& io_context)
: service(boost::asio::use_service<IoObjectService>(io_service)) : service_(boost::asio::use_service<IoObjectService>(io_context))
{ {
service.construct(implementation); service_.construct(implementation_);
} }
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
@@ -127,47 +153,42 @@ protected:
*/ */
~basic_io_object() ~basic_io_object()
{ {
service.destroy(implementation); service_.destroy(implementation_);
} }
/// Get the service associated with the I/O object. /// Get the service associated with the I/O object.
service_type& get_service() service_type& get_service()
{ {
return service; return service_;
} }
/// Get the service associated with the I/O object. /// Get the service associated with the I/O object.
const service_type& get_service() const 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. /// Get the underlying implementation of the I/O object.
implementation_type& get_implementation() implementation_type& get_implementation()
{ {
return implementation; return implementation_;
} }
/// Get the underlying implementation of the I/O object. /// Get the underlying implementation of the I/O object.
const implementation_type& get_implementation() const 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: private:
basic_io_object(const basic_io_object&); basic_io_object(const basic_io_object&);
basic_io_object& operator=(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) #if defined(BOOST_ASIO_HAS_MOVE)
@@ -179,43 +200,57 @@ public:
typedef IoObjectService service_type; typedef IoObjectService service_type;
typedef typename service_type::implementation_type implementation_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: protected:
explicit basic_io_object(boost::asio::io_service& io_service) explicit basic_io_object(boost::asio::io_context& io_context)
: service_(&boost::asio::use_service<IoObjectService>(io_service)) : service_(&boost::asio::use_service<IoObjectService>(io_context))
{ {
service_->construct(implementation); service_->construct(implementation_);
} }
basic_io_object(basic_io_object&& other) basic_io_object(basic_io_object&& other)
: service_(&other.get_service()) : service_(&other.get_service())
{ {
service_->move_construct(implementation, other.implementation); service_->move_construct(implementation_, other.implementation_);
} }
template <typename IoObjectService1> template <typename IoObjectService1>
basic_io_object(IoObjectService1& other_service, basic_io_object(IoObjectService1& other_service,
typename IoObjectService1::implementation_type& other_implementation) typename IoObjectService1::implementation_type& other_implementation)
: service_(&boost::asio::use_service<IoObjectService>( : service_(&boost::asio::use_service<IoObjectService>(
other_service.get_io_service())) other_service.get_io_context()))
{ {
service_->converting_move_construct(implementation, service_->converting_move_construct(implementation_,
other_service, other_implementation); other_service, other_implementation);
} }
~basic_io_object() ~basic_io_object()
{ {
service_->destroy(implementation); service_->destroy(implementation_);
} }
basic_io_object& operator=(basic_io_object&& other) basic_io_object& operator=(basic_io_object&& other)
{ {
service_->move_assign(implementation, service_->move_assign(implementation_,
*other.service_, other.implementation); *other.service_, other.implementation_);
service_ = other.service_; service_ = other.service_;
return *this; return *this;
} }
@@ -232,21 +267,20 @@ protected:
implementation_type& get_implementation() implementation_type& get_implementation()
{ {
return implementation; return implementation_;
} }
const implementation_type& get_implementation() const const implementation_type& get_implementation() const
{ {
return implementation; return implementation_;
} }
implementation_type implementation;
private: private:
basic_io_object(const basic_io_object&); basic_io_object(const basic_io_object&);
void operator=(const basic_io_object&); void operator=(const basic_io_object&);
IoObjectService* service_; IoObjectService* service_;
implementation_type implementation_;
}; };
#endif // defined(BOOST_ASIO_HAS_MOVE) #endif // defined(BOOST_ASIO_HAS_MOVE)

Some files were not shown because too many files have changed in this diff Show More