2012-02-08 14:39:36 +00:00
|
|
|
#ifndef SPROUT_BREED_TRANSFORM_WHEN_HPP
|
|
|
|
#define SPROUT_BREED_TRANSFORM_WHEN_HPP
|
|
|
|
|
|
|
|
#include <type_traits>
|
|
|
|
#include <sprout/config.hpp>
|
|
|
|
#include <sprout/type/type_tuple.hpp>
|
|
|
|
#include <sprout/type/iterator/deref.hpp>
|
|
|
|
#include <sprout/type/seq/algorithm/find_if.hpp>
|
|
|
|
#include <sprout/breed/breed_fwd.hpp>
|
|
|
|
#include <sprout/breed/traits.hpp>
|
|
|
|
#include <sprout/breed/transform/call.hpp>
|
|
|
|
#include <sprout/breed/transform/make.hpp>
|
|
|
|
#include <sprout/breed/transform/impl.hpp>
|
|
|
|
|
|
|
|
namespace sprout {
|
|
|
|
namespace breed {
|
|
|
|
//
|
|
|
|
// when
|
|
|
|
//
|
|
|
|
template<typename Grammar, typename PrimitiveTransform>
|
|
|
|
struct when
|
|
|
|
: public PrimitiveTransform
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef Grammar first;
|
|
|
|
typedef PrimitiveTransform second;
|
|
|
|
typedef typename Grammar::breed_grammar breed_grammar;
|
|
|
|
};
|
|
|
|
template<typename Grammar, typename Fun>
|
|
|
|
struct when<Grammar, Fun*>
|
|
|
|
: public sprout::breed::when<Grammar, Fun>
|
|
|
|
{};
|
|
|
|
template<typename Grammar>
|
|
|
|
struct when<Grammar, sprout::breed::external_transform>
|
|
|
|
: public sprout::breed::transform<when<Grammar, sprout::breed::external_transform> >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef Grammar first;
|
|
|
|
typedef external_transform second;
|
|
|
|
typedef typename Grammar::breed_grammar breed_grammar;
|
|
|
|
public:
|
|
|
|
template<typename Expr, typename State, typename Data>
|
|
|
|
struct impl
|
|
|
|
: public Data::template when<Grammar>::template impl<Expr, State, Data>
|
|
|
|
{};
|
|
|
|
template<typename Expr, typename State, typename Data>
|
|
|
|
struct impl<Expr, State, Data&>
|
|
|
|
: public Data::template when<Grammar>::template impl<Expr, State, Data&>
|
|
|
|
{};
|
|
|
|
};
|
|
|
|
template<typename Grammar, typename R, typename... Args>
|
|
|
|
struct when<Grammar, R(Args...)>
|
|
|
|
: public sprout::breed::transform<when<Grammar, R(Args...)> >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef Grammar first;
|
|
|
|
typedef R second(Args...);
|
|
|
|
typedef typename Grammar::breed_grammar breed_grammar;
|
|
|
|
public:
|
|
|
|
template<typename Expr, typename State, typename Data>
|
|
|
|
struct impl
|
|
|
|
: public sprout::breed::transform_impl<Expr, State, Data>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef typename std::conditional<
|
|
|
|
sprout::breed::is_callable<R>::value,
|
|
|
|
sprout::breed::call<R(Args...)>,
|
|
|
|
sprout::breed::make<R(Args...)>
|
|
|
|
>::type which;
|
|
|
|
typedef typename which::template impl<Expr, State, Data>::result_type result_type;
|
|
|
|
public:
|
|
|
|
SPROUT_CONSTEXPR result_type operator()(
|
|
|
|
typename impl::expr_param e,
|
|
|
|
typename impl::state_param s,
|
|
|
|
typename impl::data_param d
|
|
|
|
) const
|
|
|
|
{
|
|
|
|
return typename which::template impl<Expr, State, Data>()(e, s, d);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
//
|
|
|
|
// is_callable
|
|
|
|
//
|
|
|
|
template<typename Grammar, typename Transform>
|
|
|
|
struct is_callable<sprout::breed::when<Grammar, Transform> >
|
|
|
|
: public std::true_type
|
|
|
|
{};
|
|
|
|
//
|
|
|
|
// otherwise
|
|
|
|
//
|
|
|
|
template<typename Fun>
|
|
|
|
struct otherwise
|
|
|
|
: public sprout::breed::when<sprout::breed::_, Fun>
|
|
|
|
{};
|
2012-05-21 16:06:13 +00:00
|
|
|
//
|
2012-02-08 14:39:36 +00:00
|
|
|
// external_transforms
|
|
|
|
//
|
|
|
|
template<typename... Args>
|
|
|
|
struct external_transforms {
|
|
|
|
public:
|
|
|
|
typedef sprout::types::type_tuple<Args...> map_type;
|
|
|
|
private:
|
|
|
|
template<typename Rule>
|
|
|
|
struct map_pred {
|
|
|
|
public:
|
|
|
|
template<typename T>
|
|
|
|
struct apply
|
|
|
|
: public std::is_same<Rule, typename T::first>
|
|
|
|
{};
|
|
|
|
};
|
|
|
|
public:
|
|
|
|
template<typename Rule>
|
|
|
|
struct when
|
|
|
|
: public sprout::breed::when<
|
|
|
|
sprout::breed::_,
|
|
|
|
sprout::types::deref<
|
|
|
|
typename sprout::types::find_if<map_type, map_pred<Rule> >::type
|
|
|
|
>::type
|
|
|
|
>
|
|
|
|
{};
|
|
|
|
};
|
|
|
|
} // namespace breed
|
|
|
|
} // namespace sprout
|
|
|
|
|
|
|
|
#endif // #ifndef SPROUT_BREED_TRANSFORM_WHEN_HPP
|