forked from organicmaps/organicmaps
Updated boost to 1.51
This commit is contained in:
parent
16e18a8af9
commit
7c5036ce53
3398 changed files with 196494 additions and 68206 deletions
|
@ -115,6 +115,12 @@ namespace boost { namespace accumulators
|
|||
{
|
||||
}
|
||||
|
||||
droppable_accumulator_base(droppable_accumulator_base const &that)
|
||||
: Accumulator(*static_cast<Accumulator const *>(&that))
|
||||
, ref_count_(that.ref_count_)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
void operator ()(Args const &args)
|
||||
{
|
||||
|
@ -162,6 +168,11 @@ namespace boost { namespace accumulators
|
|||
: droppable_accumulator::base(args)
|
||||
{
|
||||
}
|
||||
|
||||
droppable_accumulator(droppable_accumulator const &that)
|
||||
: droppable_accumulator::base(*static_cast<typename droppable_accumulator::base const *>(&that))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
@ -277,6 +278,8 @@ namespace boost { namespace numeric
|
|||
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);
|
||||
|
||||
typename remove_const<Arg>::type operator ()(Arg &) const
|
||||
{
|
||||
return (std::numeric_limits<typename remove_const<Arg>::type>::min)();
|
||||
|
@ -287,6 +290,8 @@ namespace boost { namespace numeric
|
|||
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);
|
||||
|
||||
typename remove_const<Arg>::type operator ()(Arg &) const
|
||||
{
|
||||
return -(std::numeric_limits<typename remove_const<Arg>::type>::max)();
|
||||
|
@ -297,6 +302,8 @@ namespace boost { namespace numeric
|
|||
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);
|
||||
|
||||
typename remove_const<Arg>::type operator ()(Arg &) const
|
||||
{
|
||||
return (std::numeric_limits<typename remove_const<Arg>::type>::max)();
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <boost/accumulators/statistics/peaks_over_threshold.hpp>
|
||||
#include <boost/accumulators/statistics/pot_tail_mean.hpp>
|
||||
#include <boost/accumulators/statistics/pot_quantile.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumulative_distribution.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_quantile.hpp>
|
||||
#include <boost/accumulators/statistics/skewness.hpp>
|
||||
#include <boost/accumulators/statistics/stats.hpp>
|
||||
|
@ -45,7 +45,7 @@
|
|||
#include <boost/accumulators/statistics/weighted_median.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_moment.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_peaks_over_threshold.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_cumulative_distribution.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_quantile.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_skewness.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_sum.hpp>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <boost/accumulators/statistics/count.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_quantile.hpp>
|
||||
#include <boost/accumulators/statistics/density.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumulative_distribution.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// p_square_cumulative_distribution.hpp
|
||||
//
|
||||
// Copyright 2005 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/accumulators/framework/accumulator_base.hpp>
|
||||
#include <boost/accumulators/framework/extractor.hpp>
|
||||
#include <boost/accumulators/numeric/functional.hpp>
|
||||
#include <boost/accumulators/framework/parameters/sample.hpp>
|
||||
#include <boost/accumulators/statistics_fwd.hpp>
|
||||
#include <boost/accumulators/statistics/count.hpp>
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// num_cells named parameter
|
||||
//
|
||||
BOOST_PARAMETER_NESTED_KEYWORD(tag, p_square_cumulative_distribution_num_cells, num_cells)
|
||||
|
||||
namespace impl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// p_square_cumulative_distribution_impl
|
||||
// cumulative_distribution calculation (as histogram)
|
||||
/**
|
||||
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm
|
||||
|
||||
A histogram of the sample cumulative distribution is computed dynamically without storing samples
|
||||
based on the \f$ P^2 \f$ algorithm. The returned histogram has a specifiable amount (num_cells)
|
||||
equiprobable (and not equal-sized) cells.
|
||||
|
||||
For further details, see
|
||||
|
||||
R. Jain and I. Chlamtac, The P^2 algorithmus for dynamic calculation of quantiles and
|
||||
histograms without storing observations, Communications of the ACM,
|
||||
Volume 28 (October), Number 10, 1985, p. 1076-1085.
|
||||
|
||||
@param p_square_cumulative_distribution_num_cells.
|
||||
*/
|
||||
template<typename Sample>
|
||||
struct p_square_cumulative_distribution_impl
|
||||
: accumulator_base
|
||||
{
|
||||
typedef typename numeric::functional::average<Sample, std::size_t>::result_type float_type;
|
||||
typedef std::vector<float_type> array_type;
|
||||
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
|
||||
// for boost::result_of
|
||||
typedef iterator_range<typename histogram_type::iterator> result_type;
|
||||
|
||||
template<typename Args>
|
||||
p_square_cumulative_distribution_impl(Args const &args)
|
||||
: num_cells(args[p_square_cumulative_distribution_num_cells])
|
||||
, heights(num_cells + 1)
|
||||
, actual_positions(num_cells + 1)
|
||||
, desired_positions(num_cells + 1)
|
||||
, positions_increments(num_cells + 1)
|
||||
, histogram(num_cells + 1)
|
||||
, is_dirty(true)
|
||||
{
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
for (std::size_t i = 0; i < b + 1; ++i)
|
||||
{
|
||||
this->actual_positions[i] = i + 1.;
|
||||
this->desired_positions[i] = i + 1.;
|
||||
this->positions_increments[i] = numeric::average(i, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
void operator ()(Args const &args)
|
||||
{
|
||||
this->is_dirty = true;
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
std::size_t sample_cell = 1; // k
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
// accumulate num_cells + 1 first samples
|
||||
if (cnt <= b + 1)
|
||||
{
|
||||
this->heights[cnt - 1] = args[sample];
|
||||
|
||||
// complete the initialization of heights by sorting
|
||||
if (cnt == b + 1)
|
||||
{
|
||||
std::sort(this->heights.begin(), this->heights.end());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
|
||||
if (args[sample] < this->heights[0])
|
||||
{
|
||||
this->heights[0] = args[sample];
|
||||
sample_cell = 1;
|
||||
}
|
||||
else if (this->heights[b] <= args[sample])
|
||||
{
|
||||
this->heights[b] = args[sample];
|
||||
sample_cell = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename array_type::iterator it;
|
||||
it = std::upper_bound(
|
||||
this->heights.begin()
|
||||
, this->heights.end()
|
||||
, args[sample]
|
||||
);
|
||||
|
||||
sample_cell = std::distance(this->heights.begin(), it);
|
||||
}
|
||||
|
||||
// increment positions of markers above sample_cell
|
||||
for (std::size_t i = sample_cell; i < b + 1; ++i)
|
||||
{
|
||||
++this->actual_positions[i];
|
||||
}
|
||||
|
||||
// update desired position of markers 2 to num_cells + 1
|
||||
// (desired position of first marker is always 1)
|
||||
for (std::size_t i = 1; i < b + 1; ++i)
|
||||
{
|
||||
this->desired_positions[i] += this->positions_increments[i];
|
||||
}
|
||||
|
||||
// adjust heights of markers 2 to num_cells if necessary
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
// offset to desire position
|
||||
float_type d = this->desired_positions[i] - this->actual_positions[i];
|
||||
|
||||
// offset to next position
|
||||
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
|
||||
|
||||
// offset to previous position
|
||||
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
|
||||
|
||||
// height ds
|
||||
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
|
||||
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
|
||||
|
||||
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
|
||||
{
|
||||
short sign_d = static_cast<short>(d / std::abs(d));
|
||||
|
||||
// try adjusting heights[i] using p-squared formula
|
||||
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
|
||||
|
||||
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
|
||||
{
|
||||
this->heights[i] = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use linear formula
|
||||
if (d>0)
|
||||
{
|
||||
this->heights[i] += hp;
|
||||
}
|
||||
if (d<0)
|
||||
{
|
||||
this->heights[i] -= hm;
|
||||
}
|
||||
}
|
||||
this->actual_positions[i] += sign_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
result_type result(Args const &args) const
|
||||
{
|
||||
if (this->is_dirty)
|
||||
{
|
||||
this->is_dirty = false;
|
||||
|
||||
// creates a vector of std::pair where each pair i holds
|
||||
// the values heights[i] (x-axis of histogram) and
|
||||
// actual_positions[i] / cnt (y-axis of histogram)
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
|
||||
for (std::size_t i = 0; i < this->histogram.size(); ++i)
|
||||
{
|
||||
this->histogram[i] = std::make_pair(this->heights[i], numeric::average(this->actual_positions[i], cnt));
|
||||
}
|
||||
}
|
||||
//return histogram;
|
||||
return make_iterator_range(this->histogram);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t num_cells; // number of cells b
|
||||
array_type heights; // q_i
|
||||
array_type actual_positions; // n_i
|
||||
array_type desired_positions; // n'_i
|
||||
array_type positions_increments; // dn'_i
|
||||
mutable histogram_type histogram; // histogram
|
||||
mutable bool is_dirty;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// tag::p_square_cumulative_distribution
|
||||
//
|
||||
namespace tag
|
||||
{
|
||||
struct p_square_cumulative_distribution
|
||||
: depends_on<count>
|
||||
, p_square_cumulative_distribution_num_cells
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
typedef accumulators::impl::p_square_cumulative_distribution_impl<mpl::_1> impl;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// extract::p_square_cumulative_distribution
|
||||
//
|
||||
namespace extract
|
||||
{
|
||||
extractor<tag::p_square_cumulative_distribution> const p_square_cumulative_distribution = {};
|
||||
|
||||
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_cumulative_distribution)
|
||||
}
|
||||
|
||||
using extract::p_square_cumulative_distribution;
|
||||
|
||||
// So that p_square_cumulative_distribution can be automatically substituted with
|
||||
// weighted_p_square_cumulative_distribution when the weight parameter is non-void
|
||||
template<>
|
||||
struct as_weighted_feature<tag::p_square_cumulative_distribution>
|
||||
{
|
||||
typedef tag::weighted_p_square_cumulative_distribution type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct feature_of<tag::weighted_p_square_cumulative_distribution>
|
||||
: feature_of<tag::p_square_cumulative_distribution>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::accumulators
|
||||
|
||||
#endif
|
|
@ -1,260 +1,19 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// p_square_cumulative_distribution.hpp
|
||||
//
|
||||
// Copyright 2005 Daniel Egloff, Olivier Gygi. Distributed under the Boost
|
||||
// Copyright 2012 Eric Niebler. 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_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_DE_01_01_2006
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_DE_01_01_2006
|
||||
#ifndef BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/accumulators/framework/accumulator_base.hpp>
|
||||
#include <boost/accumulators/framework/extractor.hpp>
|
||||
#include <boost/accumulators/numeric/functional.hpp>
|
||||
#include <boost/accumulators/framework/parameters/sample.hpp>
|
||||
#include <boost/accumulators/statistics_fwd.hpp>
|
||||
#include <boost/accumulators/statistics/count.hpp>
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
|
||||
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp")
|
||||
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||
# warning "This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// num_cells named parameter
|
||||
//
|
||||
BOOST_PARAMETER_NESTED_KEYWORD(tag, p_square_cumulative_distribution_num_cells, num_cells)
|
||||
|
||||
namespace impl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// p_square_cumulative_distribution_impl
|
||||
// cumulative_distribution calculation (as histogram)
|
||||
/**
|
||||
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm
|
||||
|
||||
A histogram of the sample cumulative distribution is computed dynamically without storing samples
|
||||
based on the \f$ P^2 \f$ algorithm. The returned histogram has a specifiable amount (num_cells)
|
||||
equiprobable (and not equal-sized) cells.
|
||||
|
||||
For further details, see
|
||||
|
||||
R. Jain and I. Chlamtac, The P^2 algorithmus for dynamic calculation of quantiles and
|
||||
histograms without storing observations, Communications of the ACM,
|
||||
Volume 28 (October), Number 10, 1985, p. 1076-1085.
|
||||
|
||||
@param p_square_cumulative_distribution_num_cells.
|
||||
*/
|
||||
template<typename Sample>
|
||||
struct p_square_cumulative_distribution_impl
|
||||
: accumulator_base
|
||||
{
|
||||
typedef typename numeric::functional::average<Sample, std::size_t>::result_type float_type;
|
||||
typedef std::vector<float_type> array_type;
|
||||
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
|
||||
// for boost::result_of
|
||||
typedef iterator_range<typename histogram_type::iterator> result_type;
|
||||
|
||||
template<typename Args>
|
||||
p_square_cumulative_distribution_impl(Args const &args)
|
||||
: num_cells(args[p_square_cumulative_distribution_num_cells])
|
||||
, heights(num_cells + 1)
|
||||
, actual_positions(num_cells + 1)
|
||||
, desired_positions(num_cells + 1)
|
||||
, positions_increments(num_cells + 1)
|
||||
, histogram(num_cells + 1)
|
||||
, is_dirty(true)
|
||||
{
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
for (std::size_t i = 0; i < b + 1; ++i)
|
||||
{
|
||||
this->actual_positions[i] = i + 1.;
|
||||
this->desired_positions[i] = i + 1.;
|
||||
this->positions_increments[i] = numeric::average(i, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
void operator ()(Args const &args)
|
||||
{
|
||||
this->is_dirty = true;
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
std::size_t sample_cell = 1; // k
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
// accumulate num_cells + 1 first samples
|
||||
if (cnt <= b + 1)
|
||||
{
|
||||
this->heights[cnt - 1] = args[sample];
|
||||
|
||||
// complete the initialization of heights by sorting
|
||||
if (cnt == b + 1)
|
||||
{
|
||||
std::sort(this->heights.begin(), this->heights.end());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
|
||||
if (args[sample] < this->heights[0])
|
||||
{
|
||||
this->heights[0] = args[sample];
|
||||
sample_cell = 1;
|
||||
}
|
||||
else if (this->heights[b] <= args[sample])
|
||||
{
|
||||
this->heights[b] = args[sample];
|
||||
sample_cell = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename array_type::iterator it;
|
||||
it = std::upper_bound(
|
||||
this->heights.begin()
|
||||
, this->heights.end()
|
||||
, args[sample]
|
||||
);
|
||||
|
||||
sample_cell = std::distance(this->heights.begin(), it);
|
||||
}
|
||||
|
||||
// increment positions of markers above sample_cell
|
||||
for (std::size_t i = sample_cell; i < b + 1; ++i)
|
||||
{
|
||||
++this->actual_positions[i];
|
||||
}
|
||||
|
||||
// update desired position of markers 2 to num_cells + 1
|
||||
// (desired position of first marker is always 1)
|
||||
for (std::size_t i = 1; i < b + 1; ++i)
|
||||
{
|
||||
this->desired_positions[i] += this->positions_increments[i];
|
||||
}
|
||||
|
||||
// adjust heights of markers 2 to num_cells if necessary
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
// offset to desire position
|
||||
float_type d = this->desired_positions[i] - this->actual_positions[i];
|
||||
|
||||
// offset to next position
|
||||
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
|
||||
|
||||
// offset to previous position
|
||||
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
|
||||
|
||||
// height ds
|
||||
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
|
||||
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
|
||||
|
||||
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
|
||||
{
|
||||
short sign_d = static_cast<short>(d / std::abs(d));
|
||||
|
||||
// try adjusting heights[i] using p-squared formula
|
||||
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
|
||||
|
||||
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
|
||||
{
|
||||
this->heights[i] = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use linear formula
|
||||
if (d>0)
|
||||
{
|
||||
this->heights[i] += hp;
|
||||
}
|
||||
if (d<0)
|
||||
{
|
||||
this->heights[i] -= hm;
|
||||
}
|
||||
}
|
||||
this->actual_positions[i] += sign_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
result_type result(Args const &args) const
|
||||
{
|
||||
if (this->is_dirty)
|
||||
{
|
||||
this->is_dirty = false;
|
||||
|
||||
// creates a vector of std::pair where each pair i holds
|
||||
// the values heights[i] (x-axis of histogram) and
|
||||
// actual_positions[i] / cnt (y-axis of histogram)
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
|
||||
for (std::size_t i = 0; i < this->histogram.size(); ++i)
|
||||
{
|
||||
this->histogram[i] = std::make_pair(this->heights[i], numeric::average(this->actual_positions[i], cnt));
|
||||
}
|
||||
}
|
||||
//return histogram;
|
||||
return make_iterator_range(this->histogram);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t num_cells; // number of cells b
|
||||
array_type heights; // q_i
|
||||
array_type actual_positions; // n_i
|
||||
array_type desired_positions; // n'_i
|
||||
array_type positions_increments; // dn'_i
|
||||
mutable histogram_type histogram; // histogram
|
||||
mutable bool is_dirty;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// tag::p_square_cumulative_distribution
|
||||
//
|
||||
namespace tag
|
||||
{
|
||||
struct p_square_cumulative_distribution
|
||||
: depends_on<count>
|
||||
, p_square_cumulative_distribution_num_cells
|
||||
{
|
||||
/// INTERNAL ONLY
|
||||
///
|
||||
typedef accumulators::impl::p_square_cumulative_distribution_impl<mpl::_1> impl;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// extract::p_square_cumulative_distribution
|
||||
//
|
||||
namespace extract
|
||||
{
|
||||
extractor<tag::p_square_cumulative_distribution> const p_square_cumulative_distribution = {};
|
||||
|
||||
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_cumulative_distribution)
|
||||
}
|
||||
|
||||
using extract::p_square_cumulative_distribution;
|
||||
|
||||
// So that p_square_cumulative_distribution can be automatically substituted with
|
||||
// weighted_p_square_cumulative_distribution when the weight parameter is non-void
|
||||
template<>
|
||||
struct as_weighted_feature<tag::p_square_cumulative_distribution>
|
||||
{
|
||||
typedef tag::weighted_p_square_cumulative_distribution type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct feature_of<tag::weighted_p_square_cumulative_distribution>
|
||||
: feature_of<tag::p_square_cumulative_distribution>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::accumulators
|
||||
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,7 @@ struct sum_kahan_impl
|
|||
template<typename Args>
|
||||
void
|
||||
#if BOOST_ACCUMULATORS_GCC_VERSION > 40305
|
||||
__attribute__((optimize("no-associative-math")))
|
||||
__attribute__((__optimize__("no-associative-math")))
|
||||
#endif
|
||||
operator ()(Args const & args)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <boost/accumulators/statistics/median.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_quantile.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_density.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_cumulative_distribution.hpp>
|
||||
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// weighted_p_square_cumul_dist.hpp
|
||||
//
|
||||
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/accumulators/framework/accumulator_base.hpp>
|
||||
#include <boost/accumulators/framework/extractor.hpp>
|
||||
#include <boost/accumulators/numeric/functional.hpp>
|
||||
#include <boost/accumulators/framework/parameters/sample.hpp>
|
||||
#include <boost/accumulators/statistics_fwd.hpp>
|
||||
#include <boost/accumulators/statistics/count.hpp>
|
||||
#include <boost/accumulators/statistics/sum.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp> // for named parameter p_square_cumulative_distribution_num_cells
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
|
||||
namespace impl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// weighted_p_square_cumulative_distribution_impl
|
||||
// cumulative distribution calculation (as histogram)
|
||||
/**
|
||||
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm for weighted samples
|
||||
|
||||
A histogram of the sample cumulative distribution is computed dynamically without storing samples
|
||||
based on the \f$ P^2 \f$ algorithm for weighted samples. The returned histogram has a specifiable
|
||||
amount (num_cells) equiprobable (and not equal-sized) cells.
|
||||
|
||||
Note that applying importance sampling results in regions to be more and other regions to be less
|
||||
accurately estimated than without importance sampling, i.e., with unweighted samples.
|
||||
|
||||
For further details, see
|
||||
|
||||
R. Jain and I. Chlamtac, The P^2 algorithmus for dynamic calculation of quantiles and
|
||||
histograms without storing observations, Communications of the ACM,
|
||||
Volume 28 (October), Number 10, 1985, p. 1076-1085.
|
||||
|
||||
@param p_square_cumulative_distribution_num_cells
|
||||
*/
|
||||
template<typename Sample, typename Weight>
|
||||
struct weighted_p_square_cumulative_distribution_impl
|
||||
: accumulator_base
|
||||
{
|
||||
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
|
||||
typedef typename numeric::functional::average<weighted_sample, std::size_t>::result_type float_type;
|
||||
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
|
||||
typedef std::vector<float_type> array_type;
|
||||
// for boost::result_of
|
||||
typedef iterator_range<typename histogram_type::iterator> result_type;
|
||||
|
||||
template<typename Args>
|
||||
weighted_p_square_cumulative_distribution_impl(Args const &args)
|
||||
: num_cells(args[p_square_cumulative_distribution_num_cells])
|
||||
, heights(num_cells + 1)
|
||||
, actual_positions(num_cells + 1)
|
||||
, desired_positions(num_cells + 1)
|
||||
, histogram(num_cells + 1)
|
||||
, is_dirty(true)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
void operator ()(Args const &args)
|
||||
{
|
||||
this->is_dirty = true;
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
std::size_t sample_cell = 1; // k
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
// accumulate num_cells + 1 first samples
|
||||
if (cnt <= b + 1)
|
||||
{
|
||||
this->heights[cnt - 1] = args[sample];
|
||||
this->actual_positions[cnt - 1] = args[weight];
|
||||
|
||||
// complete the initialization of heights by sorting
|
||||
if (cnt == b + 1)
|
||||
{
|
||||
//std::sort(this->heights.begin(), this->heights.end());
|
||||
|
||||
// TODO: we need to sort the initial samples (in heights) in ascending order and
|
||||
// sort their weights (in actual_positions) the same way. The following lines do
|
||||
// it, but there must be a better and more efficient way of doing this.
|
||||
typename array_type::iterator it_begin, it_end, it_min;
|
||||
|
||||
it_begin = this->heights.begin();
|
||||
it_end = this->heights.end();
|
||||
|
||||
std::size_t pos = 0;
|
||||
|
||||
while (it_begin != it_end)
|
||||
{
|
||||
it_min = std::min_element(it_begin, it_end);
|
||||
std::size_t d = std::distance(it_begin, it_min);
|
||||
std::swap(*it_begin, *it_min);
|
||||
std::swap(this->actual_positions[pos], this->actual_positions[pos + d]);
|
||||
++it_begin;
|
||||
++pos;
|
||||
}
|
||||
|
||||
// calculate correct initial actual positions
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
this->actual_positions[i] += this->actual_positions[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
|
||||
if (args[sample] < this->heights[0])
|
||||
{
|
||||
this->heights[0] = args[sample];
|
||||
this->actual_positions[0] = args[weight];
|
||||
sample_cell = 1;
|
||||
}
|
||||
else if (this->heights[b] <= args[sample])
|
||||
{
|
||||
this->heights[b] = args[sample];
|
||||
sample_cell = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename array_type::iterator it;
|
||||
it = std::upper_bound(
|
||||
this->heights.begin()
|
||||
, this->heights.end()
|
||||
, args[sample]
|
||||
);
|
||||
|
||||
sample_cell = std::distance(this->heights.begin(), it);
|
||||
}
|
||||
|
||||
// increment positions of markers above sample_cell
|
||||
for (std::size_t i = sample_cell; i < b + 1; ++i)
|
||||
{
|
||||
this->actual_positions[i] += args[weight];
|
||||
}
|
||||
|
||||
// determine desired marker positions
|
||||
for (std::size_t i = 1; i < b + 1; ++i)
|
||||
{
|
||||
this->desired_positions[i] = this->actual_positions[0]
|
||||
+ numeric::average((i-1) * (sum_of_weights(args) - this->actual_positions[0]), b);
|
||||
}
|
||||
|
||||
// adjust heights of markers 2 to num_cells if necessary
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
// offset to desire position
|
||||
float_type d = this->desired_positions[i] - this->actual_positions[i];
|
||||
|
||||
// offset to next position
|
||||
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
|
||||
|
||||
// offset to previous position
|
||||
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
|
||||
|
||||
// height ds
|
||||
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
|
||||
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
|
||||
|
||||
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
|
||||
{
|
||||
short sign_d = static_cast<short>(d / std::abs(d));
|
||||
|
||||
// try adjusting heights[i] using p-squared formula
|
||||
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
|
||||
|
||||
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
|
||||
{
|
||||
this->heights[i] = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use linear formula
|
||||
if (d>0)
|
||||
{
|
||||
this->heights[i] += hp;
|
||||
}
|
||||
if (d<0)
|
||||
{
|
||||
this->heights[i] -= hm;
|
||||
}
|
||||
}
|
||||
this->actual_positions[i] += sign_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
result_type result(Args const &args) const
|
||||
{
|
||||
if (this->is_dirty)
|
||||
{
|
||||
this->is_dirty = false;
|
||||
|
||||
// creates a vector of std::pair where each pair i holds
|
||||
// the values heights[i] (x-axis of histogram) and
|
||||
// actual_positions[i] / sum_of_weights (y-axis of histogram)
|
||||
|
||||
for (std::size_t i = 0; i < this->histogram.size(); ++i)
|
||||
{
|
||||
this->histogram[i] = std::make_pair(this->heights[i], numeric::average(this->actual_positions[i], sum_of_weights(args)));
|
||||
}
|
||||
}
|
||||
|
||||
return make_iterator_range(this->histogram);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t num_cells; // number of cells b
|
||||
array_type heights; // q_i
|
||||
array_type actual_positions; // n_i
|
||||
array_type desired_positions; // n'_i
|
||||
mutable histogram_type histogram; // histogram
|
||||
mutable bool is_dirty;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// tag::weighted_p_square_cumulative_distribution
|
||||
//
|
||||
namespace tag
|
||||
{
|
||||
struct weighted_p_square_cumulative_distribution
|
||||
: depends_on<count, sum_of_weights>
|
||||
, p_square_cumulative_distribution_num_cells
|
||||
{
|
||||
typedef accumulators::impl::weighted_p_square_cumulative_distribution_impl<mpl::_1, mpl::_2> impl;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// extract::weighted_p_square_cumulative_distribution
|
||||
//
|
||||
namespace extract
|
||||
{
|
||||
extractor<tag::weighted_p_square_cumulative_distribution> const weighted_p_square_cumulative_distribution = {};
|
||||
|
||||
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_p_square_cumulative_distribution)
|
||||
}
|
||||
|
||||
using extract::weighted_p_square_cumulative_distribution;
|
||||
|
||||
}} // namespace boost::accumulators
|
||||
|
||||
#endif
|
|
@ -1,262 +1,19 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// weighted_p_square_cumulative_distribution.hpp
|
||||
//
|
||||
// Copyright 2006 Daniel Egloff, Olivier Gygi. Distributed under the Boost
|
||||
// Copyright 2012 Eric Niebler. 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_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_DE_01_01_2006
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_DE_01_01_2006
|
||||
#ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/accumulators/framework/accumulator_base.hpp>
|
||||
#include <boost/accumulators/framework/extractor.hpp>
|
||||
#include <boost/accumulators/numeric/functional.hpp>
|
||||
#include <boost/accumulators/framework/parameters/sample.hpp>
|
||||
#include <boost/accumulators/statistics_fwd.hpp>
|
||||
#include <boost/accumulators/statistics/count.hpp>
|
||||
#include <boost/accumulators/statistics/sum.hpp>
|
||||
#include <boost/accumulators/statistics/p_square_cumulative_distribution.hpp> // for named parameter p_square_cumulative_distribution_num_cells
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
|
||||
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp")
|
||||
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||
# warning "This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace accumulators
|
||||
{
|
||||
|
||||
namespace impl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// weighted_p_square_cumulative_distribution_impl
|
||||
// cumulative distribution calculation (as histogram)
|
||||
/**
|
||||
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm for weighted samples
|
||||
|
||||
A histogram of the sample cumulative distribution is computed dynamically without storing samples
|
||||
based on the \f$ P^2 \f$ algorithm for weighted samples. The returned histogram has a specifiable
|
||||
amount (num_cells) equiprobable (and not equal-sized) cells.
|
||||
|
||||
Note that applying importance sampling results in regions to be more and other regions to be less
|
||||
accurately estimated than without importance sampling, i.e., with unweighted samples.
|
||||
|
||||
For further details, see
|
||||
|
||||
R. Jain and I. Chlamtac, The P^2 algorithmus for dynamic calculation of quantiles and
|
||||
histograms without storing observations, Communications of the ACM,
|
||||
Volume 28 (October), Number 10, 1985, p. 1076-1085.
|
||||
|
||||
@param p_square_cumulative_distribution_num_cells
|
||||
*/
|
||||
template<typename Sample, typename Weight>
|
||||
struct weighted_p_square_cumulative_distribution_impl
|
||||
: accumulator_base
|
||||
{
|
||||
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
|
||||
typedef typename numeric::functional::average<weighted_sample, std::size_t>::result_type float_type;
|
||||
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
|
||||
typedef std::vector<float_type> array_type;
|
||||
// for boost::result_of
|
||||
typedef iterator_range<typename histogram_type::iterator> result_type;
|
||||
|
||||
template<typename Args>
|
||||
weighted_p_square_cumulative_distribution_impl(Args const &args)
|
||||
: num_cells(args[p_square_cumulative_distribution_num_cells])
|
||||
, heights(num_cells + 1)
|
||||
, actual_positions(num_cells + 1)
|
||||
, desired_positions(num_cells + 1)
|
||||
, histogram(num_cells + 1)
|
||||
, is_dirty(true)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
void operator ()(Args const &args)
|
||||
{
|
||||
this->is_dirty = true;
|
||||
|
||||
std::size_t cnt = count(args);
|
||||
std::size_t sample_cell = 1; // k
|
||||
std::size_t b = this->num_cells;
|
||||
|
||||
// accumulate num_cells + 1 first samples
|
||||
if (cnt <= b + 1)
|
||||
{
|
||||
this->heights[cnt - 1] = args[sample];
|
||||
this->actual_positions[cnt - 1] = args[weight];
|
||||
|
||||
// complete the initialization of heights by sorting
|
||||
if (cnt == b + 1)
|
||||
{
|
||||
//std::sort(this->heights.begin(), this->heights.end());
|
||||
|
||||
// TODO: we need to sort the initial samples (in heights) in ascending order and
|
||||
// sort their weights (in actual_positions) the same way. The following lines do
|
||||
// it, but there must be a better and more efficient way of doing this.
|
||||
typename array_type::iterator it_begin, it_end, it_min;
|
||||
|
||||
it_begin = this->heights.begin();
|
||||
it_end = this->heights.end();
|
||||
|
||||
std::size_t pos = 0;
|
||||
|
||||
while (it_begin != it_end)
|
||||
{
|
||||
it_min = std::min_element(it_begin, it_end);
|
||||
std::size_t d = std::distance(it_begin, it_min);
|
||||
std::swap(*it_begin, *it_min);
|
||||
std::swap(this->actual_positions[pos], this->actual_positions[pos + d]);
|
||||
++it_begin;
|
||||
++pos;
|
||||
}
|
||||
|
||||
// calculate correct initial actual positions
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
this->actual_positions[i] += this->actual_positions[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
|
||||
if (args[sample] < this->heights[0])
|
||||
{
|
||||
this->heights[0] = args[sample];
|
||||
this->actual_positions[0] = args[weight];
|
||||
sample_cell = 1;
|
||||
}
|
||||
else if (this->heights[b] <= args[sample])
|
||||
{
|
||||
this->heights[b] = args[sample];
|
||||
sample_cell = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename array_type::iterator it;
|
||||
it = std::upper_bound(
|
||||
this->heights.begin()
|
||||
, this->heights.end()
|
||||
, args[sample]
|
||||
);
|
||||
|
||||
sample_cell = std::distance(this->heights.begin(), it);
|
||||
}
|
||||
|
||||
// increment positions of markers above sample_cell
|
||||
for (std::size_t i = sample_cell; i < b + 1; ++i)
|
||||
{
|
||||
this->actual_positions[i] += args[weight];
|
||||
}
|
||||
|
||||
// determine desired marker positions
|
||||
for (std::size_t i = 1; i < b + 1; ++i)
|
||||
{
|
||||
this->desired_positions[i] = this->actual_positions[0]
|
||||
+ numeric::average((i-1) * (sum_of_weights(args) - this->actual_positions[0]), b);
|
||||
}
|
||||
|
||||
// adjust heights of markers 2 to num_cells if necessary
|
||||
for (std::size_t i = 1; i < b; ++i)
|
||||
{
|
||||
// offset to desire position
|
||||
float_type d = this->desired_positions[i] - this->actual_positions[i];
|
||||
|
||||
// offset to next position
|
||||
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
|
||||
|
||||
// offset to previous position
|
||||
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
|
||||
|
||||
// height ds
|
||||
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
|
||||
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
|
||||
|
||||
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
|
||||
{
|
||||
short sign_d = static_cast<short>(d / std::abs(d));
|
||||
|
||||
// try adjusting heights[i] using p-squared formula
|
||||
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
|
||||
|
||||
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
|
||||
{
|
||||
this->heights[i] = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use linear formula
|
||||
if (d>0)
|
||||
{
|
||||
this->heights[i] += hp;
|
||||
}
|
||||
if (d<0)
|
||||
{
|
||||
this->heights[i] -= hm;
|
||||
}
|
||||
}
|
||||
this->actual_positions[i] += sign_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
result_type result(Args const &args) const
|
||||
{
|
||||
if (this->is_dirty)
|
||||
{
|
||||
this->is_dirty = false;
|
||||
|
||||
// creates a vector of std::pair where each pair i holds
|
||||
// the values heights[i] (x-axis of histogram) and
|
||||
// actual_positions[i] / sum_of_weights (y-axis of histogram)
|
||||
|
||||
for (std::size_t i = 0; i < this->histogram.size(); ++i)
|
||||
{
|
||||
this->histogram[i] = std::make_pair(this->heights[i], numeric::average(this->actual_positions[i], sum_of_weights(args)));
|
||||
}
|
||||
}
|
||||
|
||||
return make_iterator_range(this->histogram);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t num_cells; // number of cells b
|
||||
array_type heights; // q_i
|
||||
array_type actual_positions; // n_i
|
||||
array_type desired_positions; // n'_i
|
||||
mutable histogram_type histogram; // histogram
|
||||
mutable bool is_dirty;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// tag::weighted_p_square_cumulative_distribution
|
||||
//
|
||||
namespace tag
|
||||
{
|
||||
struct weighted_p_square_cumulative_distribution
|
||||
: depends_on<count, sum_of_weights>
|
||||
, p_square_cumulative_distribution_num_cells
|
||||
{
|
||||
typedef accumulators::impl::weighted_p_square_cumulative_distribution_impl<mpl::_1, mpl::_2> impl;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// extract::weighted_p_square_cumulative_distribution
|
||||
//
|
||||
namespace extract
|
||||
{
|
||||
extractor<tag::weighted_p_square_cumulative_distribution> const weighted_p_square_cumulative_distribution = {};
|
||||
|
||||
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_p_square_cumulative_distribution)
|
||||
}
|
||||
|
||||
using extract::weighted_p_square_cumulative_distribution;
|
||||
|
||||
}} // namespace boost::accumulators
|
||||
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_QUANTILE_HPP_DE_01_01_2006
|
||||
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_QUANTILE_HPP_DE_01_01_2006
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <functional>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace impl
|
|||
template<typename Args>
|
||||
void
|
||||
#if BOOST_ACCUMULATORS_GCC_VERSION > 40305
|
||||
__attribute__((optimize("no-associative-math")))
|
||||
__attribute__((__optimize__("no-associative-math")))
|
||||
#endif
|
||||
operator ()(Args const &args)
|
||||
{
|
||||
|
|
175
3party/boost/boost/algorithm/clamp.hpp
Normal file
175
3party/boost/boost/algorithm/clamp.hpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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)
|
||||
|
||||
Revision history:
|
||||
27 June 2009 mtc First version
|
||||
23 Oct 2010 mtc Added predicate version
|
||||
|
||||
*/
|
||||
|
||||
/// \file clamp.hpp
|
||||
/// \brief Clamp algorithm
|
||||
/// \author Marshall Clow
|
||||
///
|
||||
/// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
|
||||
|
||||
#ifndef BOOST_ALGORITHM_CLAMP_HPP
|
||||
#define BOOST_ALGORITHM_CLAMP_HPP
|
||||
|
||||
#include <functional> // For std::less
|
||||
#include <iterator> // For std::iterator_traits
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/mpl/identity.hpp> // for identity
|
||||
#include <boost/utility/enable_if.hpp> // for boost::disable_if
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// typename boost::mpl::identity<T>::type const& lo,
|
||||
/// typename boost::mpl::identity<T>::type const& hi, Pred p )
|
||||
/// \return the value "val" brought into the range [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
/// If p ( val, lo ) return lo.
|
||||
/// If p ( hi, val ) return hi.
|
||||
/// Otherwise, return the original value.
|
||||
///
|
||||
/// \param val The value to be clamped
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
///
|
||||
template<typename T, typename Pred>
|
||||
T const & clamp ( T const& val,
|
||||
typename boost::mpl::identity<T>::type const & lo,
|
||||
typename boost::mpl::identity<T>::type const & hi, Pred p )
|
||||
{
|
||||
// assert ( !p ( hi, lo )); // Can't assert p ( lo, hi ) b/c they might be equal
|
||||
return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
|
||||
}
|
||||
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// typename boost::mpl::identity<T>::type const& lo,
|
||||
/// typename boost::mpl::identity<T>::type const& hi )
|
||||
/// \return the value "val" brought into the range [ lo, hi ].
|
||||
/// If the value is less than lo, return lo.
|
||||
/// If the value is greater than "hi", return hi.
|
||||
/// Otherwise, return the original value.
|
||||
///
|
||||
/// \param val The value to be clamped
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
///
|
||||
template<typename T>
|
||||
T const& clamp ( const T& val,
|
||||
typename boost::mpl::identity<T>::type const & lo,
|
||||
typename boost::mpl::identity<T>::type const & hi )
|
||||
{
|
||||
return (clamp) ( val, lo, hi, std::less<T>());
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param first The start of the range of values
|
||||
/// \param last One past the end of the range of input values
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower 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>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
*out++ = clamp ( *first++, lo, hi );
|
||||
return out;
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param r The range of values to be clamped
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower 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>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
|
||||
}
|
||||
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
///
|
||||
/// \param first The start of the range of values
|
||||
/// \param last One past the end of the range of input values
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Pred>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
*out++ = clamp ( *first++, lo, hi, p );
|
||||
return out;
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
/// Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
///
|
||||
/// \param r The range of values to be clamped
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
//
|
||||
// Disable this template if the first two parameters are the same type;
|
||||
// In that case, the user will get the two iterator version.
|
||||
template<typename Range, typename OutputIterator, typename Pred>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
Pred p )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_CLAMP_HPP
|
91
3party/boost/boost/algorithm/cxx11/all_of.hpp
Normal file
91
3party/boost/boost/algorithm/cxx11/all_of.hpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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 all_of.hpp
|
||||
/// \brief Test ranges to see if all elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ALL_OF_HPP
|
||||
#define BOOST_ALGORITHM_ALL_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::all_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of all_of if it is available
|
||||
using std::all_of; // Section 25.2.1
|
||||
#else
|
||||
/// \fn all_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if all elements in [first, last) satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool all_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p(*first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn all_of ( const Range &r, Predicate p )
|
||||
/// \return true if all elements in the range satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool all_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
/// \fn all_of_equal ( InputIterator first, InputIterator last, const T &val )
|
||||
/// \return true if all elements in [first, last) are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename T>
|
||||
bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val != *first )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn all_of_equal ( const Range &r, const T &val )
|
||||
/// \return true if all elements in the range are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename T>
|
||||
bool all_of_equal ( const Range &r, const T &val )
|
||||
{
|
||||
return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ALL_OF_HPP
|
90
3party/boost/boost/algorithm/cxx11/any_of.hpp
Normal file
90
3party/boost/boost/algorithm/cxx11/any_of.hpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Test ranges to see if any elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ANY_OF_HPP
|
||||
#define BOOST_ALGORITHM_ANY_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::any_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// Use the C++11 versions of any_of if it is available
|
||||
#if __cplusplus >= 201103L
|
||||
using std::any_of; // Section 25.2.2
|
||||
#else
|
||||
/// \fn any_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if any of the elements in [first, last) satisfy the predicate
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool any_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p(*first))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn any_of ( const Range &r, Predicate p )
|
||||
/// \return true if any elements in the range satisfy the predicate 'p'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool any_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::any_of (boost::begin (r), boost::end (r), p);
|
||||
}
|
||||
|
||||
/// \fn any_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if any of the elements in [first, last) are equal to 'val'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool any_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val == *first )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn any_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if any of the elements in the range are equal to 'val'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool any_of_equal ( const Range &r, const V &val )
|
||||
{
|
||||
return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ANY_OF_HPP
|
133
3party/boost/boost/algorithm/cxx11/copy_if.hpp
Normal file
133
3party/boost/boost/algorithm/cxx11/copy_if.hpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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 copy_if.hpp
|
||||
/// \brief Copy a subset of a sequence to a new sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_COPY_IF_HPP
|
||||
#define BOOST_ALGORITHM_COPY_IF_HPP
|
||||
|
||||
#include <algorithm> // for std::copy_if, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of copy_if if it is available
|
||||
using std::copy_if; // Section 25.3.1
|
||||
#else
|
||||
/// \fn copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements from the input range that satisfy the
|
||||
/// predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if (p(*first))
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements from the input range that satisfy the
|
||||
/// predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( InputIterator first, InputIterator last,
|
||||
OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && p(*first); ++first )
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that do not
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && !p(*first); ++first )
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that do not
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_COPY_IF_HPP
|
44
3party/boost/boost/algorithm/cxx11/copy_n.hpp
Normal file
44
3party/boost/boost/algorithm/cxx11/copy_n.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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 copy_n.hpp
|
||||
/// \brief Copy n items from one sequence to another
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_COPY_N_HPP
|
||||
#define BOOST_ALGORITHM_COPY_N_HPP
|
||||
|
||||
#include <algorithm> // for std::copy_n, if available
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of copy_n if it is available
|
||||
using std::copy_n; // Section 25.3.1
|
||||
#else
|
||||
/// \fn copy_n ( InputIterator first, Size n, OutputIterator result )
|
||||
/// \brief Copies exactly n (n > 0) elements from the range starting at first to
|
||||
/// the range starting at result.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param n The number of elements to copy
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template <typename InputIterator, typename Size, typename OutputIterator>
|
||||
OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result )
|
||||
{
|
||||
for ( ; n > 0; --n, ++first, ++result )
|
||||
*result = *first;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_COPY_IF_HPP
|
60
3party/boost/boost/algorithm/cxx11/find_if_not.hpp
Normal file
60
3party/boost/boost/algorithm/cxx11/find_if_not.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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 find_if_not.hpp
|
||||
/// \brief Find the first element in a sequence that does not satisfy a predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_FIND_IF_NOT_HPP
|
||||
#define BOOST_ALGORITHM_FIND_IF_NOT_HPP
|
||||
|
||||
#include <algorithm> // for std::find_if_not, if it exists
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of find_if_not if it is available
|
||||
using std::find_if_not; // Section 25.2.5
|
||||
#else
|
||||
/// \fn find_if_not(InputIterator first, InputIterator last, Predicate p)
|
||||
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
|
||||
/// \return The iterator pointing to the desired element.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template<typename InputIterator, typename Predicate>
|
||||
InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p(*first))
|
||||
break;
|
||||
return first;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn find_if_not ( const Range &r, Predicate p )
|
||||
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
|
||||
/// \return The iterator pointing to the desired element.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
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);
|
||||
}
|
||||
|
||||
}}
|
||||
#endif // BOOST_ALGORITHM_FIND_IF_NOT_HPP
|
74
3party/boost/boost/algorithm/cxx11/iota.hpp
Normal file
74
3party/boost/boost/algorithm/cxx11/iota.hpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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 iota.hpp
|
||||
/// \brief Generate an increasing series
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IOTA_HPP
|
||||
#define BOOST_ALGORITHM_IOTA_HPP
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::iota; // Section 26.7.6
|
||||
#else
|
||||
/// \fn iota ( ForwardIterator first, ForwardIterator last, T value )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in [first, last)
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param value The initial value of the sequence to be generated
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template <typename ForwardIterator, typename T>
|
||||
void iota ( ForwardIterator first, ForwardIterator last, T value )
|
||||
{
|
||||
for ( ; first != last; ++first, ++value )
|
||||
*first = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn iota ( Range &r, T value )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param value The initial value of the sequence to be generated
|
||||
///
|
||||
template <typename Range, typename T>
|
||||
void iota ( Range &r, T value )
|
||||
{
|
||||
boost::algorithm::iota (boost::begin(r), boost::end(r), value);
|
||||
}
|
||||
|
||||
|
||||
/// \fn iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param out An output iterator to write the results into
|
||||
/// \param value The initial value of the sequence to be generated
|
||||
/// \param n The number of items to write
|
||||
///
|
||||
template <typename OutputIterator, typename T>
|
||||
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
{
|
||||
while ( n-- > 0 )
|
||||
*out++ = value++;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IOTA_HPP
|
65
3party/boost/boost/algorithm/cxx11/is_partitioned.hpp
Normal file
65
3party/boost/boost/algorithm/cxx11/is_partitioned.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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.hpp
|
||||
/// \brief Tell if a sequence is partitioned
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
||||
#define BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
||||
|
||||
#include <algorithm> // for std::is_partitioned, if available
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_partitioned if it is available
|
||||
using std::is_partitioned; // Section 25.3.13
|
||||
#else
|
||||
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
|
||||
/// \brief Tests to see if a sequence is partititioned according to a predicate
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p The predicicate to test the values with
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template <typename InputIterator, typename UnaryPredicate>
|
||||
bool is_partitioned ( 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 false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn is_partitioned ( const Range &r, UnaryPredicate p )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p The predicicate to test the values with
|
||||
///
|
||||
template <typename Range, typename UnaryPredicate>
|
||||
bool is_partitioned ( const Range &r, UnaryPredicate p )
|
||||
{
|
||||
return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
139
3party/boost/boost/algorithm/cxx11/is_permutation.hpp
Normal file
139
3party/boost/boost/algorithm/cxx11/is_permutation.hpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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_permutation.hpp
|
||||
/// \brief Is a sequence a permutation of another sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
|
||||
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||
#include <utility> // for std::make_pair
|
||||
#include <functional> // for std::equal_to
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/tr1/tr1/tuple> // for tie
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_permutation if it is available
|
||||
using std::is_permutation; // Section 25.2.12
|
||||
#else
|
||||
/// \cond DOXYGEN_HIDE
|
||||
namespace detail {
|
||||
template <typename Predicate, typename Iterator>
|
||||
struct value_predicate {
|
||||
value_predicate ( Predicate p, Iterator it ) : p_ ( p ), it_ ( it ) {}
|
||||
|
||||
template <typename T1>
|
||||
bool operator () ( const T1 &t1 ) const { return p_ ( *it_, t1 ); }
|
||||
private:
|
||||
Predicate &p_;
|
||||
Iterator it_;
|
||||
};
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2, BinaryPredicate p )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param p The predicate to compare elements with
|
||||
///
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, BinaryPredicate p )
|
||||
{
|
||||
// Skip the common prefix (if any)
|
||||
// std::tie (first1, first2) = std::mismatch (first1, last1, first2, p);
|
||||
std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2, p);
|
||||
first1 = eq.first;
|
||||
first2 = eq.second;
|
||||
if ( first1 != last1 ) {
|
||||
// Create last2
|
||||
ForwardIterator2 last2 = first2;
|
||||
std::advance ( last2, std::distance (first1, last1));
|
||||
|
||||
// for each unique value in the sequence [first1,last1), count how many times
|
||||
// it occurs, and make sure it occurs the same number of times in [first2, last2)
|
||||
for ( ForwardIterator1 iter = first1; iter != last1; ++iter ) {
|
||||
detail::value_predicate<BinaryPredicate, ForwardIterator1> pred ( p, iter );
|
||||
|
||||
/* For each value we haven't seen yet... */
|
||||
if ( std::find_if ( first1, iter, pred ) == iter ) {
|
||||
std::size_t dest_count = std::count_if ( first2, last2, pred );
|
||||
if ( dest_count == 0 || dest_count != (std::size_t) std::count_if ( iter, last1, pred ))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2 >
|
||||
bool is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
{
|
||||
// How should I deal with the idea that ForwardIterator1::value_type
|
||||
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||
return boost::algorithm::is_permutation ( first, last, first2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
template <typename Range, typename ForwardIterator>
|
||||
bool is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
{
|
||||
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2 );
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param pred The predicate to compare elements with
|
||||
///
|
||||
// Disable this template when the first two parameters are the same type
|
||||
// That way the non-range version will be chosen.
|
||||
template <typename Range, typename ForwardIterator, typename BinaryPredicate>
|
||||
typename boost::disable_if_c<boost::is_same<Range, ForwardIterator>::value, bool>::type
|
||||
is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2, pred );
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
287
3party/boost/boost/algorithm/cxx11/is_sorted.hpp
Normal file
287
3party/boost/boost/algorithm/cxx11/is_sorted.hpp
Normal file
|
@ -0,0 +1,287 @@
|
|||
// Copyright (c) 2010 Nuovation System Designs, LLC
|
||||
// Grant Erickson <gerickson@nuovations.com>
|
||||
//
|
||||
// Reworked somewhat by Marshall Clow; August 2010
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ORDERED_HPP
|
||||
#define BOOST_ALGORITHM_ORDERED_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_sorted/is_sorted_until if they are available
|
||||
using std::is_sorted_until; // Section 25.4.1.5
|
||||
using std::is_sorted; // Section 25.4.1.5
|
||||
#else
|
||||
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
/// \return the point in the sequence [first, last) where the elements are unordered
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename ForwardIterator, typename Pred>
|
||||
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
{
|
||||
if ( first == last ) return last; // the empty sequence is ordered
|
||||
ForwardIterator next = first;
|
||||
while ( ++next != last )
|
||||
{
|
||||
if ( p ( *next, *first ))
|
||||
return next;
|
||||
first = next;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return the point in the sequence [first, last) where the elements are unordered
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
template <typename ForwardIterator>
|
||||
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
/// \return whether or not the entire sequence is sorted
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename ForwardIterator, typename Pred>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until (first, last, p) == last;
|
||||
}
|
||||
|
||||
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return whether or not the entire sequence is sorted
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
template <typename ForwardIterator>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until (first, last) == last;
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_sorted_until ( const R &range, Pred p )
|
||||
/// \return the point in the range R where the elements are unordered
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename R, typename Pred>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<R, Pred>::value,
|
||||
typename boost::range_iterator<const R>
|
||||
>::type is_sorted_until ( const R &range, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted_until ( const R &range )
|
||||
/// \return the point in the range R where the elements are unordered
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
template <typename R>
|
||||
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 ));
|
||||
}
|
||||
|
||||
/// \fn is_sorted ( const R &range, Pred p )
|
||||
/// \return whether or not the entire range R is sorted
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename R, typename Pred>
|
||||
typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
|
||||
is_sorted ( const R &range, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted ( const R &range )
|
||||
/// \return whether or not the entire range R is sorted
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
template <typename R>
|
||||
bool is_sorted ( const R &range )
|
||||
{
|
||||
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
|
||||
/// equal to the previous one.
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::less<value_type>());
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_increasing ( const R &range )
|
||||
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
|
||||
/// equal to the previous one.
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
|
||||
template <typename R>
|
||||
bool is_increasing ( const R &range )
|
||||
{
|
||||
return is_increasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \fn is_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is decreasing; i.e, each item is less than
|
||||
/// or equal to the previous one.
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_decreasing ( const R &range )
|
||||
/// \return true if the entire sequence is decreasing; i.e, each item is less than
|
||||
/// or equal to the previous one.
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
|
||||
template <typename R>
|
||||
bool is_decreasing ( const R &range )
|
||||
{
|
||||
return is_decreasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \fn is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
|
||||
/// than the previous one
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_increasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_strictly_increasing ( const R &range )
|
||||
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
|
||||
/// than the previous one
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_increasing instead.
|
||||
template <typename R>
|
||||
bool is_strictly_increasing ( const R &range )
|
||||
{
|
||||
return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
|
||||
/// the previous one
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_decreasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_strictly_decreasing ( const R &range )
|
||||
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
|
||||
/// the previous one
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_decreasing instead.
|
||||
template <typename R>
|
||||
bool is_strictly_decreasing ( const R &range )
|
||||
{
|
||||
return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
}} // namespace boost
|
||||
|
||||
#endif // BOOST_ALGORITHM_ORDERED_HPP
|
88
3party/boost/boost/algorithm/cxx11/none_of.hpp
Normal file
88
3party/boost/boost/algorithm/cxx11/none_of.hpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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 none_of.hpp
|
||||
/// \brief Test ranges to see if no elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_NONE_OF_HPP
|
||||
#define BOOST_ALGORITHM_NONE_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::none_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// Use the C++11 versions of the none_of if it is available
|
||||
#if __cplusplus >= 201103L
|
||||
using std::none_of; // Section 25.2.3
|
||||
#else
|
||||
/// \fn none_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if none of the elements in [first, last) satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool none_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p(*first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn none_of ( const Range &r, Predicate p )
|
||||
/// \return true if none of the elements in the range satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool none_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::none_of (boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
/// \fn none_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if none of the elements in [first, last) are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool none_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val == *first )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn none_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if none of the elements in the range are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool none_of_equal ( const Range &r, const V & val )
|
||||
{
|
||||
return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_NONE_OF_HPP
|
82
3party/boost/boost/algorithm/cxx11/one_of.hpp
Normal file
82
3party/boost/boost/algorithm/cxx11/one_of.hpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
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 one_of.hpp
|
||||
/// \brief Test ranges to see if only one element matches a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef 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/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn one_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if the predicate 'p' is true for exactly one item in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool one_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
InputIterator i = std::find_if (first, last, p);
|
||||
if (i == last)
|
||||
return false; // Didn't occur at all
|
||||
return boost::algorithm::none_of (++i, last, p);
|
||||
}
|
||||
|
||||
/// \fn one_of ( const Range &r, Predicate p )
|
||||
/// \return true if the predicate 'p' is true for exactly one item in the range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool one_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn one_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if the value 'val' exists only once in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool one_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
InputIterator i = std::find (first, last, val); // find first occurrence of 'val'
|
||||
if (i == last)
|
||||
return false; // Didn't occur at all
|
||||
return boost::algorithm::none_of_equal (++i, last, val);
|
||||
}
|
||||
|
||||
/// \fn one_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if the value 'val' exists only once in the range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool one_of_equal ( const Range &r, const V &val )
|
||||
{
|
||||
return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ALL_HPP
|
78
3party/boost/boost/algorithm/cxx11/partition_copy.hpp
Normal file
78
3party/boost/boost/algorithm/cxx11/partition_copy.hpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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 partition_copy.hpp
|
||||
/// \brief Copy a subset of a sequence to a new sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
|
||||
#include <algorithm> // for std::partition_copy, if available
|
||||
#include <utility> // for make_pair
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of partition_copy if it is available
|
||||
using std::partition_copy; // Section 25.3.13
|
||||
#else
|
||||
/// \fn partition_copy ( InputIterator first, InputIterator last,
|
||||
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
/// \brief Copies the elements that satisfy the predicate p from the range [first, last)
|
||||
/// to the range beginning at d_first_true, and
|
||||
/// copies the elements that do not satisfy p to the range beginning at d_first_false.
|
||||
///
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param out_true An output iterator to write the elements that satisfy the predicate into
|
||||
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
|
||||
/// \param p A predicate for dividing the elements of the input sequence.
|
||||
///
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template <typename InputIterator,
|
||||
typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
|
||||
std::pair<OutputIterator1, OutputIterator2>
|
||||
partition_copy ( InputIterator first, InputIterator last,
|
||||
OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p (*first))
|
||||
*out_true++ = *first;
|
||||
else
|
||||
*out_false++ = *first;
|
||||
return std::pair<OutputIterator1, OutputIterator2> ( out_true, out_false );
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn partition_copy ( const Range &r,
|
||||
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param out_true An output iterator to write the elements that satisfy the predicate into
|
||||
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
|
||||
/// \param p A predicate for dividing the elements of the input sequence.
|
||||
///
|
||||
template <typename Range, typename OutputIterator1, typename OutputIterator2,
|
||||
typename UnaryPredicate>
|
||||
std::pair<OutputIterator1, OutputIterator2>
|
||||
partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false,
|
||||
UnaryPredicate p )
|
||||
{
|
||||
return boost::algorithm::partition_copy
|
||||
(boost::begin(r), boost::end(r), out_true, out_false, p );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_PARTITION_COPY_HPP
|
72
3party/boost/boost/algorithm/cxx11/partition_point.hpp
Normal file
72
3party/boost/boost/algorithm/cxx11/partition_point.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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 partition_point.hpp
|
||||
/// \brief Find the partition point in a sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
|
||||
#include <algorithm> // for std::partition_point, if available
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of partition_point if it is available
|
||||
using std::partition_point; // Section 25.3.13
|
||||
#else
|
||||
/// \fn partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
|
||||
/// \brief Given a partitioned range, returns the partition point, i.e, the first element
|
||||
/// that does not satisfy p
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p The predicate to test the values with
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template <typename ForwardIterator, typename Predicate>
|
||||
ForwardIterator partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
|
||||
{
|
||||
std::size_t dist = std::distance ( first, last );
|
||||
while ( first != last ) {
|
||||
std::size_t d2 = dist / 2;
|
||||
ForwardIterator ret_val = first;
|
||||
std::advance (ret_val, d2);
|
||||
if (p (*ret_val)) {
|
||||
first = ++ret_val;
|
||||
dist -= d2 + 1;
|
||||
}
|
||||
else {
|
||||
last = ret_val;
|
||||
dist = d2;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn partition_point ( Range &r, Predicate p )
|
||||
/// \brief Given a partitioned range, returns the partition point
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p The predicate to test the values with
|
||||
///
|
||||
template <typename Range, typename Predicate>
|
||||
typename boost::range_iterator<Range> partition_point ( Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::partition_point (boost::begin(r), boost::end(r), p);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_PARTITION_POINT_HPP
|
265
3party/boost/boost/algorithm/hex.hpp
Normal file
265
3party/boost/boost/algorithm/hex.hpp
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2011-2012.
|
||||
|
||||
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)
|
||||
|
||||
Thanks to Nevin for his comments/help.
|
||||
*/
|
||||
|
||||
/*
|
||||
General problem - turn a sequence of integral types into a sequence of hexadecimal characters.
|
||||
- and back.
|
||||
|
||||
TO DO:
|
||||
1. these should really only work on integral types. (see the >> and << operations)
|
||||
-- this is done, I think.
|
||||
2. The 'value_type_or_char' struct is really a hack.
|
||||
-- but it's a better hack now that it works with back_insert_iterators
|
||||
*/
|
||||
|
||||
/// \file hex.hpp
|
||||
/// \brief Convert sequence of integral types into a sequence of hexadecimal
|
||||
/// characters and back. Based on the MySQL functions HEX and UNHEX
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_HEXHPP
|
||||
#define BOOST_ALGORITHM_HEXHPP
|
||||
|
||||
#include <iterator> // for std::iterator_traits
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/exception/all.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/*!
|
||||
\struct hex_decode_error
|
||||
\brief Base exception class for all hex decoding errors
|
||||
|
||||
\struct non_hex_input
|
||||
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
|
||||
Contains the offending character
|
||||
|
||||
\struct not_enough_input
|
||||
\brief Thrown when the input sequence unexpectedly ends
|
||||
|
||||
*/
|
||||
struct hex_decode_error : virtual boost::exception, virtual std::exception {};
|
||||
struct not_enough_input : virtual hex_decode_error {};
|
||||
struct non_hex_input : virtual hex_decode_error {};
|
||||
typedef boost::error_info<struct bad_char_,char> bad_char;
|
||||
|
||||
namespace detail {
|
||||
/// \cond DOXYGEN_HIDE
|
||||
|
||||
template <typename T, typename OutputIterator>
|
||||
OutputIterator encode_one ( T val, OutputIterator out ) {
|
||||
const std::size_t num_hex_digits = 2 * sizeof ( T );
|
||||
char res [ num_hex_digits ];
|
||||
char *p = res + num_hex_digits;
|
||||
for ( std::size_t i = 0; i < num_hex_digits; ++i, val >>= 4 )
|
||||
*--p = "0123456789ABCDEF" [ val & 0x0F ];
|
||||
return std::copy ( res, res + num_hex_digits, out );
|
||||
}
|
||||
|
||||
unsigned hex_char_to_int ( char c ) {
|
||||
if ( c >= '0' && c <= '9' ) return c - '0';
|
||||
if ( c >= 'A' && c <= 'F' ) return c - 'A' + 10;
|
||||
if ( c >= 'a' && c <= 'f' ) return c - 'a' + 10;
|
||||
BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c));
|
||||
return 0; // keep dumb compilers happy
|
||||
}
|
||||
|
||||
|
||||
// My own iterator_traits class.
|
||||
// It is here so that I can "reach inside" some kinds of output iterators
|
||||
// and get the type to write.
|
||||
template <typename Iterator>
|
||||
struct hex_iterator_traits {
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
struct hex_iterator_traits< std::back_insert_iterator<Container> > {
|
||||
typedef typename Container::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
struct hex_iterator_traits< std::front_insert_iterator<Container> > {
|
||||
typedef typename Container::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
struct hex_iterator_traits< std::insert_iterator<Container> > {
|
||||
typedef typename Container::value_type value_type;
|
||||
};
|
||||
|
||||
// ostream_iterators have three template parameters.
|
||||
// The first one is the output type, the second one is the character type of
|
||||
// the underlying stream, the third is the character traits.
|
||||
// We only care about the first one.
|
||||
template<typename T, typename charType, typename traits>
|
||||
struct hex_iterator_traits< std::ostream_iterator<T, charType, traits> > {
|
||||
typedef T value_type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
|
||||
|
||||
template <typename T>
|
||||
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
|
||||
|
||||
// What can we assume here about the inputs?
|
||||
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
|
||||
// Could it be wchar_t, say? Does it matter?
|
||||
// We are assuming ASCII for the values - but what about the storage?
|
||||
template <typename InputIterator, typename OutputIterator, typename EndPred>
|
||||
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
|
||||
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
|
||||
typedef typename hex_iterator_traits<OutputIterator>::value_type T;
|
||||
T res (0);
|
||||
|
||||
// Need to make sure that we get can read that many chars here.
|
||||
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
|
||||
if ( pred ( first, last ))
|
||||
BOOST_THROW_EXCEPTION (not_enough_input ());
|
||||
res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first));
|
||||
}
|
||||
|
||||
*out = res;
|
||||
return ++out;
|
||||
}
|
||||
/// \endcond
|
||||
}
|
||||
|
||||
|
||||
/// \fn hex ( InputIterator first, InputIterator last, OutputIterator out )
|
||||
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
|
||||
hex ( InputIterator first, InputIterator last, OutputIterator out ) {
|
||||
for ( ; first != last; ++first )
|
||||
out = detail::encode_one ( *first, out );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/// \fn hex ( const T *ptr, OutputIterator out )
|
||||
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
|
||||
///
|
||||
/// \param ptr A pointer to a 0-terminated sequence of data.
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename T, typename OutputIterator>
|
||||
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
|
||||
hex ( const T *ptr, OutputIterator out ) {
|
||||
while ( *ptr )
|
||||
out = detail::encode_one ( *ptr++, out );
|
||||
return out;
|
||||
}
|
||||
|
||||
/// \fn hex ( const Range &r, OutputIterator out )
|
||||
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename Range, typename OutputIterator>
|
||||
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<typename Range::iterator>::value_type>, OutputIterator>::type
|
||||
hex ( const Range &r, OutputIterator out ) {
|
||||
return hex (boost::begin(r), boost::end(r), out);
|
||||
}
|
||||
|
||||
|
||||
/// \fn unhex ( InputIterator first, InputIterator last, OutputIterator out )
|
||||
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
|
||||
while ( first != last )
|
||||
out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/// \fn unhex ( const T *ptr, OutputIterator out )
|
||||
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
|
||||
///
|
||||
/// \param ptr A pointer to a null-terminated input sequence.
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename T, typename OutputIterator>
|
||||
OutputIterator unhex ( const T *ptr, OutputIterator out ) {
|
||||
typedef typename detail::hex_iterator_traits<OutputIterator>::value_type OutputType;
|
||||
// If we run into the terminator while decoding, we will throw a
|
||||
// malformed input exception. It would be nicer to throw a 'Not enough input'
|
||||
// exception - but how much extra work would that require?
|
||||
while ( *ptr )
|
||||
out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end<T> );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/// \fn OutputIterator unhex ( const Range &r, OutputIterator out )
|
||||
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param out An output iterator to the results into
|
||||
/// \return The updated output iterator
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename Range, typename OutputIterator>
|
||||
OutputIterator unhex ( const Range &r, OutputIterator out ) {
|
||||
return unhex (boost::begin(r), boost::end(r), out);
|
||||
}
|
||||
|
||||
|
||||
/// \fn String hex ( const String &input )
|
||||
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
|
||||
///
|
||||
/// \param input A container to be converted
|
||||
/// \return A container with the encoded text
|
||||
template<typename String>
|
||||
String hex ( const String &input ) {
|
||||
String output;
|
||||
output.reserve (input.size () * (2 * sizeof (typename String::value_type)));
|
||||
(void) hex (input, std::back_inserter (output));
|
||||
return output;
|
||||
}
|
||||
|
||||
/// \fn String unhex ( const String &input )
|
||||
/// \brief Converts a sequence of hexadecimal characters into a sequence of characters.
|
||||
///
|
||||
/// \param input A container to be converted
|
||||
/// \return A container with the decoded text
|
||||
template<typename String>
|
||||
String unhex ( const String &input ) {
|
||||
String output;
|
||||
output.reserve (input.size () / (2 * sizeof (typename String::value_type)));
|
||||
(void) unhex (input, std::back_inserter (output));
|
||||
return output;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_HEXHPP
|
268
3party/boost/boost/algorithm/searching/boyer_moore.hpp
Normal file
268
3party/boost/boost/algorithm/searching/boyer_moore.hpp
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2010-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/*
|
||||
A templated version of the boyer-moore searching algorithm.
|
||||
|
||||
References:
|
||||
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/
|
||||
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
|
||||
|
||||
Explanations: boostinspect:noascii (test tool complains)
|
||||
http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm
|
||||
http://www.movsd.com/bm.htm
|
||||
http://www.cs.ucdavis.edu/~gusfield/cs224f09/bnotes.pdf
|
||||
|
||||
The Boyer-Moore search algorithm uses two tables, a "bad character" table
|
||||
to tell how far to skip ahead when it hits a character that is not in the pattern,
|
||||
and a "good character" table to tell how far to skip ahead when it hits a
|
||||
mismatch on a character that _is_ in the pattern.
|
||||
|
||||
Requirements:
|
||||
* Random access iterators
|
||||
* The two iterator types (patIter and corpusIter) must
|
||||
"point to" the same underlying type and be comparable.
|
||||
* Additional requirements may be imposed but the skip table, such as:
|
||||
** Numeric type (array-based skip table)
|
||||
** Hashable type (map-based skip table)
|
||||
*/
|
||||
|
||||
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||
class boyer_moore {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
boyer_moore ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length, -1 ),
|
||||
suffix_ ( k_pattern_length + 1 )
|
||||
{
|
||||
this->build_skip_table ( first, last );
|
||||
this->build_suffix_table ( first, last );
|
||||
}
|
||||
|
||||
~boyer_moore () {}
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||
typename std::iterator_traits<patIter>::value_type,
|
||||
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||
|
||||
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||
|
||||
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||
// If the pattern is larger than the corpus, we can't find it!
|
||||
if ( k_corpus_length < k_pattern_length )
|
||||
return corpus_last;
|
||||
|
||||
// Do the search
|
||||
return this->do_search ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
|
||||
return (*this) (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
typename traits::skip_table_t skip_;
|
||||
std::vector <difference_type> suffix_;
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param p A predicate used for the search comparisons.
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
/* ---- Do the matching ---- */
|
||||
corpusIter curPos = corpus_first;
|
||||
const corpusIter lastPos = corpus_last - k_pattern_length;
|
||||
difference_type j, k, m;
|
||||
|
||||
while ( curPos <= lastPos ) {
|
||||
/* while ( std::distance ( curPos, corpus_last ) >= k_pattern_length ) { */
|
||||
// Do we match right where we are?
|
||||
j = k_pattern_length;
|
||||
while ( pat_first [j-1] == curPos [j-1] ) {
|
||||
j--;
|
||||
// We matched - we're done!
|
||||
if ( j == 0 )
|
||||
return curPos;
|
||||
}
|
||||
|
||||
// Since we didn't match, figure out how far to skip forward
|
||||
k = skip_ [ curPos [ j - 1 ]];
|
||||
m = j - k - 1;
|
||||
if ( k < j && m > suffix_ [ j ] )
|
||||
curPos += m;
|
||||
else
|
||||
curPos += suffix_ [ j ];
|
||||
}
|
||||
|
||||
return corpus_last; // We didn't find anything
|
||||
}
|
||||
|
||||
|
||||
void build_skip_table ( patIter first, patIter last ) {
|
||||
for ( std::size_t i = 0; first != last; ++first, ++i )
|
||||
skip_.insert ( *first, i );
|
||||
}
|
||||
|
||||
|
||||
template<typename Iter, typename Container>
|
||||
void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) {
|
||||
const std::size_t count = std::distance ( pat_first, pat_last );
|
||||
BOOST_ASSERT ( count > 0 );
|
||||
BOOST_ASSERT ( prefix.size () == count );
|
||||
|
||||
prefix[0] = 0;
|
||||
std::size_t k = 0;
|
||||
for ( std::size_t i = 1; i < count; ++i ) {
|
||||
BOOST_ASSERT ( k < count );
|
||||
while ( k > 0 && ( pat_first[k] != pat_first[i] )) {
|
||||
BOOST_ASSERT ( k < count );
|
||||
k = prefix [ k - 1 ];
|
||||
}
|
||||
|
||||
if ( pat_first[k] == pat_first[i] )
|
||||
k++;
|
||||
prefix [ i ] = k;
|
||||
}
|
||||
}
|
||||
|
||||
void build_suffix_table ( patIter pat_first, patIter pat_last ) {
|
||||
const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last );
|
||||
|
||||
if ( count > 0 ) { // empty pattern
|
||||
std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count);
|
||||
(void) std::reverse_copy ( pat_first, pat_last, reversed.begin ());
|
||||
|
||||
std::vector<difference_type> prefix (count);
|
||||
compute_bm_prefix ( pat_first, pat_last, prefix );
|
||||
|
||||
std::vector<difference_type> prefix_reversed (count);
|
||||
compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed );
|
||||
|
||||
for ( std::size_t i = 0; i <= count; i++ )
|
||||
suffix_[i] = count - prefix [count-1];
|
||||
|
||||
for ( std::size_t i = 0; i < count; i++ ) {
|
||||
const std::size_t j = count - prefix_reversed[i];
|
||||
const difference_type k = i - prefix_reversed[i] + 1;
|
||||
|
||||
if (suffix_[j] > k)
|
||||
suffix_[j] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
|
||||
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
|
||||
Use a bit of TMP to disambiguate the 3-argument templates */
|
||||
|
||||
/// \fn boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter boyer_moore_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||
return bm ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename corpusIter>
|
||||
corpusIter boyer_moore_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||
return bm ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename patIter, typename CorpusRange>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
|
||||
::type
|
||||
boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||
return bm (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename CorpusRange>
|
||||
typename boost::range_iterator<CorpusRange>::type
|
||||
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||
return bm (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
|
||||
// Creator functions -- take a pattern range, return an object
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore<typename boost::range_iterator<const Range>::type>
|
||||
make_boyer_moore ( const Range &r ) {
|
||||
return boost::algorithm::boyer_moore
|
||||
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore<typename boost::range_iterator<Range>::type>
|
||||
make_boyer_moore ( Range &r ) {
|
||||
return boost::algorithm::boyer_moore
|
||||
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
194
3party/boost/boost/algorithm/searching/boyer_moore_horspool.hpp
Normal file
194
3party/boost/boost/algorithm/searching/boyer_moore_horspool.hpp
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2010-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
// #define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/*
|
||||
A templated version of the boyer-moore-horspool searching algorithm.
|
||||
|
||||
Requirements:
|
||||
* Random access iterators
|
||||
* The two iterator types (patIter and corpusIter) must
|
||||
"point to" the same underlying type.
|
||||
* Additional requirements may be imposed buy the skip table, such as:
|
||||
** Numeric type (array-based skip table)
|
||||
** Hashable type (map-based skip table)
|
||||
|
||||
http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
|
||||
|
||||
*/
|
||||
|
||||
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||
class boyer_moore_horspool {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
boyer_moore_horspool ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length, k_pattern_length ) {
|
||||
|
||||
// Build the skip table
|
||||
std::size_t i = 0;
|
||||
if ( first != last ) // empty pattern?
|
||||
for ( patIter iter = first; iter != last-1; ++iter, ++i )
|
||||
skip_.insert ( *iter, k_pattern_length - 1 - i );
|
||||
#ifdef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||
skip_.PrintSkipTable ();
|
||||
#endif
|
||||
}
|
||||
|
||||
~boyer_moore_horspool () {}
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param p A predicate used for the search comparisons.
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||
typename std::iterator_traits<patIter>::value_type,
|
||||
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||
|
||||
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||
|
||||
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||
// If the pattern is larger than the corpus, we can't find it!
|
||||
if ( k_corpus_length < k_pattern_length )
|
||||
return corpus_last;
|
||||
|
||||
// Do the search
|
||||
return this->do_search ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
|
||||
return (*this) (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
typename traits::skip_table_t skip_;
|
||||
|
||||
/// \fn do_search ( corpusIter corpus_first, corpusIter corpus_last )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param k_corpus_length The length of the corpus to search
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
corpusIter curPos = corpus_first;
|
||||
const corpusIter lastPos = corpus_last - k_pattern_length;
|
||||
while ( curPos <= lastPos ) {
|
||||
// Do we match right where we are?
|
||||
std::size_t j = k_pattern_length - 1;
|
||||
while ( pat_first [j] == curPos [j] ) {
|
||||
// We matched - we're done!
|
||||
if ( j == 0 )
|
||||
return curPos;
|
||||
j--;
|
||||
}
|
||||
|
||||
curPos += skip_ [ curPos [ k_pattern_length - 1 ]];
|
||||
}
|
||||
|
||||
return corpus_last;
|
||||
}
|
||||
// \endcond
|
||||
};
|
||||
|
||||
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
|
||||
Use a bit of TMP to disambiguate the 3-argument templates */
|
||||
|
||||
/// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter boyer_moore_horspool_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
|
||||
return bmh ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename corpusIter>
|
||||
corpusIter boyer_moore_horspool_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
|
||||
return bmh ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename patIter, typename CorpusRange>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
|
||||
::type
|
||||
boyer_moore_horspool_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
|
||||
return bm (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename CorpusRange>
|
||||
typename boost::range_iterator<CorpusRange>::type
|
||||
boyer_moore_horspool_search ( CorpusRange &corpus, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
|
||||
return bmh (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
|
||||
// Creator functions -- take a pattern range, return an object
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<const Range>::type>
|
||||
make_boyer_moore_horspool ( const Range &r ) {
|
||||
return boost::algorithm::boyer_moore_horspool
|
||||
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<Range>::type>
|
||||
make_boyer_moore_horspool ( Range &r ) {
|
||||
return boost::algorithm::boyer_moore_horspool
|
||||
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
105
3party/boost/boost/algorithm/searching/detail/bm_traits.hpp
Normal file
105
3party/boost/boost/algorithm/searching/detail/bm_traits.hpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2010-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||
#define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||
|
||||
#include <climits> // for CHAR_BIT
|
||||
#include <vector>
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/tr1/tr1/unordered_map>
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
namespace boost { namespace algorithm { namespace detail {
|
||||
|
||||
//
|
||||
// Default implementations of the skip tables for B-M and B-M-H
|
||||
//
|
||||
template<typename key_type, typename value_type, bool /*useArray*/> class skip_table;
|
||||
|
||||
// General case for data searching other than bytes; use a map
|
||||
template<typename key_type, typename value_type>
|
||||
class skip_table<key_type, value_type, false> {
|
||||
private:
|
||||
typedef std::tr1::unordered_map<key_type, value_type> skip_map;
|
||||
const value_type k_default_value;
|
||||
skip_map skip_;
|
||||
|
||||
public:
|
||||
skip_table ( std::size_t patSize, value_type default_value )
|
||||
: k_default_value ( default_value ), skip_ ( patSize ) {}
|
||||
|
||||
void insert ( key_type key, value_type val ) {
|
||||
skip_ [ key ] = val; // Would skip_.insert (val) be better here?
|
||||
}
|
||||
|
||||
value_type operator [] ( key_type key ) const {
|
||||
typename skip_map::const_iterator it = skip_.find ( key );
|
||||
return it == skip_.end () ? k_default_value : it->second;
|
||||
}
|
||||
|
||||
void PrintSkipTable () const {
|
||||
std::cout << "BM(H) Skip Table <unordered_map>:" << std::endl;
|
||||
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||
if ( it->second != k_default_value )
|
||||
std::cout << " " << it->first << ": " << it->second << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Special case small numeric values; use an array
|
||||
template<typename key_type, typename value_type>
|
||||
class skip_table<key_type, value_type, true> {
|
||||
private:
|
||||
typedef typename boost::make_unsigned<key_type>::type unsigned_key_type;
|
||||
typedef boost::array<value_type, 1U << (CHAR_BIT * sizeof(key_type))> skip_map;
|
||||
skip_map skip_;
|
||||
const value_type k_default_value;
|
||||
public:
|
||||
skip_table ( std::size_t patSize, value_type default_value ) : k_default_value ( default_value ) {
|
||||
std::fill_n ( skip_.begin(), skip_.size(), default_value );
|
||||
}
|
||||
|
||||
void insert ( key_type key, value_type val ) {
|
||||
skip_ [ static_cast<unsigned_key_type> ( key ) ] = val;
|
||||
}
|
||||
|
||||
value_type operator [] ( key_type key ) const {
|
||||
return skip_ [ static_cast<unsigned_key_type> ( key ) ];
|
||||
}
|
||||
|
||||
void PrintSkipTable () const {
|
||||
std::cout << "BM(H) Skip Table <boost:array>:" << std::endl;
|
||||
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||
if ( *it != k_default_value )
|
||||
std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct BM_traits {
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::value_type key_type;
|
||||
typedef boost::algorithm::detail::skip_table<key_type, value_type,
|
||||
boost::is_integral<key_type>::value && (sizeof(key_type)==1)> skip_table_t;
|
||||
};
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
30
3party/boost/boost/algorithm/searching/detail/debugging.hpp
Normal file
30
3party/boost/boost/algorithm/searching/detail/debugging.hpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2010-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||
#define BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||
|
||||
#include <iostream>
|
||||
/// \cond DOXYGEN_HIDE
|
||||
|
||||
namespace boost { namespace algorithm { namespace detail {
|
||||
|
||||
// Debugging support
|
||||
template <typename Iter>
|
||||
void PrintTable ( Iter first, Iter last ) {
|
||||
std::cout << std::distance ( first, last ) << ": { ";
|
||||
for ( Iter iter = first; iter != last; ++iter )
|
||||
std::cout << *iter << " ";
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
|
||||
}}}
|
||||
/// \endcond
|
||||
|
||||
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
253
3party/boost/boost/algorithm/searching/knuth_morris_pratt.hpp
Normal file
253
3party/boost/boost/algorithm/searching/knuth_morris_pratt.hpp
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
Copyright (c) Marshall Clow 2010-2012.
|
||||
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
// #define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// #define NEW_KMP
|
||||
|
||||
/*
|
||||
A templated version of the Knuth-Morris-Pratt searching algorithm.
|
||||
|
||||
Requirements:
|
||||
* Random-access iterators
|
||||
* The two iterator types (I1 and I2) must "point to" the same underlying type.
|
||||
|
||||
http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm
|
||||
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm
|
||||
*/
|
||||
|
||||
template <typename patIter>
|
||||
class knuth_morris_pratt {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
knuth_morris_pratt ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length + 1 ) {
|
||||
#ifdef NEW_KMP
|
||||
preKmp ( pat_first, pat_last );
|
||||
#else
|
||||
init_skip_table ( pat_first, pat_last );
|
||||
#endif
|
||||
#ifdef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||
detail::PrintTable ( skip_.begin (), skip_.end ());
|
||||
#endif
|
||||
}
|
||||
|
||||
~knuth_morris_pratt () {}
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param p A predicate used for the search comparisons.
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||
typename std::iterator_traits<patIter>::value_type,
|
||||
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||
|
||||
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||
// If the pattern is larger than the corpus, we can't find it!
|
||||
if ( k_corpus_length < k_pattern_length )
|
||||
return corpus_last;
|
||||
|
||||
return do_search ( corpus_first, corpus_last, k_corpus_length );
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
|
||||
return (*this) (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
std::vector <difference_type> skip_;
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param p A predicate used for the search comparisons.
|
||||
///
|
||||
template <typename corpusIter>
|
||||
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
difference_type k_corpus_length ) const {
|
||||
difference_type match_start = 0; // position in the corpus that we're matching
|
||||
|
||||
#ifdef NEW_KMP
|
||||
int patternIdx = 0;
|
||||
while ( match_start < k_corpus_length ) {
|
||||
while ( patternIdx > -1 && pat_first[patternIdx] != corpus_first [match_start] )
|
||||
patternIdx = skip_ [patternIdx]; //<--- Shifting the pattern on mismatch
|
||||
|
||||
patternIdx++;
|
||||
match_start++; //<--- corpus is always increased by 1
|
||||
|
||||
if ( patternIdx >= (int) k_pattern_length )
|
||||
return corpus_first + match_start - patternIdx;
|
||||
}
|
||||
|
||||
#else
|
||||
// At this point, we know:
|
||||
// k_pattern_length <= k_corpus_length
|
||||
// for all elements of skip, it holds -1 .. k_pattern_length
|
||||
//
|
||||
// In the loop, we have the following invariants
|
||||
// idx is in the range 0 .. k_pattern_length
|
||||
// match_start is in the range 0 .. k_corpus_length - k_pattern_length + 1
|
||||
|
||||
const difference_type last_match = k_corpus_length - k_pattern_length;
|
||||
difference_type idx = 0; // position in the pattern we're comparing
|
||||
|
||||
while ( match_start <= last_match ) {
|
||||
while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) {
|
||||
if ( ++idx == k_pattern_length )
|
||||
return corpus_first + match_start;
|
||||
}
|
||||
// Figure out where to start searching again
|
||||
// assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward
|
||||
match_start += idx - skip_ [ idx ];
|
||||
idx = skip_ [ idx ] >= 0 ? skip_ [ idx ] : 0;
|
||||
// assert ( idx >= 0 && idx < k_pattern_length );
|
||||
}
|
||||
#endif
|
||||
|
||||
// We didn't find anything
|
||||
return corpus_last;
|
||||
}
|
||||
|
||||
|
||||
void preKmp ( patIter first, patIter last ) {
|
||||
const /*std::size_t*/ int count = std::distance ( first, last );
|
||||
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
j = skip_[0] = -1;
|
||||
while (i < count) {
|
||||
while (j > -1 && first[i] != first[j])
|
||||
j = skip_[j];
|
||||
i++;
|
||||
j++;
|
||||
if (first[i] == first[j])
|
||||
skip_[i] = skip_[j];
|
||||
else
|
||||
skip_[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_skip_table ( patIter first, patIter last ) {
|
||||
const difference_type count = std::distance ( first, last );
|
||||
|
||||
int j;
|
||||
skip_ [ 0 ] = -1;
|
||||
for ( int i = 1; i <= count; ++i ) {
|
||||
j = skip_ [ i - 1 ];
|
||||
while ( j >= 0 ) {
|
||||
if ( first [ j ] == first [ i - 1 ] )
|
||||
break;
|
||||
j = skip_ [ j ];
|
||||
}
|
||||
skip_ [ i ] = j + 1;
|
||||
}
|
||||
}
|
||||
// \endcond
|
||||
};
|
||||
|
||||
|
||||
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
|
||||
Use a bit of TMP to disambiguate the 3-argument templates */
|
||||
|
||||
/// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||
/// \param corpus_last One past the end of the data to search
|
||||
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter knuth_morris_pratt_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last )
|
||||
{
|
||||
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
|
||||
return kmp ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename corpusIter>
|
||||
corpusIter knuth_morris_pratt_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
|
||||
return kmp ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename patIter, typename CorpusRange>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
|
||||
::type
|
||||
knuth_morris_pratt_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
|
||||
{
|
||||
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
|
||||
return kmp (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename CorpusRange>
|
||||
typename boost::range_iterator<CorpusRange>::type
|
||||
knuth_morris_pratt_search ( CorpusRange &corpus, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
|
||||
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
|
||||
return kmp (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
|
||||
// Creator functions -- take a pattern range, return an object
|
||||
template <typename Range>
|
||||
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<const Range>::type>
|
||||
make_knuth_morris_pratt ( const Range &r ) {
|
||||
return boost::algorithm::knuth_morris_pratt
|
||||
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<Range>::type>
|
||||
make_knuth_morris_pratt ( Range &r ) {
|
||||
return boost::algorithm::knuth_morris_pratt
|
||||
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
|
@ -15,6 +15,8 @@
|
|||
#include <locale>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
namespace detail {
|
||||
|
@ -37,7 +39,7 @@ namespace boost {
|
|||
CharT operator ()( CharT Ch ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::tolower( Ch);
|
||||
return std::tolower( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
|
||||
#else
|
||||
return std::tolower<CharT>( Ch, *m_Loc );
|
||||
#endif
|
||||
|
@ -57,7 +59,7 @@ namespace boost {
|
|||
CharT operator ()( CharT Ch ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::toupper( Ch);
|
||||
return std::toupper( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
|
||||
#else
|
||||
return std::toupper<CharT>( Ch, *m_Loc );
|
||||
#endif
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace boost {
|
|||
}
|
||||
|
||||
// Use fixed storage
|
||||
::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -206,7 +206,7 @@ namespace boost {
|
|||
}
|
||||
|
||||
// Copy the data
|
||||
::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -228,13 +228,13 @@ namespace boost {
|
|||
//! Find head algorithm
|
||||
/*!
|
||||
Get the head of the input. Head is a prefix of the string of the
|
||||
given size. If the input is shorter then required, whole input if considered
|
||||
given size. If the input is shorter then required, whole input is considered
|
||||
to be the head.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the head
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
For N<0, at most size(Input)-|N| characters are extracted.
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
Returned iterator is either \c Range1T::iterator or
|
||||
|
@ -258,13 +258,13 @@ namespace boost {
|
|||
//! Find tail algorithm
|
||||
/*!
|
||||
Get the tail of the input. Tail is a suffix of the string of the
|
||||
given size. If the input is shorter then required, whole input if considered
|
||||
given size. If the input is shorter then required, whole input is considered
|
||||
to be the tail.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the tail.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
For N<0, at most size(Input)-|N| characters are extracted.
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
Returned iterator is either \c RangeT::iterator or
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace boost {
|
|||
a match).
|
||||
\param Input A container which will be searched.
|
||||
\param Finder A Finder object used for searching
|
||||
\return A reference the result
|
||||
\return A reference to the result
|
||||
|
||||
\note Prior content of the result will be overwritten.
|
||||
*/
|
||||
|
@ -122,7 +122,7 @@ namespace boost {
|
|||
Each match is used as a separator of segments. These segments are then
|
||||
returned in the result.
|
||||
|
||||
\param Result A 'container container' to container the result of search.
|
||||
\param Result A 'container container' to contain the result of search.
|
||||
Both outer and inner container must have constructor taking a pair
|
||||
of iterators as an argument.
|
||||
Typical type of the result is
|
||||
|
@ -131,7 +131,7 @@ namespace boost {
|
|||
a match).
|
||||
\param Input A container which will be searched.
|
||||
\param Finder A finder object used for searching
|
||||
\return A reference the result
|
||||
\return A reference to the result
|
||||
|
||||
\note Prior content of the result will be overwritten.
|
||||
*/
|
||||
|
|
|
@ -150,7 +150,8 @@ private:
|
|||
base_type t;
|
||||
public:
|
||||
object_id_type(): t(0) {};
|
||||
explicit object_id_type(const unsigned int & t_) : t(t_){
|
||||
// note: presumes that size_t >= unsigned int.
|
||||
explicit object_id_type(const std::size_t & t_) : t(t_){
|
||||
BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max);
|
||||
}
|
||||
object_id_type(const object_id_type & t_) :
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <set>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace std{
|
|||
|
||||
#define DONT_USE_HAS_NEW_OPERATOR ( \
|
||||
defined(__BORLANDC__) \
|
||||
|| defined(__IBMCPP__) \
|
||||
|| BOOST_WORKAROUND(__IBMCPP__, < 1210) \
|
||||
|| defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) \
|
||||
|| defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \
|
||||
)
|
||||
|
|
|
@ -39,7 +39,7 @@ template<class CharType>
|
|||
struct to_6_bit {
|
||||
typedef CharType result_type;
|
||||
CharType operator()(CharType t) const{
|
||||
const char lookup_table[] = {
|
||||
const signed char lookup_table[] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
|
||||
|
|
|
@ -42,8 +42,8 @@ private:
|
|||
> super_t;
|
||||
|
||||
typedef head_iterator<Predicate, Base> this_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME super_t::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME super_t::reference reference_type;
|
||||
typedef super_t::value_type value_type;
|
||||
typedef super_t::reference reference_type;
|
||||
|
||||
reference_type dereference_impl(){
|
||||
if(! m_end){
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
//#include <boost/detail/workaround.hpp>
|
||||
//#if ! BOOST_WORKAROUND(BOOST_MSVC, <=1300)
|
||||
|
@ -140,13 +141,19 @@ public:
|
|||
template<class Base>
|
||||
class remove_whitespace :
|
||||
public filter_iterator<
|
||||
remove_whitespace_predicate<BOOST_DEDUCED_TYPENAME Base::value_type>,
|
||||
remove_whitespace_predicate<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
|
||||
//BOOST_DEDUCED_TYPENAME Base::value_type
|
||||
>,
|
||||
Base
|
||||
>
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
typedef filter_iterator<
|
||||
remove_whitespace_predicate<BOOST_DEDUCED_TYPENAME Base::value_type>,
|
||||
remove_whitespace_predicate<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
|
||||
//BOOST_DEDUCED_TYPENAME Base::value_type
|
||||
>,
|
||||
Base
|
||||
> super_t;
|
||||
public:
|
||||
|
|
|
@ -127,7 +127,7 @@ public:
|
|||
template<class T>
|
||||
struct non_polymorphic {
|
||||
static const boost::serialization::extended_type_info *
|
||||
get_object_identifier(T & t){
|
||||
get_object_identifier(T &){
|
||||
return & boost::serialization::singleton<
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
boost::serialization::type_info_implementation< T >::type
|
||||
|
|
|
@ -126,8 +126,7 @@ public:
|
|||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4511 4512)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* 14 Apr 2012 - (mtc) Added support for boost::hash
|
||||
* 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
|
||||
* 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
|
||||
* See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168
|
||||
|
@ -46,6 +47,7 @@
|
|||
// Handles broken standard libraries better than <iterator>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
// FIXES for broken compilers
|
||||
|
@ -118,13 +120,13 @@ namespace boost {
|
|||
// operator[]
|
||||
reference operator[](size_type i)
|
||||
{
|
||||
BOOST_ASSERT( i < N && "out of range" );
|
||||
BOOST_ASSERT_MSG( i < N, "out of range" );
|
||||
return elems[i];
|
||||
}
|
||||
|
||||
const_reference operator[](size_type i) const
|
||||
{
|
||||
BOOST_ASSERT( i < N && "out of range" );
|
||||
BOOST_ASSERT_MSG( i < N, "out of range" );
|
||||
return elems[i];
|
||||
}
|
||||
|
||||
|
@ -427,6 +429,13 @@ namespace boost {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<class T, std::size_t N>
|
||||
std::size_t hash_value(const array<T,N>& arr)
|
||||
{
|
||||
return boost::hash_range(arr.begin(), arr.end());
|
||||
}
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// asio.hpp
|
||||
// ~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -29,6 +29,7 @@
|
|||
#include <boost/asio/basic_socket_streambuf.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <boost/asio/basic_streambuf.hpp>
|
||||
#include <boost/asio/basic_waitable_timer.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/buffered_read_stream_fwd.hpp>
|
||||
#include <boost/asio/buffered_read_stream.hpp>
|
||||
|
@ -92,9 +93,14 @@
|
|||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/asio/time_traits.hpp>
|
||||
#include <boost/asio/version.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_random_access_handle.hpp>
|
||||
#include <boost/asio/windows/basic_stream_handle.hpp>
|
||||
#include <boost/asio/windows/object_handle.hpp>
|
||||
#include <boost/asio/windows/object_handle_service.hpp>
|
||||
#include <boost/asio/windows/overlapped_ptr.hpp>
|
||||
#include <boost/asio/windows/random_access_handle.hpp>
|
||||
#include <boost/asio/windows/random_access_handle_service.hpp>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_datagram_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_io_object.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_raw_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_seq_packet_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_serial_port.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_signal_set.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_socket_acceptor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_socket_iostream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -53,7 +53,7 @@
|
|||
basic_socket_streambuf<Protocol, StreamSocketService, \
|
||||
Time, TimeTraits, TimerService> >::member) \
|
||||
{ \
|
||||
tie(this); \
|
||||
this->setf(std::ios_base::unitbuf); \
|
||||
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
|
||||
this->setstate(std::ios_base::failbit); \
|
||||
} \
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService> >::member)
|
||||
{
|
||||
tie(this);
|
||||
this->setf(std::ios_base::unitbuf);
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
|
@ -131,7 +131,7 @@ public:
|
|||
basic_socket_streambuf<Protocol, StreamSocketService,
|
||||
Time, TimeTraits, TimerService> >::member)
|
||||
{
|
||||
tie(this);
|
||||
this->setf(std::ios_base::unitbuf);
|
||||
if (rdbuf()->connect(x...) == 0)
|
||||
this->setstate(std::ios_base::failbit);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_socket_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_stream_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// basic_streambuf_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
518
3party/boost/boost/asio/basic_waitable_timer.hpp
Normal file
518
3party/boost/boost/asio/basic_waitable_timer.hpp
Normal file
|
@ -0,0 +1,518 @@
|
|||
//
|
||||
// basic_waitable_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2012 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_BASIC_WAITABLE_TIMER_HPP
|
||||
#define BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/asio/basic_io_object.hpp>
|
||||
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||
#include <boost/asio/detail/throw_error.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/wait_traits.hpp>
|
||||
#include <boost/asio/waitable_timer_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
/// Provides waitable timer functionality.
|
||||
/**
|
||||
* The basic_waitable_timer class template provides the ability to perform a
|
||||
* blocking or asynchronous wait for a timer to expire.
|
||||
*
|
||||
* A waitable timer is always in one of two states: "expired" or "not expired".
|
||||
* If the wait() or async_wait() function is called on an expired timer, the
|
||||
* wait operation will complete immediately.
|
||||
*
|
||||
* Most applications will use the boost::asio::waitable_timer typedef.
|
||||
*
|
||||
* @note This waitable timer functionality is for use with the C++11 standard
|
||||
* library's @c <chrono> facility, or with the Boost.Chrono library.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Examples
|
||||
* Performing a blocking wait:
|
||||
* @code
|
||||
* // Construct a timer without setting an expiry time.
|
||||
* boost::asio::waitable_timer timer(io_service);
|
||||
*
|
||||
* // Set an expiry time relative to now.
|
||||
* timer.expires_from_now(boost::posix_time::seconds(5));
|
||||
*
|
||||
* // Wait for the timer to expire.
|
||||
* timer.wait();
|
||||
* @endcode
|
||||
*
|
||||
* @par
|
||||
* Performing an asynchronous wait:
|
||||
* @code
|
||||
* void handler(const boost::system::error_code& error)
|
||||
* {
|
||||
* if (!error)
|
||||
* {
|
||||
* // Timer expired.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // Construct a timer with an absolute expiry time.
|
||||
* boost::asio::waitable_timer timer(io_service,
|
||||
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
|
||||
*
|
||||
* // Start an asynchronous wait.
|
||||
* timer.async_wait(handler);
|
||||
* @endcode
|
||||
*
|
||||
* @par Changing an active waitable_timer's expiry time
|
||||
*
|
||||
* Changing the expiry time of a timer while there are pending asynchronous
|
||||
* waits causes those wait operations to be cancelled. To ensure that the action
|
||||
* associated with the timer is performed only once, use something like this:
|
||||
* used:
|
||||
*
|
||||
* @code
|
||||
* void on_some_event()
|
||||
* {
|
||||
* if (my_timer.expires_from_now(seconds(5)) > 0)
|
||||
* {
|
||||
* // We managed to cancel the timer. Start new asynchronous wait.
|
||||
* my_timer.async_wait(on_timeout);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Too late, timer has already expired!
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* void on_timeout(const boost::system::error_code& e)
|
||||
* {
|
||||
* if (e != boost::asio::error::operation_aborted)
|
||||
* {
|
||||
* // Timer was not cancelled, take necessary action.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @li The boost::asio::basic_waitable_timer::expires_from_now() function
|
||||
* cancels any pending asynchronous waits, and returns the number of
|
||||
* asynchronous waits that were cancelled. If it returns 0 then you were too
|
||||
* late and the wait handler has already been executed, or will soon be
|
||||
* executed. If it returns 1 then the wait handler was successfully cancelled.
|
||||
*
|
||||
* @li If a wait handler is cancelled, the boost::system::error_code passed to
|
||||
* it contains the value boost::asio::error::operation_aborted.
|
||||
*/
|
||||
template <typename Clock,
|
||||
typename WaitTraits = boost::asio::wait_traits<Clock>,
|
||||
typename WaitableTimerService = waitable_timer_service<Clock, WaitTraits> >
|
||||
class basic_waitable_timer
|
||||
: public basic_io_object<WaitableTimerService>
|
||||
{
|
||||
public:
|
||||
/// The clock type.
|
||||
typedef Clock clock_type;
|
||||
|
||||
/// The duration type of the clock.
|
||||
typedef typename clock_type::duration duration;
|
||||
|
||||
/// The time point type of the clock.
|
||||
typedef typename clock_type::time_point time_point;
|
||||
|
||||
/// The wait traits type.
|
||||
typedef WaitTraits traits_type;
|
||||
|
||||
/// 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 io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*/
|
||||
explicit basic_waitable_timer(boost::asio::io_service& io_service)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time as an absolute 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
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
basic_waitable_timer(boost::asio::io_service& io_service,
|
||||
const time_point& expiry_time)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time relative to now.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
basic_waitable_timer(boost::asio::io_service& io_service,
|
||||
const duration& expiry_time)
|
||||
: basic_io_object<WaitableTimerService>(io_service)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.expires_from_now(this->implementation, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
* operations against the timer. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*
|
||||
* @note If the timer has already expired when cancel() is called, then the
|
||||
* handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t cancel()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel(this->implementation, ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
* operations against the timer. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @note If the timer has already expired when cancel() is called, then the
|
||||
* handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t cancel(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Cancels one asynchronous operation that is waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of one pending asynchronous wait
|
||||
* operation against the timer. Handlers are cancelled in FIFO order. The
|
||||
* handler for the cancelled operation will be invoked with the
|
||||
* boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled. That is,
|
||||
* either 0 or 1.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*
|
||||
* @note If the timer has already expired when cancel_one() is called, then
|
||||
* the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t cancel_one()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.cancel_one(this->implementation, ec);
|
||||
boost::asio::detail::throw_error(ec, "cancel_one");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Cancels one asynchronous operation that is waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of one pending asynchronous wait
|
||||
* operation against the timer. Handlers are cancelled in FIFO order. The
|
||||
* handler for the cancelled operation will be invoked with the
|
||||
* boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled. That is,
|
||||
* either 0 or 1.
|
||||
*
|
||||
* @note If the timer has already expired when cancel_one() is called, then
|
||||
* the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t cancel_one(boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.cancel_one(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
time_point expires_at() const
|
||||
{
|
||||
return this->service.expires_at(this->implementation);
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*
|
||||
* @note If the timer has already expired when expires_at() is called, then
|
||||
* the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t expires_at(const time_point& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_at(
|
||||
this->implementation, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_at");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @note If the timer has already expired when expires_at() is called, then
|
||||
* the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t expires_at(const time_point& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
duration expires_from_now() const
|
||||
{
|
||||
return this->service.expires_from_now(this->implementation);
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*
|
||||
* @note If the timer has already expired when expires_from_now() is called,
|
||||
* then the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t expires_from_now(const duration& expiry_time)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
std::size_t s = this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
boost::asio::detail::throw_error(ec, "expires_from_now");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the boost::asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @note If the timer has already expired when expires_from_now() is called,
|
||||
* then the handlers for asynchronous wait operations will:
|
||||
*
|
||||
* @li have already been invoked; or
|
||||
*
|
||||
* @li have been queued for invocation in the near future.
|
||||
*
|
||||
* These handlers can no longer be cancelled, and therefore are passed an
|
||||
* error code that indicates the successful completion of the wait operation.
|
||||
*/
|
||||
std::size_t expires_from_now(const duration& expiry_time,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
return this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
/**
|
||||
* This function is used to wait for the timer to expire. This function
|
||||
* blocks and does not return until the timer has expired.
|
||||
*
|
||||
* @throws boost::system::system_error Thrown on failure.
|
||||
*/
|
||||
void wait()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
this->service.wait(this->implementation, ec);
|
||||
boost::asio::detail::throw_error(ec, "wait");
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
/**
|
||||
* This function is used to wait for the timer to expire. This function
|
||||
* blocks and does not return until the timer has expired.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
void wait(boost::system::error_code& ec)
|
||||
{
|
||||
this->service.wait(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous wait on the timer.
|
||||
/**
|
||||
* This function may be used to initiate an asynchronous wait against the
|
||||
* timer. It always returns immediately.
|
||||
*
|
||||
* For each call to async_wait(), the supplied handler will be called exactly
|
||||
* once. The handler will be called when:
|
||||
*
|
||||
* @li The timer has expired.
|
||||
*
|
||||
* @li The timer was cancelled, in which case the handler is passed the error
|
||||
* code boost::asio::error::operation_aborted.
|
||||
*
|
||||
* @param handler The handler to be called when the timer expires. Copies
|
||||
* will be made of the handler as required. The function signature of the
|
||||
* handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* boost::asio::io_service::post().
|
||||
*/
|
||||
template <typename WaitHandler>
|
||||
void async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
|
||||
{
|
||||
// If you get an error on the following line it means that your handler does
|
||||
// not meet the documented type requirements for a WaitHandler.
|
||||
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
|
||||
|
||||
this->service.async_wait(this->implementation,
|
||||
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
|
|
@ -2,7 +2,7 @@
|
|||
// buffer.hpp
|
||||
// ~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_read_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_read_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_write_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
? bytes_avail : space_avail;
|
||||
storage_.resize(orig_size + length);
|
||||
std::size_t bytes_copied = boost::asio::buffer_copy(
|
||||
storage_.data(), buffers_, length);
|
||||
storage_.data() + orig_size, buffers_, length);
|
||||
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
|
||||
}
|
||||
|
@ -335,7 +335,8 @@ private:
|
|||
std::size_t bytes_avail = boost::asio::buffer_size(buffers);
|
||||
std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail;
|
||||
storage_.resize(orig_size + length);
|
||||
return boost::asio::buffer_copy(storage_.data(), buffers, length);
|
||||
return boost::asio::buffer_copy(
|
||||
storage_.data() + orig_size, buffers, length);
|
||||
}
|
||||
|
||||
/// The next layer.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffered_write_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// buffers_iterator.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -128,7 +128,7 @@ public:
|
|||
/// Construct an iterator representing the beginning of the buffers' data.
|
||||
static buffers_iterator begin(const BufferSequence& buffers)
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 4) && BOOST_WORKAROUND(__GNUC_MINOR__, == 3)
|
||||
__attribute__ ((noinline))
|
||||
__attribute__ ((__noinline__))
|
||||
#endif
|
||||
{
|
||||
buffers_iterator new_iter;
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
/// Construct an iterator representing the end of the buffers' data.
|
||||
static buffers_iterator end(const BufferSequence& buffers)
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 4) && BOOST_WORKAROUND(__GNUC_MINOR__, == 3)
|
||||
__attribute__ ((noinline))
|
||||
__attribute__ ((__noinline__))
|
||||
#endif
|
||||
{
|
||||
buffers_iterator new_iter;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// completion_condition.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// connect.hpp
|
||||
// ~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// datagram_socket_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include <boost/asio/detail/deadline_timer_service.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/time_traits.hpp>
|
||||
#include <boost/asio/detail/timer_queue_ptime.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/array.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/array_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/atomic_count.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -17,7 +17,9 @@
|
|||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
|
||||
// Nothing to include.
|
||||
#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
# include <atomic>
|
||||
#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
# include <boost/detail/atomic_count.hpp>
|
||||
|
@ -27,10 +29,15 @@ namespace boost {
|
|||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
|
||||
typedef long atomic_count;
|
||||
inline void increment(atomic_count& a, long b) { a += b; }
|
||||
#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
typedef std::atomic<long> atomic_count;
|
||||
inline void increment(atomic_count& a, long b) { a += b; }
|
||||
#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
typedef boost::detail::atomic_count atomic_count;
|
||||
inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/base_from_completion_cond.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/bind_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/buffer_resize_guard.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/buffer_sequence_adapter.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/detail/array_fwd.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
@ -247,6 +248,114 @@ private:
|
|||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
template <typename Buffer, typename Elem>
|
||||
class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
|
||||
: buffer_sequence_adapter_base
|
||||
{
|
||||
public:
|
||||
explicit buffer_sequence_adapter(
|
||||
const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
|
||||
init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
|
||||
+ boost::asio::buffer_size(buffer_sequence[1]);
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
{
|
||||
return buffers_;
|
||||
}
|
||||
|
||||
std::size_t count() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
}
|
||||
|
||||
static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence[0]) == 0
|
||||
&& boost::asio::buffer_size(buffer_sequence[1]) == 0;
|
||||
}
|
||||
|
||||
static void validate(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
|
||||
}
|
||||
|
||||
static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
|
||||
? buffer_sequence[0] : buffer_sequence[1]);
|
||||
}
|
||||
|
||||
private:
|
||||
native_buffer_type buffers_[2];
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
template <typename Buffer, typename Elem>
|
||||
class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
|
||||
: buffer_sequence_adapter_base
|
||||
{
|
||||
public:
|
||||
explicit buffer_sequence_adapter(
|
||||
const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
|
||||
init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
|
||||
total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
|
||||
+ boost::asio::buffer_size(buffer_sequence[1]);
|
||||
}
|
||||
|
||||
native_buffer_type* buffers()
|
||||
{
|
||||
return buffers_;
|
||||
}
|
||||
|
||||
std::size_t count() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool all_empty() const
|
||||
{
|
||||
return total_buffer_size_ == 0;
|
||||
}
|
||||
|
||||
static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return boost::asio::buffer_size(buffer_sequence[0]) == 0
|
||||
&& boost::asio::buffer_size(buffer_sequence[1]) == 0;
|
||||
}
|
||||
|
||||
static void validate(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
|
||||
boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
|
||||
}
|
||||
|
||||
static Buffer first(const std::array<Elem, 2>& buffer_sequence)
|
||||
{
|
||||
return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
|
||||
? buffer_sequence[0] : buffer_sequence[1]);
|
||||
}
|
||||
|
||||
private:
|
||||
native_buffer_type buffers_[2];
|
||||
std::size_t total_buffer_size_;
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/buffered_stream_storage.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/call_stack.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -27,34 +27,60 @@ namespace detail {
|
|||
|
||||
// Helper class to determine whether or not the current thread is inside an
|
||||
// invocation of io_service::run() for a specified io_service object.
|
||||
template <typename Owner>
|
||||
template <typename Key, typename Value = unsigned char>
|
||||
class call_stack
|
||||
{
|
||||
public:
|
||||
// Context class automatically pushes an owner on to the stack.
|
||||
// Context class automatically pushes the key/value pair on to the stack.
|
||||
class context
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Push the owner on to the stack.
|
||||
explicit context(Owner* d)
|
||||
: owner_(d),
|
||||
next_(call_stack<Owner>::top_)
|
||||
// Push the key on to the stack.
|
||||
explicit context(Key* k)
|
||||
: key_(k),
|
||||
next_(call_stack<Key, Value>::top_)
|
||||
{
|
||||
call_stack<Owner>::top_ = this;
|
||||
value_ = reinterpret_cast<unsigned char*>(this);
|
||||
call_stack<Key, Value>::top_ = this;
|
||||
}
|
||||
|
||||
// Pop the owner from the stack.
|
||||
// Push the key/value pair on to the stack.
|
||||
context(Key* k, Value& v)
|
||||
: key_(k),
|
||||
value_(&v),
|
||||
next_(call_stack<Key, Value>::top_)
|
||||
{
|
||||
call_stack<Key, Value>::top_ = this;
|
||||
}
|
||||
|
||||
// Pop the key/value pair from the stack.
|
||||
~context()
|
||||
{
|
||||
call_stack<Owner>::top_ = next_;
|
||||
call_stack<Key, Value>::top_ = next_;
|
||||
}
|
||||
|
||||
// Find the next context with the same key.
|
||||
Value* next_by_key() const
|
||||
{
|
||||
context* elem = next_;
|
||||
while (elem)
|
||||
{
|
||||
if (elem->key_ == key_)
|
||||
return elem->value_;
|
||||
elem = elem->next_;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class call_stack<Owner>;
|
||||
friend class call_stack<Key, Value>;
|
||||
|
||||
// The owner associated with the context.
|
||||
Owner* owner_;
|
||||
// The key associated with the context.
|
||||
Key* key_;
|
||||
|
||||
// The value associated with the context.
|
||||
Value* value_;
|
||||
|
||||
// The next element in the stack.
|
||||
context* next_;
|
||||
|
@ -62,17 +88,18 @@ public:
|
|||
|
||||
friend class context;
|
||||
|
||||
// Determine whether the specified owner is on the stack.
|
||||
static bool contains(Owner* d)
|
||||
// Determine whether the specified owner is on the stack. Returns address of
|
||||
// key if present, 0 otherwise.
|
||||
static Value* contains(Key* k)
|
||||
{
|
||||
context* elem = top_;
|
||||
while (elem)
|
||||
{
|
||||
if (elem->owner_ == d)
|
||||
return true;
|
||||
if (elem->key_ == k)
|
||||
return elem->value_;
|
||||
elem = elem->next_;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -80,9 +107,9 @@ private:
|
|||
static tss_ptr<context> top_;
|
||||
};
|
||||
|
||||
template <typename Owner>
|
||||
tss_ptr<typename call_stack<Owner>::context>
|
||||
call_stack<Owner>::top_;
|
||||
template <typename Key, typename Value>
|
||||
tss_ptr<typename call_stack<Key, Value>::context>
|
||||
call_stack<Key, Value>::top_;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
|
129
3party/boost/boost/asio/detail/chrono_time_traits.hpp
Normal file
129
3party/boost/boost/asio/detail/chrono_time_traits.hpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
//
|
||||
// detail/chrono_time_traits.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2012 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_DETAIL_CHRONO_TIME_TRAITS_HPP
|
||||
#define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Adapts std::chrono clocks for use with a deadline timer.
|
||||
template <typename Clock, typename WaitTraits>
|
||||
struct chrono_time_traits
|
||||
{
|
||||
// The clock type.
|
||||
typedef Clock clock_type;
|
||||
|
||||
// The duration type of the clock.
|
||||
typedef typename clock_type::duration duration_type;
|
||||
|
||||
// The time point type of the clock.
|
||||
typedef typename clock_type::time_point time_type;
|
||||
|
||||
// The period of the clock.
|
||||
typedef typename duration_type::period period_type;
|
||||
|
||||
// Get the current time.
|
||||
static time_type now()
|
||||
{
|
||||
return clock_type::now();
|
||||
}
|
||||
|
||||
// Add a duration to a time.
|
||||
static time_type add(const time_type& t, const duration_type& d)
|
||||
{
|
||||
return t + d;
|
||||
}
|
||||
|
||||
// Subtract one time from another.
|
||||
static duration_type subtract(const time_type& t1, const time_type& t2)
|
||||
{
|
||||
return t1 - t2;
|
||||
}
|
||||
|
||||
// Test whether one time is less than another.
|
||||
static bool less_than(const time_type& t1, const time_type& t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
}
|
||||
|
||||
// Implement just enough of the posix_time::time_duration interface to supply
|
||||
// what the timer_queue requires.
|
||||
class posix_time_duration
|
||||
{
|
||||
public:
|
||||
explicit posix_time_duration(const duration_type& d)
|
||||
: d_(d)
|
||||
{
|
||||
}
|
||||
|
||||
boost::int64_t ticks() const
|
||||
{
|
||||
return d_.count();
|
||||
}
|
||||
|
||||
boost::int64_t total_seconds() const
|
||||
{
|
||||
return duration_cast<1, 1>();
|
||||
}
|
||||
|
||||
boost::int64_t total_milliseconds() const
|
||||
{
|
||||
return duration_cast<1, 1000>();
|
||||
}
|
||||
|
||||
boost::int64_t total_microseconds() const
|
||||
{
|
||||
return duration_cast<1, 1000000>();
|
||||
}
|
||||
|
||||
private:
|
||||
template <boost::int64_t Num, boost::int64_t Den>
|
||||
boost::int64_t duration_cast() const
|
||||
{
|
||||
const boost::int64_t num = period_type::num * Den;
|
||||
const boost::int64_t den = period_type::den * Num;
|
||||
|
||||
if (num == 1 && den == 1)
|
||||
return ticks();
|
||||
else if (num != 1 && den == 1)
|
||||
return ticks() * num;
|
||||
else if (num == 1 && period_type::den != 1)
|
||||
return ticks() / den;
|
||||
else
|
||||
return ticks() * num / den;
|
||||
}
|
||||
|
||||
duration_type d_;
|
||||
};
|
||||
|
||||
// Convert to POSIX duration type.
|
||||
static posix_time_duration to_posix_duration(const duration_type& d)
|
||||
{
|
||||
return posix_time_duration(WaitTraits::to_wait_duration(d));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
|
|
@ -2,7 +2,7 @@
|
|||
// detail/completion_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -40,7 +40,8 @@ public:
|
|||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
completion_handler* h(static_cast<completion_handler*>(base));
|
||||
|
@ -61,7 +62,7 @@ public:
|
|||
// Make the upcall if required.
|
||||
if (owner)
|
||||
{
|
||||
boost::asio::detail::fenced_block b;
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/config.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -12,6 +12,7 @@
|
|||
#define BOOST_ASIO_DETAIL_CONFIG_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// Default to a header-only implementation. The user must specifically request
|
||||
// separate compilation by defining either BOOST_ASIO_SEPARATE_COMPILATION or
|
||||
|
@ -111,6 +112,20 @@
|
|||
# endif // defined(__GNUC__)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
|
||||
|
||||
// Compliant C++11 compilers put noexcept specifiers on error_category members.
|
||||
#if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
# if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
|
||||
# define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT
|
||||
# endif // !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
|
||||
#endif // !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
|
||||
|
||||
// Standard library support for arrays.
|
||||
#if !defined(BOOST_ASIO_DISABLE_STD_ARRAY)
|
||||
# if defined(__GNUC__)
|
||||
|
@ -154,6 +169,29 @@
|
|||
# endif // defined(__GNUC__)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_STD_ATOMIC)
|
||||
|
||||
// Standard library support for chrono. Some standard libraries (such as the
|
||||
// libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x
|
||||
// drafts, rather than the eventually standardised name of steady_clock.
|
||||
#if !defined(BOOST_ASIO_DISABLE_STD_CHRONO)
|
||||
# if defined(__GNUC__)
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define BOOST_ASIO_HAS_STD_CHRONO
|
||||
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))
|
||||
# define BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))
|
||||
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
|
||||
# endif // defined(__GNUC__)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_STD_CHRONO)
|
||||
|
||||
// Boost support for chrono.
|
||||
#if !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
|
||||
# if (BOOST_VERSION >= 104700)
|
||||
# define BOOST_ASIO_HAS_BOOST_CHRONO
|
||||
# endif // (BOOST_VERSION >= 104700)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
|
||||
|
||||
// Windows: target OS version.
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
|
||||
|
@ -289,6 +327,15 @@
|
|||
# endif // defined(BOOST_ASIO_HAS_IOCP)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
|
||||
|
||||
// Windows: object handles.
|
||||
#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)
|
||||
# if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# if !defined(UNDER_CE)
|
||||
# define BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE 1
|
||||
# endif // !defined(UNDER_CE)
|
||||
# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)
|
||||
|
||||
// Windows: OVERLAPPED wrapper.
|
||||
#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
|
||||
# if defined(BOOST_ASIO_HAS_IOCP)
|
||||
|
@ -324,4 +371,19 @@
|
|||
# endif // !defined(UNDER_CE)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_SIGNAL)
|
||||
|
||||
// Support for the __thread keyword extension.
|
||||
#if !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
|
||||
# if defined(__linux__)
|
||||
# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
|
||||
# if !defined(__INTEL_COMPILER) && !defined(__ICL)
|
||||
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
|
||||
# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
|
||||
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
|
||||
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
|
||||
# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
|
||||
# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# endif // defined(__linux__)
|
||||
#endif // !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_CONFIG_HPP
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/consuming_buffers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
34
3party/boost/boost/asio/detail/date_time_fwd.hpp
Normal file
34
3party/boost/boost/asio/detail/date_time_fwd.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// detail/date_time_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2012 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_DETAIL_DATE_TIME_FWD_HPP
|
||||
#define BOOST_ASIO_DETAIL_DATE_TIME_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace date_time {
|
||||
|
||||
template<class T, class TimeSystem>
|
||||
class base_time;
|
||||
|
||||
} // namespace date_time
|
||||
namespace posix_time {
|
||||
|
||||
class ptime;
|
||||
|
||||
} // namespace posix_time
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_DATE_TIME_FWD_HPP
|
|
@ -2,7 +2,7 @@
|
|||
// detail/deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -24,14 +24,10 @@
|
|||
#include <boost/asio/detail/noncopyable.hpp>
|
||||
#include <boost/asio/detail/socket_ops.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
#include <boost/asio/detail/timer_op.hpp>
|
||||
#include <boost/asio/detail/timer_queue.hpp>
|
||||
#include <boost/asio/detail/timer_scheduler.hpp>
|
||||
#include <boost/asio/detail/wait_handler.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
|
@ -166,12 +162,8 @@ public:
|
|||
ec = boost::system::error_code();
|
||||
while (Time_Traits::less_than(now, impl.expiry) && !ec)
|
||||
{
|
||||
boost::posix_time::time_duration timeout =
|
||||
Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now));
|
||||
::timeval tv;
|
||||
tv.tv_sec = timeout.total_seconds();
|
||||
tv.tv_usec = timeout.total_microseconds() % 1000000;
|
||||
socket_ops::select(0, 0, 0, 0, &tv, ec);
|
||||
this->do_wait(Time_Traits::to_posix_duration(
|
||||
Time_Traits::subtract(impl.expiry, now)), ec);
|
||||
now = Time_Traits::now();
|
||||
}
|
||||
}
|
||||
|
@ -196,6 +188,18 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
// Helper function to wait given a duration type. The duration type should
|
||||
// either be of type boost::posix_time::time_duration, or implement the
|
||||
// required subset of its interface.
|
||||
template <typename Duration>
|
||||
void do_wait(const Duration& timeout, boost::system::error_code& ec)
|
||||
{
|
||||
::timeval tv;
|
||||
tv.tv_sec = timeout.total_seconds();
|
||||
tv.tv_usec = timeout.total_microseconds() % 1000000;
|
||||
socket_ops::select(0, 0, 0, 0, &tv, ec);
|
||||
}
|
||||
|
||||
// The queue of timers.
|
||||
timer_queue<Time_Traits> timer_queue_;
|
||||
|
||||
|
|
38
3party/boost/boost/asio/detail/dependent_type.hpp
Normal file
38
3party/boost/boost/asio/detail/dependent_type.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// detail/dependent_type.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2012 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_DETAIL_DEPENDENT_TYPE_HPP
|
||||
#define BOOST_ASIO_DETAIL_DEPENDENT_TYPE_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/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename DependsOn, typename T>
|
||||
struct dependent_type
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_DETAIL_DEPENDENT_TYPE_HPP
|
|
@ -2,7 +2,7 @@
|
|||
// detail/descriptor_ops.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -93,9 +93,11 @@ BOOST_ASIO_DECL int fcntl(int d, long cmd, boost::system::error_code& ec);
|
|||
BOOST_ASIO_DECL int fcntl(int d, long cmd,
|
||||
long arg, boost::system::error_code& ec);
|
||||
|
||||
BOOST_ASIO_DECL int poll_read(int d, boost::system::error_code& ec);
|
||||
BOOST_ASIO_DECL int poll_read(int d,
|
||||
state_type state, boost::system::error_code& ec);
|
||||
|
||||
BOOST_ASIO_DECL int poll_write(int d, boost::system::error_code& ec);
|
||||
BOOST_ASIO_DECL int poll_write(int d,
|
||||
state_type state, boost::system::error_code& ec);
|
||||
|
||||
} // namespace descriptor_ops
|
||||
} // namespace detail
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/descriptor_read_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -76,7 +76,8 @@ public:
|
|||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
|
||||
|
@ -98,7 +99,7 @@ public:
|
|||
// Make the upcall if required.
|
||||
if (owner)
|
||||
{
|
||||
boost::asio::detail::fenced_block b;
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/descriptor_write_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -76,7 +76,8 @@ public:
|
|||
}
|
||||
|
||||
static void do_complete(io_service_impl* owner, operation* base,
|
||||
boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
|
||||
const boost::system::error_code& /*ec*/,
|
||||
std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
// Take ownership of the handler object.
|
||||
descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
|
||||
|
@ -98,7 +99,7 @@ public:
|
|||
// Make the upcall if required.
|
||||
if (owner)
|
||||
{
|
||||
boost::asio::detail::fenced_block b;
|
||||
fenced_block b(fenced_block::half);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
|
||||
boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
|
||||
BOOST_ASIO_HANDLER_INVOCATION_END;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/dev_poll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
@ -31,10 +31,10 @@
|
|||
#include <boost/asio/detail/reactor_op_queue.hpp>
|
||||
#include <boost/asio/detail/select_interrupter.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
#include <boost/asio/detail/timer_op.hpp>
|
||||
#include <boost/asio/detail/timer_queue_base.hpp>
|
||||
#include <boost/asio/detail/timer_queue_fwd.hpp>
|
||||
#include <boost/asio/detail/timer_queue_set.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
template <typename Time_Traits>
|
||||
void schedule_timer(timer_queue<Time_Traits>& queue,
|
||||
const typename Time_Traits::time_type& time,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
|
||||
|
||||
// Cancel the timer operations associated with the given token. Returns the
|
||||
// number of operations that have been posted or dispatched.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/dev_poll_reactor_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/epoll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@ -19,8 +19,10 @@
|
|||
|
||||
#if defined(BOOST_ASIO_HAS_EPOLL)
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/detail/atomic_count.hpp>
|
||||
#include <boost/asio/detail/epoll_reactor_fwd.hpp>
|
||||
#include <boost/asio/detail/mutex.hpp>
|
||||
#include <boost/asio/detail/object_pool.hpp>
|
||||
|
@ -28,10 +30,10 @@
|
|||
#include <boost/asio/detail/reactor_op.hpp>
|
||||
#include <boost/asio/detail/select_interrupter.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
#include <boost/asio/detail/timer_op.hpp>
|
||||
#include <boost/asio/detail/timer_queue_base.hpp>
|
||||
#include <boost/asio/detail/timer_queue_fwd.hpp>
|
||||
#include <boost/asio/detail/timer_queue_set.hpp>
|
||||
#include <boost/asio/detail/wait_op.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
|
@ -47,16 +49,27 @@ public:
|
|||
connect_op = 1, except_op = 2, max_ops = 3 };
|
||||
|
||||
// Per-descriptor queues.
|
||||
class descriptor_state
|
||||
class descriptor_state : operation
|
||||
{
|
||||
friend class epoll_reactor;
|
||||
friend class object_pool_access;
|
||||
mutex mutex_;
|
||||
int descriptor_;
|
||||
op_queue<reactor_op> op_queue_[max_ops];
|
||||
bool shutdown_;
|
||||
|
||||
descriptor_state* next_;
|
||||
descriptor_state* prev_;
|
||||
|
||||
mutex mutex_;
|
||||
epoll_reactor* reactor_;
|
||||
int descriptor_;
|
||||
boost::uint32_t registered_events_;
|
||||
op_queue<reactor_op> op_queue_[max_ops];
|
||||
bool shutdown_;
|
||||
|
||||
BOOST_ASIO_DECL descriptor_state();
|
||||
void set_ready_events(uint32_t events) { task_result_ = events; }
|
||||
BOOST_ASIO_DECL operation* perform_io(uint32_t events);
|
||||
BOOST_ASIO_DECL static void do_complete(
|
||||
io_service_impl* owner, operation* base,
|
||||
const boost::system::error_code& ec, std::size_t bytes_transferred);
|
||||
};
|
||||
|
||||
// Per-descriptor data.
|
||||
|
@ -134,7 +147,7 @@ public:
|
|||
template <typename Time_Traits>
|
||||
void schedule_timer(timer_queue<Time_Traits>& queue,
|
||||
const typename Time_Traits::time_type& time,
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
|
||||
typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
|
||||
|
||||
// Cancel the timer operations associated with the given token. Returns the
|
||||
// number of operations that have been posted or dispatched.
|
||||
|
@ -160,6 +173,12 @@ private:
|
|||
// Create the timerfd file descriptor. Does not throw.
|
||||
BOOST_ASIO_DECL static int do_timerfd_create();
|
||||
|
||||
// Allocate a new descriptor state object.
|
||||
BOOST_ASIO_DECL descriptor_state* allocate_descriptor_state();
|
||||
|
||||
// Free an existing descriptor state object.
|
||||
BOOST_ASIO_DECL void free_descriptor_state(descriptor_state* s);
|
||||
|
||||
// Helper function to add a new timer queue.
|
||||
BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
|
||||
|
||||
|
@ -186,15 +205,15 @@ private:
|
|||
// Mutex to protect access to internal data.
|
||||
mutex mutex_;
|
||||
|
||||
// The interrupter is used to break a blocking epoll_wait call.
|
||||
select_interrupter interrupter_;
|
||||
|
||||
// The epoll file descriptor.
|
||||
int epoll_fd_;
|
||||
|
||||
// The timer file descriptor.
|
||||
int timer_fd_;
|
||||
|
||||
// The interrupter is used to break a blocking epoll_wait call.
|
||||
select_interrupter interrupter_;
|
||||
|
||||
// The timer queues.
|
||||
timer_queue_set timer_queues_;
|
||||
|
||||
|
@ -206,6 +225,10 @@ private:
|
|||
|
||||
// Keep track of all registered descriptors.
|
||||
object_pool<descriptor_state> registered_descriptors_;
|
||||
|
||||
// Helper class to do post-perform_io cleanup.
|
||||
struct perform_io_cleanup_on_block_exit;
|
||||
friend struct perform_io_cleanup_on_block_exit;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/epoll_reactor_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// detail/event.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2012 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)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue