• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 // reference_accumulator.hpp
3 //
4 //  Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_REFERENCE_ACCUMULATOR_HPP_EAN_03_23_2006
9 #define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_REFERENCE_ACCUMULATOR_HPP_EAN_03_23_2006
10 
11 #include <boost/ref.hpp>
12 #include <boost/mpl/always.hpp>
13 #include <boost/parameter/keyword.hpp>
14 #include <boost/accumulators/framework/depends_on.hpp> // for feature_tag
15 #include <boost/accumulators/framework/accumulator_base.hpp>
16 #include <boost/accumulators/framework/extractor.hpp>
17 
18 namespace boost { namespace accumulators
19 {
20 
21 namespace impl
22 {
23     //////////////////////////////////////////////////////////////////////////
24     // reference_accumulator_impl
25     //
26     template<typename Referent, typename Tag>
27     struct reference_accumulator_impl
28       : accumulator_base
29     {
30         typedef Referent &result_type;
31 
32         template<typename Args>
reference_accumulator_implboost::accumulators::impl::reference_accumulator_impl33         reference_accumulator_impl(Args const &args)
34           : ref(args[parameter::keyword<Tag>::instance])
35         {
36         }
37 
resultboost::accumulators::impl::reference_accumulator_impl38         result_type result(dont_care) const
39         {
40             return this->ref;
41         }
42 
43     private:
44         reference_wrapper<Referent> ref;
45     };
46 } // namespace impl
47 
48 namespace tag
49 {
50     //////////////////////////////////////////////////////////////////////////
51     // reference_tag
52     template<typename Tag>
53     struct reference_tag
54     {
55     };
56 
57     //////////////////////////////////////////////////////////////////////////
58     // reference
59     template<typename Referent, typename Tag>
60     struct reference
61       : depends_on<>
62     {
63         /// INTERNAL ONLY
64         ///
65         typedef mpl::always<accumulators::impl::reference_accumulator_impl<Referent, Tag> > impl;
66     };
67 }
68 
69 namespace extract
70 {
71     BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, reference, (typename)(typename))
72     BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, reference_tag, (typename))
73 }
74 
75 using extract::reference;
76 using extract::reference_tag;
77 
78 // Map all reference<V,T> features to reference_tag<T> so
79 // that references can be extracted using reference_tag<T>
80 // without specifying the referent type.
81 template<typename ValueType, typename Tag>
82 struct feature_of<tag::reference<ValueType, Tag> >
83   : feature_of<tag::reference_tag<Tag> >
84 {
85 };
86 
87 }} // namespace boost::accumulators
88 
89 #endif
90