Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // rolling_window.hpp Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tag::rolling_window::size named parameter Chris@16: BOOST_PARAMETER_NESTED_KEYWORD(tag, rolling_window_size, window_size) Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_size) Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // rolling_window_plus1_impl Chris@16: // stores the latest N+1 samples, where N is specified at construction time Chris@16: // with the rolling_window_size named parameter Chris@16: template Chris@16: struct rolling_window_plus1_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename circular_buffer::const_iterator const_iterator; Chris@16: typedef iterator_range result_type; Chris@16: Chris@16: template Chris@16: rolling_window_plus1_impl(Args const & args) Chris@16: : buffer_(args[rolling_window_size] + 1) Chris@16: {} Chris@16: Chris@16: #if BOOST_VERSION < 103600 Chris@16: // Before Boost 1.36, copying a circular buffer didn't copy Chris@16: // it's capacity, and we need that behavior. Chris@16: rolling_window_plus1_impl(rolling_window_plus1_impl const &that) Chris@16: : buffer_(that.buffer_) Chris@16: { Chris@16: this->buffer_.set_capacity(that.buffer_.capacity()); Chris@16: } Chris@16: Chris@16: rolling_window_plus1_impl &operator =(rolling_window_plus1_impl const &that) Chris@16: { Chris@16: this->buffer_ = that.buffer_; Chris@16: this->buffer_.set_capacity(that.buffer_.capacity()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: template Chris@16: void operator ()(Args const &args) Chris@16: { Chris@16: this->buffer_.push_back(args[sample]); Chris@16: } Chris@16: Chris@16: bool full() const Chris@16: { Chris@16: return this->buffer_.full(); Chris@16: } Chris@16: Chris@16: // The result of a shifted rolling window is the range including Chris@16: // everything except the most recently added element. Chris@16: result_type result(dont_care) const Chris@16: { Chris@16: return result_type(this->buffer_.begin(), this->buffer_.end()); Chris@16: } Chris@16: Chris@16: private: Chris@16: circular_buffer buffer_; Chris@16: }; Chris@16: Chris@16: template Chris@16: bool is_rolling_window_plus1_full(Args const &args) Chris@16: { Chris@16: return find_accumulator(args[accumulator]).full(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // rolling_window_impl Chris@16: // stores the latest N samples, where N is specified at construction type Chris@16: // with the rolling_window_size named parameter Chris@16: template Chris@16: struct rolling_window_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename circular_buffer::const_iterator const_iterator; Chris@16: typedef iterator_range result_type; Chris@16: Chris@16: rolling_window_impl(dont_care) Chris@16: {} Chris@16: Chris@16: template Chris@16: result_type result(Args const &args) const Chris@16: { Chris@16: return rolling_window_plus1(args).advance_begin(is_rolling_window_plus1_full(args)); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tag::rolling_window_plus1 Chris@16: // tag::rolling_window Chris@16: // Chris@16: namespace tag Chris@16: { Chris@16: struct rolling_window_plus1 Chris@16: : depends_on<> Chris@16: , tag::rolling_window_size Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl; Chris@16: Chris@16: #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED Chris@16: /// tag::rolling_window::size named parameter Chris@16: static boost::parameter::keyword const window_size; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: struct rolling_window Chris@16: : depends_on< rolling_window_plus1 > Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl; Chris@16: Chris@16: #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED Chris@16: /// tag::rolling_window::size named parameter Chris@16: static boost::parameter::keyword const window_size; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: } // namespace tag Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extract::rolling_window_plus1 Chris@16: // extract::rolling_window Chris@16: // Chris@16: namespace extract Chris@16: { Chris@16: extractor const rolling_window_plus1 = {}; Chris@16: extractor const rolling_window = {}; Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_plus1) Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window) Chris@16: } Chris@16: Chris@16: using extract::rolling_window_plus1; Chris@16: using extract::rolling_window; Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #endif