• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
tail_variate_implboost::accumulators::impl::tail_variate_impl43         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>
assignboost::accumulators::impl::tail_variate_impl49         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>
resultboost::accumulators::impl::tail_variate_impl55         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>
do_resultboost::accumulators::impl::tail_variate_impl64         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>
serializeboost::accumulators::impl::tail_variate_impl75         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 tail_variate = {};
127     extractor<tag::abstract_tail_weights> const tail_weights = {};
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