1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // tail_variate.hpp |
3 | // |
4 | // Copyright 2005 Eric Niebler, Michael Gauckler. Distributed under the Boost |
5 | // Software License, Version 1.0. (See accompanying file |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | #ifndef BOOST_STAT_STATISTICS_TAIL_VARIATE_HPP_EAN_28_10_2005 |
9 | #define BOOST_STAT_STATISTICS_TAIL_VARIATE_HPP_EAN_28_10_2005 |
10 | |
11 | #include <boost/range.hpp> |
12 | #include <boost/mpl/always.hpp> |
13 | #include <boost/mpl/placeholders.hpp> |
14 | #include <boost/iterator/reverse_iterator.hpp> |
15 | #include <boost/iterator/permutation_iterator.hpp> |
16 | #include <boost/accumulators/framework/accumulator_base.hpp> |
17 | #include <boost/accumulators/framework/extractor.hpp> |
18 | #include <boost/accumulators/framework/depends_on.hpp> |
19 | #include <boost/accumulators/statistics_fwd.hpp> |
20 | #include <boost/accumulators/statistics/tail.hpp> |
21 | #include <boost/serialization/vector.hpp> |
22 | |
23 | namespace boost { namespace accumulators |
24 | { |
25 | |
26 | namespace impl |
27 | { |
28 | /////////////////////////////////////////////////////////////////////////////// |
29 | // tail_variate_impl |
30 | template<typename VariateType, typename VariateTag, typename LeftRight> |
31 | struct tail_variate_impl |
32 | : accumulator_base |
33 | { |
34 | // for boost::result_of |
35 | typedef |
36 | typename detail::tail_range< |
37 | typename std::vector<VariateType>::const_iterator |
38 | , std::vector<std::size_t>::iterator |
39 | >::type |
40 | result_type; |
41 | |
42 | template<typename Args> |
43 | tail_variate_impl(Args const &args) |
44 | : variates(args[tag::tail<LeftRight>::cache_size], args[parameter::keyword<VariateTag>::get() | VariateType()]) |
45 | { |
46 | } |
47 | |
48 | template<typename Args> |
49 | void assign(Args const &args, std::size_t index) |
50 | { |
51 | this->variates[index] = args[parameter::keyword<VariateTag>::get()]; |
52 | } |
53 | |
54 | template<typename Args> |
55 | result_type result(Args const &args) const |
56 | { |
57 | // getting the order result causes the indices vector to be sorted. |
58 | extractor<tag::tail<LeftRight> > const some_tail = {}; |
59 | return this->do_result(some_tail(args)); |
60 | } |
61 | |
62 | private: |
63 | template<typename TailRng> |
64 | result_type do_result(TailRng const &rng) const |
65 | { |
66 | return detail::make_tail_range( |
67 | this->variates.begin() |
68 | , rng.end().base().base() // the index iterator |
69 | , rng.begin().base().base() // (begin and end reversed because these are reverse iterators) |
70 | ); |
71 | } |
72 | |
73 | // make this accumulator serializeable |
74 | template<class Archive> |
75 | void serialize(Archive & ar, const unsigned int file_version) |
76 | { |
77 | ar & variates; |
78 | } |
79 | |
80 | private: |
81 | std::vector<VariateType> variates; |
82 | }; |
83 | |
84 | } // namespace impl |
85 | |
86 | /////////////////////////////////////////////////////////////////////////////// |
87 | // tag::tail_variate<> |
88 | // |
89 | namespace tag |
90 | { |
91 | template<typename VariateType, typename VariateTag, typename LeftRight> |
92 | struct tail_variate |
93 | : depends_on<tail<LeftRight> > |
94 | { |
95 | /// INTERNAL ONLY |
96 | /// |
97 | typedef mpl::always<accumulators::impl::tail_variate_impl<VariateType, VariateTag, LeftRight> > impl; |
98 | }; |
99 | |
100 | struct abstract_tail_variate |
101 | : depends_on<> |
102 | { |
103 | }; |
104 | |
105 | template<typename LeftRight> |
106 | struct tail_weights |
107 | : depends_on<tail<LeftRight> > |
108 | { |
109 | /// INTERNAL ONLY |
110 | /// |
111 | typedef accumulators::impl::tail_variate_impl<mpl::_2, tag::weight, LeftRight> impl; |
112 | }; |
113 | |
114 | struct abstract_tail_weights |
115 | : depends_on<> |
116 | { |
117 | }; |
118 | } |
119 | |
120 | /////////////////////////////////////////////////////////////////////////////// |
121 | // extract::tail_variate |
122 | // extract::tail_weights |
123 | // |
124 | namespace extract |
125 | { |
126 | extractor<tag::abstract_tail_variate> const = {}; |
127 | extractor<tag::abstract_tail_weights> const = {}; |
128 | |
129 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_variate) |
130 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_weights) |
131 | } |
132 | |
133 | using extract::tail_variate; |
134 | using extract::tail_weights; |
135 | |
136 | template<typename VariateType, typename VariateTag, typename LeftRight> |
137 | struct feature_of<tag::tail_variate<VariateType, VariateTag, LeftRight> > |
138 | : feature_of<tag::abstract_tail_variate> |
139 | { |
140 | }; |
141 | |
142 | template<typename LeftRight> |
143 | struct feature_of<tag::tail_weights<LeftRight> > |
144 | { |
145 | typedef tag::abstract_tail_weights type; |
146 | }; |
147 | |
148 | }} // namespace boost::accumulators |
149 | |
150 | #endif |
151 | |