123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- ///////////////////////////////////////////////////////////////////////////////
- // rolling_window.hpp
- //
- // Copyright 2008 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_ROLLING_WINDOW_HPP_EAN_26_12_2008
- #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
- #include <cstddef>
- #include <boost/version.hpp>
- #include <boost/assert.hpp>
- #include <boost/circular_buffer.hpp>
- #include <boost/range/iterator_range.hpp>
- #include <boost/accumulators/accumulators_fwd.hpp>
- #include <boost/accumulators/framework/extractor.hpp>
- #include <boost/accumulators/framework/depends_on.hpp>
- #include <boost/accumulators/framework/accumulator_base.hpp>
- #include <boost/accumulators/framework/parameters/sample.hpp>
- #include <boost/accumulators/framework/parameters/accumulator.hpp>
- #include <boost/accumulators/numeric/functional.hpp>
- #include <boost/accumulators/statistics_fwd.hpp>
- #include <boost/serialization/split_free.hpp>
- namespace boost { namespace serialization {
- // implement serialization for boost::circular_buffer
- template <class Archive, class T>
- void save(Archive& ar, const circular_buffer<T>& b, const unsigned int /* version */)
- {
- typename circular_buffer<T>::size_type size = b.size();
- ar << b.capacity();
- ar << size;
- const typename circular_buffer<T>::const_array_range one = b.array_one();
- const typename circular_buffer<T>::const_array_range two = b.array_two();
- ar.save_binary(one.first, one.second*sizeof(T));
- ar.save_binary(two.first, two.second*sizeof(T));
- }
- template <class Archive, class T>
- void load(Archive& ar, circular_buffer<T>& b, const unsigned int /* version */)
- {
- typename circular_buffer<T>::capacity_type capacity;
- typename circular_buffer<T>::size_type size;
- ar >> capacity;
- b.set_capacity(capacity);
- ar >> size;
- b.clear();
- const typename circular_buffer<T>::pointer buff = new T[size*sizeof(T)];
- ar.load_binary(buff, size*sizeof(T));
- b.insert(b.begin(), buff, buff+size);
- delete[] buff;
- }
- template<class Archive, class T>
- inline void serialize(Archive & ar, circular_buffer<T>& b, const unsigned int version)
- {
- split_free(ar, b, version);
- }
- } } // end namespace boost::serialization
- namespace boost { namespace accumulators
- {
- ///////////////////////////////////////////////////////////////////////////////
- // tag::rolling_window::size named parameter
- BOOST_PARAMETER_NESTED_KEYWORD(tag, rolling_window_size, window_size)
- BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_size)
- namespace impl
- {
- ///////////////////////////////////////////////////////////////////////////////
- // rolling_window_plus1_impl
- // stores the latest N+1 samples, where N is specified at construction time
- // with the rolling_window_size named parameter
- template<typename Sample>
- struct rolling_window_plus1_impl
- : accumulator_base
- {
- typedef typename circular_buffer<Sample>::const_iterator const_iterator;
- typedef iterator_range<const_iterator> result_type;
- template<typename Args>
- rolling_window_plus1_impl(Args const & args)
- : buffer_(args[rolling_window_size] + 1)
- {}
- #if BOOST_VERSION < 103600
- // Before Boost 1.36, copying a circular buffer didn't copy
- // it's capacity, and we need that behavior.
- rolling_window_plus1_impl(rolling_window_plus1_impl const &that)
- : buffer_(that.buffer_)
- {
- this->buffer_.set_capacity(that.buffer_.capacity());
- }
- rolling_window_plus1_impl &operator =(rolling_window_plus1_impl const &that)
- {
- this->buffer_ = that.buffer_;
- this->buffer_.set_capacity(that.buffer_.capacity());
- }
- #endif
- template<typename Args>
- void operator ()(Args const &args)
- {
- this->buffer_.push_back(args[sample]);
- }
- bool full() const
- {
- return this->buffer_.full();
- }
- // The result of a shifted rolling window is the range including
- // everything except the most recently added element.
- result_type result(dont_care) const
- {
- return result_type(this->buffer_.begin(), this->buffer_.end());
- }
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & buffer_;
- }
- private:
- circular_buffer<Sample> buffer_;
- };
- template<typename Args>
- bool is_rolling_window_plus1_full(Args const &args)
- {
- return find_accumulator<tag::rolling_window_plus1>(args[accumulator]).full();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // rolling_window_impl
- // stores the latest N samples, where N is specified at construction type
- // with the rolling_window_size named parameter
- template<typename Sample>
- struct rolling_window_impl
- : accumulator_base
- {
- typedef typename circular_buffer<Sample>::const_iterator const_iterator;
- typedef iterator_range<const_iterator> result_type;
- rolling_window_impl(dont_care)
- {}
- template<typename Args>
- result_type result(Args const &args) const
- {
- return rolling_window_plus1(args).advance_begin(is_rolling_window_plus1_full(args));
- }
-
- // serialization is done by accumulators it depends on
- template<class Archive>
- void serialize(Archive & ar, const unsigned int file_version) {}
- };
- } // namespace impl
- ///////////////////////////////////////////////////////////////////////////////
- // tag::rolling_window_plus1
- // tag::rolling_window
- //
- namespace tag
- {
- struct rolling_window_plus1
- : depends_on<>
- , tag::rolling_window_size
- {
- /// INTERNAL ONLY
- ///
- typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl;
- #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
- /// tag::rolling_window::size named parameter
- static boost::parameter::keyword<tag::rolling_window_size> const window_size;
- #endif
- };
- struct rolling_window
- : depends_on< rolling_window_plus1 >
- {
- /// INTERNAL ONLY
- ///
- typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl;
- #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
- /// tag::rolling_window::size named parameter
- static boost::parameter::keyword<tag::rolling_window_size> const window_size;
- #endif
- };
- } // namespace tag
- ///////////////////////////////////////////////////////////////////////////////
- // extract::rolling_window_plus1
- // extract::rolling_window
- //
- namespace extract
- {
- extractor<tag::rolling_window_plus1> const rolling_window_plus1 = {};
- extractor<tag::rolling_window> const rolling_window = {};
- BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_plus1)
- BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window)
- }
- using extract::rolling_window_plus1;
- using extract::rolling_window;
- }} // namespace boost::accumulators
- #endif
|