PageRenderTime 18ms CodeModel.GetById 11ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/accumulators/framework/accumulators/external_accumulator.hpp

http://hadesmem.googlecode.com/
C++ Header | 108 lines | 70 code | 16 blank | 22 comment | 0 complexity | 3dc53ed0dc2259bbd012c6df0963433b MD5 | raw file
  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
 18namespace 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
 32        external_impl(dont_care) {}
 33
 34        template<typename Args>
 35        result_type result(Args const &args) const
 36        {
 37            return this->extract_(args, args[parameter::keyword<Tag>::get() | 0]);
 38        }
 39
 40    private:
 41
 42        template<typename Args>
 43        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>
 52        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
 63namespace 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
 94template<typename Feature, typename Tag, typename AccumulatorSet>
 95struct 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.
104using tag::external;
105
106}} // namespace boost::accumulators
107
108#endif