1 /////////////////////////////////////////////////////////////////////////////// 2 // external_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_EXTERNAL_ACCUMULATOR_HPP_EAN_01_12_2005 9 #define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_EXTERNAL_ACCUMULATOR_HPP_EAN_01_12_2005 10 11 #include <boost/mpl/placeholders.hpp> 12 #include <boost/parameter/keyword.hpp> 13 #include <boost/accumulators/framework/extractor.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/accumulators/reference_accumulator.hpp> 17 18 namespace boost { namespace accumulators { namespace impl 19 { 20 21 ////////////////////////////////////////////////////////////////////////// 22 // external_impl 23 /// INTERNAL ONLY 24 /// 25 template<typename Accumulator, typename Tag> 26 struct external_impl 27 : accumulator_base 28 { 29 typedef typename Accumulator::result_type result_type; 30 typedef typename detail::feature_tag<Accumulator>::type feature_tag; 31 external_implboost::accumulators::impl::external_impl32 external_impl(dont_care) {} 33 34 template<typename Args> resultboost::accumulators::impl::external_impl35 result_type result(Args const &args) const 36 { 37 return this->extract_(args, args[parameter::keyword<Tag>::instance | 0]); 38 } 39 40 private: 41 42 template<typename Args> extract_boost::accumulators::impl::external_impl43 static result_type extract_(Args const &args, int) 44 { 45 // No named parameter passed to the extractor. Maybe the external 46 // feature is held by reference<>. 47 extractor<feature_tag> extract; 48 return extract(accumulators::reference_tag<Tag>(args)); 49 } 50 51 template<typename Args, typename AccumulatorSet> extract_boost::accumulators::impl::external_impl52 static result_type extract_(Args const &, AccumulatorSet const &acc) 53 { 54 // OK, a named parameter for this external feature was passed to the 55 // extractor, so use that. 56 extractor<feature_tag> extract; 57 return extract(acc); 58 } 59 }; 60 61 } // namespace impl 62 63 namespace tag 64 { 65 ////////////////////////////////////////////////////////////////////////// 66 // external 67 template<typename Feature, typename Tag, typename AccumulatorSet> 68 struct external 69 : depends_on<reference<AccumulatorSet, Tag> > 70 { 71 typedef 72 accumulators::impl::external_impl< 73 detail::to_accumulator<Feature, mpl::_1, mpl::_2> 74 , Tag 75 > 76 impl; 77 }; 78 79 template<typename Feature, typename Tag> 80 struct external<Feature, Tag, void> 81 : depends_on<> 82 { 83 typedef 84 accumulators::impl::external_impl< 85 detail::to_accumulator<Feature, mpl::_1, mpl::_2> 86 , Tag 87 > 88 impl; 89 }; 90 } 91 92 // for the purposes of feature-based dependency resolution, 93 // external_accumulator<Feature, Tag> provides the same feature as Feature 94 template<typename Feature, typename Tag, typename AccumulatorSet> 95 struct feature_of<tag::external<Feature, Tag, AccumulatorSet> > 96 : feature_of<Feature> 97 { 98 }; 99 100 // Note: Usually, the extractor is pulled into the accumulators namespace with 101 // a using directive, not the tag. But the external<> feature doesn't have an 102 // extractor, so we can put the external tag in the accumulators namespace 103 // without fear of a name conflict. 104 using tag::external; 105 106 }} // namespace boost::accumulators 107 108 #endif 109