Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:21

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // rolling_window.hpp
0003 //
0004 // Copyright 2008 Eric Niebler. Distributed under the Boost
0005 // Software License, Version 1.0. (See accompanying file
0006 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
0009 #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
0010 
0011 #include <cstddef>
0012 #include <boost/version.hpp>
0013 #include <boost/assert.hpp>
0014 #include <boost/circular_buffer.hpp>
0015 #include <boost/range/iterator_range.hpp>
0016 #include <boost/accumulators/accumulators_fwd.hpp>
0017 #include <boost/accumulators/framework/extractor.hpp>
0018 #include <boost/accumulators/framework/depends_on.hpp>
0019 #include <boost/accumulators/framework/accumulator_base.hpp>
0020 #include <boost/accumulators/framework/parameters/sample.hpp>
0021 #include <boost/accumulators/framework/parameters/accumulator.hpp>
0022 #include <boost/accumulators/numeric/functional.hpp>
0023 #include <boost/accumulators/statistics_fwd.hpp>
0024 #include <boost/serialization/split_free.hpp>
0025 
0026 namespace boost { namespace serialization {
0027 
0028 // implement serialization for boost::circular_buffer
0029 template <class Archive, class T>
0030 void save(Archive& ar, const circular_buffer<T>& b, const unsigned int /* version */)
0031 {
0032     typename circular_buffer<T>::size_type size = b.size();
0033     ar << b.capacity();
0034     ar << size;
0035     const typename circular_buffer<T>::const_array_range one = b.array_one();
0036     const typename circular_buffer<T>::const_array_range two = b.array_two();
0037     ar.save_binary(one.first, one.second*sizeof(T));
0038     ar.save_binary(two.first, two.second*sizeof(T));
0039 }
0040 
0041 template <class Archive, class T>
0042 void load(Archive& ar, circular_buffer<T>& b, const unsigned int /* version */)
0043 {
0044     typename circular_buffer<T>::capacity_type capacity;
0045     typename circular_buffer<T>::size_type size;
0046     ar >> capacity;
0047     b.set_capacity(capacity);
0048     ar >> size;
0049     b.clear();
0050     const typename circular_buffer<T>::pointer buff = new T[size*sizeof(T)];
0051     ar.load_binary(buff, size*sizeof(T));
0052     b.insert(b.begin(), buff, buff+size);
0053     delete[] buff;
0054 }
0055 
0056 template<class Archive, class T>
0057 inline void serialize(Archive & ar, circular_buffer<T>& b, const unsigned int version)
0058 {
0059     split_free(ar, b, version);
0060 }
0061 
0062 } } // end namespace boost::serialization
0063 
0064 namespace boost { namespace accumulators
0065 {
0066 
0067 ///////////////////////////////////////////////////////////////////////////////
0068 // tag::rolling_window::size named parameter
0069 BOOST_PARAMETER_NESTED_KEYWORD(tag, rolling_window_size, window_size)
0070 
0071 BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_size)
0072 
0073 namespace impl
0074 {
0075     ///////////////////////////////////////////////////////////////////////////////
0076     // rolling_window_plus1_impl
0077     //    stores the latest N+1 samples, where N is specified at construction time
0078     //    with the rolling_window_size named parameter
0079     template<typename Sample>
0080     struct rolling_window_plus1_impl
0081       : accumulator_base
0082     {
0083         typedef typename circular_buffer<Sample>::const_iterator const_iterator;
0084         typedef iterator_range<const_iterator> result_type;
0085 
0086         template<typename Args>
0087         rolling_window_plus1_impl(Args const & args)
0088           : buffer_(args[rolling_window_size] + 1)
0089         {}
0090 
0091         #if BOOST_VERSION < 103600
0092         // Before Boost 1.36, copying a circular buffer didn't copy
0093         // it's capacity, and we need that behavior.
0094         rolling_window_plus1_impl(rolling_window_plus1_impl const &that)
0095           : buffer_(that.buffer_)
0096         {
0097             this->buffer_.set_capacity(that.buffer_.capacity());
0098         }
0099 
0100         rolling_window_plus1_impl &operator =(rolling_window_plus1_impl const &that)
0101         {
0102             this->buffer_ = that.buffer_;
0103             this->buffer_.set_capacity(that.buffer_.capacity());
0104         }
0105         #endif
0106 
0107         template<typename Args>
0108         void operator ()(Args const &args)
0109         {
0110             this->buffer_.push_back(args[sample]);
0111         }
0112 
0113         bool full() const
0114         {
0115             return this->buffer_.full();
0116         }
0117 
0118         // The result of a shifted rolling window is the range including
0119         // everything except the most recently added element.
0120         result_type result(dont_care) const
0121         {
0122             return result_type(this->buffer_.begin(), this->buffer_.end());
0123         }
0124 
0125         template<class Archive>
0126         void serialize(Archive & ar, const unsigned int version)
0127         {
0128             ar & buffer_;
0129         }
0130 
0131     private:
0132         circular_buffer<Sample> buffer_;
0133     };
0134 
0135     template<typename Args>
0136     bool is_rolling_window_plus1_full(Args const &args)
0137     {
0138         return find_accumulator<tag::rolling_window_plus1>(args[accumulator]).full();
0139     }
0140 
0141     ///////////////////////////////////////////////////////////////////////////////
0142     // rolling_window_impl
0143     //    stores the latest N samples, where N is specified at construction type
0144     //    with the rolling_window_size named parameter
0145     template<typename Sample>
0146     struct rolling_window_impl
0147       : accumulator_base
0148     {
0149         typedef typename circular_buffer<Sample>::const_iterator const_iterator;
0150         typedef iterator_range<const_iterator> result_type;
0151 
0152         rolling_window_impl(dont_care)
0153         {}
0154 
0155         template<typename Args>
0156         result_type result(Args const &args) const
0157         {
0158             return rolling_window_plus1(args).advance_begin(is_rolling_window_plus1_full(args));
0159         }
0160         
0161         // serialization is done by accumulators it depends on
0162         template<class Archive>
0163         void serialize(Archive & ar, const unsigned int file_version) {}
0164     };
0165 
0166 } // namespace impl
0167 
0168 ///////////////////////////////////////////////////////////////////////////////
0169 // tag::rolling_window_plus1
0170 // tag::rolling_window
0171 //
0172 namespace tag
0173 {
0174     struct rolling_window_plus1
0175       : depends_on<>
0176       , tag::rolling_window_size
0177     {
0178         /// INTERNAL ONLY
0179         ///
0180         typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl;
0181 
0182         #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
0183         /// tag::rolling_window::size named parameter
0184         static boost::parameter::keyword<tag::rolling_window_size> const window_size;
0185         #endif
0186     };
0187 
0188     struct rolling_window
0189       : depends_on< rolling_window_plus1 >
0190     {
0191         /// INTERNAL ONLY
0192         ///
0193         typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl;
0194 
0195         #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
0196         /// tag::rolling_window::size named parameter
0197         static boost::parameter::keyword<tag::rolling_window_size> const window_size;
0198         #endif
0199     };
0200 
0201 } // namespace tag
0202 
0203 ///////////////////////////////////////////////////////////////////////////////
0204 // extract::rolling_window_plus1
0205 // extract::rolling_window
0206 //
0207 namespace extract
0208 {
0209     extractor<tag::rolling_window_plus1> const rolling_window_plus1 = {};
0210     extractor<tag::rolling_window> const rolling_window = {};
0211 
0212     BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_plus1)
0213     BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window)
0214 }
0215 
0216 using extract::rolling_window_plus1;
0217 using extract::rolling_window;
0218 
0219 }} // namespace boost::accumulators
0220 
0221 #endif