/usr/include/boost/accumulators/framework
Edit: /usr/include/boost/accumulators/framework/depends_on.hpp (15173B)
///////////////////////////////////////////////////////////////////////////////
// depends_on.hpp
//
// Copyright 2005 Eric Niebler. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ACCUMULATORS_FRAMEWORK_DEPENDS_ON_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_DEPENDS_ON_HPP_EAN_28_10_2005
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////
// as_feature
template
struct as_feature
{
typedef Feature type;
};
///////////////////////////////////////////////////////////////////////////
// weighted_feature
template
struct as_weighted_feature
{
typedef Feature type;
};
///////////////////////////////////////////////////////////////////////////
// feature_of
template
struct feature_of
{
typedef Feature type;
};
namespace detail
{
///////////////////////////////////////////////////////////////////////////
// feature_tag
template
struct feature_tag
{
typedef typename Accumulator::feature_tag type;
};
template
struct undroppable
{
typedef Feature type;
};
template
struct undroppable >
{
typedef Feature type;
};
// For the purpose of determining whether one feature depends on another,
// disregard whether the feature is droppable or not.
template
struct is_dependent_on
: is_base_and_derived<
typename feature_of::type>::type
, typename undroppable::type
>
{};
template
struct dependencies_of
{
typedef typename Feature::dependencies type;
};
// Should use mpl::insert_range, but doesn't seem to work with mpl sets
template
struct set_insert_range
: mpl::fold<
Range
, Set
, mpl::insert
>
{};
template
struct collect_abstract_features
: mpl::fold<
Features
, mpl::set0<>
, set_insert_range<
mpl::insert >
, collect_abstract_features >
>
>
{};
template
struct depends_on_base
: mpl::inherit_linearly<
typename mpl::sort<
typename mpl::copy<
typename collect_abstract_features::type
, mpl::back_inserter >
>::type
, is_dependent_on
>::type
// Don't inherit multiply from a feature
, mpl::if_<
is_dependent_on
, mpl::_1
, mpl::inherit
>
>::type
{
};
}
///////////////////////////////////////////////////////////////////////////
/// depends_on
template
struct depends_on
: detail::depends_on_base<
typename mpl::transform<
mpl::vector
, as_feature
>::type
>
{
typedef mpl::false_ is_weight_accumulator;
typedef
typename mpl::transform<
mpl::vector
, as_feature
>::type
dependencies;
};
namespace detail
{
template
struct matches_feature
{
template
struct apply
: is_same<
typename feature_of::type>::type
, typename feature_of::type>::type>::type
>
{};
};
template
struct contains_feature_of
{
typedef
mpl::transform_view > >
features_list;
typedef
typename feature_of::type>::type
the_feature;
typedef
typename mpl::contains::type
type;
};
// This is to work around a bug in early versions of Fusion which caused
// a compile error if contains_feature_of is used as a
// predicate to fusion::find_if
template
struct contains_feature_of_
{
template
struct apply
: contains_feature_of
{};
};
template<
typename First
, typename Last
, bool is_empty = fusion::result_of::equal_to::value
>
struct build_acc_list;
template
struct build_acc_list
{
typedef fusion::nil_ type;
template
static fusion::nil_
call(Args const &, First const&, Last const&)
{
return fusion::nil_();
}
};
template
struct build_acc_list
{
typedef
build_acc_list::type, Last>
next_build_acc_list;
typedef fusion::cons<
typename fusion::result_of::value_of::type
, typename next_build_acc_list::type>
type;
template
static type
call(Args const &args, First const& f, Last const& l)
{
return type(args, next_build_acc_list::call(args, fusion::next(f), l));
}
};
namespace meta
{
template
struct make_acc_list
: build_acc_list<
typename fusion::result_of::begin::type
, typename fusion::result_of::end::type
>
{};
}
template
typename meta::make_acc_list::type
make_acc_list(Sequence &seq, Args const &args)
{
return meta::make_acc_list::call(args, fusion::begin(seq), fusion::end(seq));
}
template
typename meta::make_acc_list::type
make_acc_list(Sequence const &seq, Args const &args)
{
return meta::make_acc_list::call(args, fusion::begin(seq), fusion::end(seq));
}
///////////////////////////////////////////////////////////////////////////
// checked_as_weighted_feature
template
struct checked_as_weighted_feature
{
typedef typename as_feature::type feature_type;
typedef typename as_weighted_feature::type type;
// weighted and non-weighted flavors should provide the same feature.
BOOST_MPL_ASSERT((
is_same<
typename feature_of::type
, typename feature_of::type
>
));
};
///////////////////////////////////////////////////////////////////////////
// as_feature_list
template
struct as_feature_list
: mpl::transform_view >
{
};
template
struct as_feature_list
: mpl::transform_view >
{
};
///////////////////////////////////////////////////////////////////////////
// accumulator_wrapper
template
struct accumulator_wrapper
: Accumulator
{
typedef Feature feature_tag;
accumulator_wrapper(accumulator_wrapper const &that)
: Accumulator(*static_cast(&that))
{
}
template
accumulator_wrapper(Args const &args)
: Accumulator(args)
{
}
};
///////////////////////////////////////////////////////////////////////////
// to_accumulator
template
struct to_accumulator
{
typedef
accumulator_wrapper<
typename mpl::apply2::type
, Feature
>
type;
};
template
struct to_accumulator >
{
BOOST_MPL_ASSERT((is_same));
BOOST_MPL_ASSERT((is_same));
typedef
accumulator_wrapper<
typename mpl::apply2::type
, Feature
>
accumulator_type;
typedef
typename mpl::if_<
typename Feature::is_weight_accumulator
, accumulator_wrapper, Feature>
, accumulator_type
>::type
type;
};
// BUGBUG work around an MPL bug wrt map insertion
template
struct insert_feature
: mpl::eval_if<
mpl::has_key::type>
, mpl::identity
, mpl::insert::type, Feature> >
>
{
};
template
struct insert_dependencies
: mpl::fold<
as_feature_list
, FeatureMap
, insert_dependencies<
insert_feature
, mpl::_2
, Weight
>
>
{
};
template
struct insert_sequence
: mpl::fold< // BUGBUG should use insert_range, but doesn't seem to work for maps
as_feature_list
, FeatureMap
, insert_feature
>
{
};
template
struct make_accumulator_tuple
{
typedef
typename mpl::fold<
as_feature_list
, mpl::map0<>
, mpl::if_<
mpl::is_sequence
, insert_sequence
, insert_feature
>
>::type
feature_map;
// for each element in the map, add its dependencies also
typedef
typename mpl::fold<
feature_map
, feature_map
, insert_dependencies, Weight>
>::type
feature_map_with_dependencies;
// turn the map into a vector so we can sort it
typedef
typename mpl::insert_range<
mpl::vector<>
, mpl::end >::type
, mpl::transform_view >
>::type
feature_vector_with_dependencies;
// sort the features according to which is derived from which
typedef
typename mpl::sort<
feature_vector_with_dependencies
, is_dependent_on
>::type
sorted_feature_vector;
// From the vector of features, construct a vector of accumulators
typedef
typename mpl::transform<
sorted_feature_vector
, to_accumulator
>::type
type;
};
} // namespace detail
}} // namespace boost::accumulators
#endif