File indexing completed on 2025-01-18 09:28:21
0001
0002
0003
0004
0005
0006
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
0029 template <class Archive, class T>
0030 void save(Archive& ar, const circular_buffer<T>& b, const unsigned int )
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 )
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 } }
0063
0064 namespace boost { namespace accumulators
0065 {
0066
0067
0068
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
0077
0078
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
0093
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
0119
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
0143
0144
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
0162 template<class Archive>
0163 void serialize(Archive & ar, const unsigned int file_version) {}
0164 };
0165
0166 }
0167
0168
0169
0170
0171
0172 namespace tag
0173 {
0174 struct rolling_window_plus1
0175 : depends_on<>
0176 , tag::rolling_window_size
0177 {
0178
0179
0180 typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl;
0181
0182 #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
0183
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
0192
0193 typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl;
0194
0195 #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
0196
0197 static boost::parameter::keyword<tag::rolling_window_size> const window_size;
0198 #endif
0199 };
0200
0201 }
0202
0203
0204
0205
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 }}
0220
0221 #endif