Introducing
Your new presentation assistant.
Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.
Trending searches
PStade.OvenとEggを読む。
//pstade/pass_by.hpp
namespace pstade {
// same as 'detail::call_param' of Boost.Fusion2.
template< class T >
struct pass_by_reference :
boost::mpl::eval_if< boost::is_reference<T>,
boost::mpl::identity<T>,
boost::add_reference<
typename boost::add_const<
typename boost::remove_cv<T>::type
>::type
>
>
{ };
// removes cv-qualifier, cuz 'foo(int const)' is same as 'foo(int)'.
template< class T >
struct pass_by_value :
boost::remove_cv<
// 'decay' calls 'remove_reference'.
typename boost::decay<T>::type
>
{ };
} // namespace pstade
//pstade/oven/range_iterator.hpp
namespace pstade { namespace oven {
template< class Range >
struct range_iterator :
#if defined(PSTADE_OVEN_BOOST_RANGE_VERSION_1)
boost::range_result_iterator<
#else
boost::range_iterator<
#endif
Range
>
{ };
} } // namespace pstade::oven
//boost/range/iterator.hpp
namespace boost
{
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
namespace range_detail_vc7_1
{
template< typename C, typename Sig = void(C) >
struct range_iterator
{
typedef BOOST_RANGE_DEDUCED_TYPENAME
mpl::eval_if_c< is_const<C>::value,
range_const_iterator< typename remove_const<C>::type >,
range_mutable_iterator<C> >::type type;
};
template< typename C, typename T >
struct range_iterator< C, void(T[]) >
{
typedef T* type;
};
}
#endif
template< typename C >
struct range_iterator
{
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
typedef BOOST_RANGE_DEDUCED_TYPENAME
range_detail_vc7_1::range_iterator<C>::type type;
#else
typedef BOOST_RANGE_DEDUCED_TYPENAME
mpl::eval_if_c< is_const<C>::value,
range_const_iterator< typename remove_const<C>::type >,
range_mutable_iterator<C> >::type type;
#endif
};
} // namespace boost
//pstade/oven/detail/filter_iterator.hpp
namespace pstade { namespace oven { namespace detail {
template< class Predicate, class Iterator >
struct filter_iterator;
template< class Predicate, class Iterator >
struct filter_iterator_super
{
typedef
boost::iterator_adaptor<
filter_iterator<Predicate, Iterator>,
Iterator,
boost::use_default,
typename minimum_pure<
boost::bidirectional_traversal_tag,
typename boost::iterator_traversal<Iterator>::type
>::type
>
type;
};
template< class Predicate, class Iterator >
struct filter_iterator :
filter_iterator_super<Predicate, Iterator>::type
{
private:
typedef typename filter_iterator_super<Predicate, Iterator>::type super_t;
public:
typedef Predicate predicate_type;
filter_iterator()
{ }
filter_iterator(Predicate pred, Iterator it, Iterator last) :
super_t(it), m_pred(pred), m_last(last)
{
satisfy_predicate();
}
template< class I >
filter_iterator(filter_iterator<Predicate, I> const& other,
typename boost::enable_if_convertible<I, Iterator>::type * = 0
) :
super_t(other.base()), m_pred(other.predicate()), m_last(other.end())
{ }
Predicate predicate() const
{
return m_pred;
}
Iterator end() const
{
return m_last;
}
private:
Predicate m_pred;
Iterator m_last;
void satisfy_predicate()
{
while ( this->base() != m_last && !m_pred(read(this->base())) )
++(this->base_reference());
}
friend class boost::iterator_core_access;
void increment()
{
++this->base_reference();
satisfy_predicate();
}
void decrement()
{
while ( !m_pred(read(--(this->base_reference()))) )
;
}
};
template< class P1, class I1, class P2, class I2 > inline
void iter_swap(filter_iterator<P1, I1> it1, filter_iterator<P2, I2> it2, int = 0)
{
do_iter_swap(it1.base(), it2.base());
}
} } } // namespace pstade::oven::detail
pstade/oven/iter_range.hpp
// What:
//
// The minimal "iterator_range".
// This range has...
// no deep equality-comparison.
// neither 'front' nor 'back'.
// no implicit template-constructor.
//<<抜粋>>
namespace pstade { namespace oven {
namespace iter_range_based_for_lookup {
template<
class Iterator,
class Injector = iter_range_detail::null_injector
>
struct iter_range :
boost::equality_comparable1< iter_range<Iterator, Injector>,
radish::bool_testable < iter_range<Iterator, Injector>,
radish::swappable < iter_range<Iterator, Injector>,
lightweight_copyable < iter_range<Iterator, Injector>,
Injector > > > >
{
private:
typedef iter_range self_t;
public:
// structors
iter_range()
{ }
template< class It, class In >
iter_range(iter_range<It, In> const& other,
typename enable_if< is_convertible<It, Iterator> >::type = 0
) :
m_first(boost::begin(other)), m_last(boost::end(other))
{ }
// range implementation
typedef Iterator iterator;
typedef Iterator const_iterator;
typedef std::size_t size_type;
Iterator begin() const
{
return m_first;
}
Iterator end() const
{
return m_last;
}
#if defined(PSTADE_OVEN_BOOST_RANGE_VERSION_1)
size_type size() const
{
return egg::copy<size_type>(detail::iter_distance(m_first, m_last));
}
#endif
// convenience
typedef self_t type;
typedef typename boost::iterator_value<Iterator>::type value_type;
typedef typename boost::iterator_difference<Iterator>::type difference_type;
typedef typename boost::iterator_reference<Iterator>::type reference;
private:
Iterator m_first, m_last;
};
template< class It, class In > inline
It begin(iter_range<It, In> const& rng)
{
return rng.begin();
}
template< class It, class In > inline
It end(iter_range<It, In> const& rng)
{
return rng.end();
}
//pstade/egg/poly.hpp
namespace pstade { namespace egg {
template<class Expr, class Strategy = by_perfect, class NullaryResult = boost::use_default>
struct poly
{
typedef
function<detail::little_poly<PSTADE_EGG_BEFORE_MPL_APPLY_TPL(Expr), NullaryResult>, Strategy>
type;
};
#define PSTADE_EGG_POLY() {{}}
} } // namespace pstade::egg
//pstade/egg/detail/little_poly.hpp
#ifndef BOOST_PP_IS_ITERATING
#ifndef PSTADE_EGG_DETAIL_LITTLE_POLY_HPP
#define PSTADE_EGG_DETAIL_LITTLE_POLY_HPP
namespace pstade { namespace egg { namespace detail {
template<class Expr, class NullaryResult>
struct little_poly
{
// 0ary
struct extract_nullary_result
{
typedef typename
boost::mpl::apply0<Expr>::type
impl_t;
typedef typename impl_t::result_type type;
};
typedef typename
eval_if_use_nullary_result< NullaryResult,
extract_nullary_result
>::type
nullary_result_type;
template<class Re>
Re call() const
{
typedef typename extract_nullary_result::impl_t impl_t;
return impl_t()();
}
// 1ary-
template<class Me, PSTADE_EGG_APPLY_DECL_PARAMS(BOOST_MPL_LIMIT_METAFUNCTION_ARITY, A)>
struct PSTADE_EGG_APPLY_DECL;
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <pstade/egg/detail/little_poly.hpp>))
#include BOOST_PP_ITERATE()
};
} } } // namespace pstade::egg::detail
#endif
#else
#define n BOOST_PP_ITERATION()
template<class Me, BOOST_PP_ENUM_PARAMS(n, class A)>
struct apply<Me, BOOST_PP_ENUM_PARAMS(n, A)>
{
typedef typename
boost::mpl::BOOST_PP_CAT(apply, n)<Expr, BOOST_PP_ENUM_PARAMS(n, A)>::type
impl_t;
typedef typename impl_t::result_type type;
};
template<class Re, BOOST_PP_ENUM_PARAMS(n, class A)>
Re call(BOOST_PP_ENUM_BINARY_PARAMS(n, A, &a)) const
{
typedef typename apply<void, BOOST_PP_ENUM_PARAMS(n, A)>::impl_t impl_t;
return impl_t()(BOOST_PP_ENUM_PARAMS(n, a));
}
#undef n
#endif
mplのプレースホルダーが使われたExprを、little関数オブジェクトに変換。
//pstade/unparenthesize.hpp
// See:
//
// http://d.hatena.ne.jp/Cryolite/20050326
// http://www.kangaroologic.com/interfaces/libs/interfaces/doc/macros/protect.html
// 'BOOST_PARAMETER_PARENTHESIZED_TYPE' with Boost v1.34
// What:
//
// Makes decayed-T with cv-qualifier from
// PSTADE_UNPARENTHESIZE((T)cv-qualifier), where cv-qualifier is optional.
#define PSTADE_UNPARENTHESIZE(TQ) \
pstade::unparenthesize_detail::aux< void (::pstade::unparenthesize_detail::klass::*) TQ >::type \
/**/
#define PSTADE_UNPARENTHESIZE_TPL \
typename PSTADE_UNPARENTHESIZE \
/**/
namespace pstade { namespace unparenthesize_detail {
struct klass;
template< class Signature >
struct aux;
template< class T >
struct aux< void (klass::*)(T) >
{
typedef T type;
};
template< >
struct aux< void (klass::*)(void) >
{
typedef void type;
};
template< class T >
struct aux< void (klass::*)(T) const >
{
typedef T const type;
};
template< class T >
struct aux< void (klass::*)(T) volatile >
{
typedef T volatile type;
};
template< class T >
struct aux< void (klass::*)(T) const volatile >
{
typedef T const volatile type;
};
} } // namespace pstade::unparenthesize_detail
//pstade/pod_constant.hpp
#define PSTADE_POD_CONSTANT(F, O) \
PSTADE_POD_ASSERT_OF(F, O); \
PSTADE_UNPARENTHESIZE(F) const PSTADE_IGNORE_UNUSED O \
/**/
//pstade/egg/pipable.hpp
namespace pstade { namespace egg {
template<class Base, class Strategy = by_perfect, class OperandBytag = by_perfect>
struct result_of_pipable
{
typedef
function<detail::little_pipable_result<Base, Strategy, OperandBytag>, Strategy>
type;
};
#define PSTADE_EGG_PIPABLE_L { {
#define PSTADE_EGG_PIPABLE_R , {} } }
#define PSTADE_EGG_PIPABLE(F) PSTADE_EGG_PIPABLE_L F PSTADE_EGG_PIPABLE_R
template<class Strategy = by_perfect, class OperandBytag = by_perfect>
struct X_pipable : derived_from_eval<
generator<
typename result_of_pipable<deduce<mpl_1, as_value>, Strategy, OperandBytag>::type,
by_value,
X_construct_braced2<>
> >
{ };
typedef X_pipable<>::base_class T_pipable;
PSTADE_POD_CONSTANT((T_pipable), pipable) = PSTADE_EGG_GENERATOR();
// If msvc fails to find operator|, use this as super type.
using detail::lookup_pipable_operator;
} } // namespace pstade::egg
//pstade/egg/detail/little_pipable_result.hpp
#ifndef BOOST_PP_IS_ITERATING
#ifndef PSTADE_EGG_DETAIL_LITTLE_PIPABLE_RESULT_HPP
#define PSTADE_EGG_DETAIL_LITTLE_PIPABLE_RESULT_HPP
#define PSTADE_EGG_PIPABLE_MAX_ARITY \
BOOST_PP_DEC(PSTADE_EGG_MAX_LINEAR_ARITY) \
/**/
namespace pstade { namespace egg { namespace detail {
namespace pipable_operators {
namespace here = pipable_operators;
template<class O, class Base, class Args>
struct result_of_output :
result_of<
typename result_of<
T_tuple_fuse(Base const &)
>::type(typename result_of<X_tuple_prepend<by_ref>(Args const &, O &)>::type)
>
{ };
// Fortunately, boost::tuples::null_type is a POD type.
template<class Base, class Strategy, class OperandBytag, class Args = boost::tuples::null_type>
struct little_pipable_result
{
Base m_base;
Args m_args;
Base const &base() const
{
return m_base;
}
template<class O>
typename result_of_output<O, Base, Args>::type
output(O &o) const
{
return tuple_fuse(m_base)(X_tuple_prepend<by_ref>()(m_args, o));
}
template<class Args_>
struct function_with
{
typedef
function<little_pipable_result<Base, Strategy, OperandBytag, Args_>, Strategy>
type;
};
// 0ary
typedef typename
function_with<boost::tuples::null_type>::type
nullary_result_type;
template<class Re>
Re call() const
{
Re r = { { m_base, {} } };
return r;
}
// 1ary-
template<class Me, PSTADE_EGG_APPLY_DECL_PARAMS(PSTADE_EGG_PIPABLE_MAX_ARITY, A)>
struct PSTADE_EGG_APPLY_DECL;
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, PSTADE_EGG_PIPABLE_MAX_ARITY, <pstade/egg/detail/little_pipable_result.hpp>))
#include BOOST_PP_ITERATE()
};
struct lookup_pipable_operator { };
// operator|
//
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< is_a_or_b<OperandBytag, by_perfect, by_ref>, result_of_output<O, Base, Args> >::type
operator|(O &o, function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi)
{
return pi.little().output(o);
}
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< is_a_or_b<OperandBytag, by_perfect, by_cref>, result_of_output<PSTADE_DEDUCED_CONST(O), Base, Args> >::type
operator|(O const &o, function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi)
{
return pi.little().output(o);
}
// by_value
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< boost::is_same<OperandBytag, by_value>, result_of_output<O, Base, Args> >::type
operator|(O o, function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi)
{
// For movable types, we can't turn `o` into const-reference.
return pi.little().output(o);
}
// operater|=
//
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< is_a_or_b<OperandBytag, by_perfect, by_ref>, result_of_output<O, Base, Args> >::type
operator|=(function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi, O &o)
{
return pi.little().output(o);
}
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< is_a_or_b<OperandBytag, by_perfect, by_cref>, result_of_output<PSTADE_DEDUCED_CONST(O), Base, Args> >::type
operator|=(function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi, O const &o)
{
return pi.little().output(o);
}
// by_value
template<class O, class Base, class Strategy, class OperandBytag, class Args> inline
typename lazy_enable_if< boost::is_same<OperandBytag, by_value>, result_of_output<O, Base, Args> >::type
operator|=(function<little_pipable_result<Base, Strategy, OperandBytag, Args>, Strategy> const &pi, O o)
{
return pi.little().output(o);
}
} // namespace pipable_operators
using pipable_operators::little_pipable_result;
using pipable_operators::lookup_pipable_operator;
} } } // namespace pstade::egg::detail
#endif
#else
#define n BOOST_PP_ITERATION()
template<class Me, BOOST_PP_ENUM_PARAMS(n, class A)>
struct apply<Me, BOOST_PP_ENUM_PARAMS(n, A)> :
function_with<
typename result_of<X_pack<Strategy>(PSTADE_PP_ENUM_PARAMS_WITH(n, A, &))>::type
>
{ };
template<class Re, BOOST_PP_ENUM_PARAMS(n, class A)>
Re call(BOOST_PP_ENUM_BINARY_PARAMS(n, A, &a)) const
{
Re r = { { m_base, X_pack<Strategy>()(BOOST_PP_ENUM_PARAMS(n, a)) } };
return r;
}
#undef n
#endif
//pstade/egg/detail/tuple_fuse.hpp
#ifndef BOOST_PP_IS_ITERATING
#ifndef PSTADE_EGG_DETAIL_TUPLE_FUSE_HPP
#define PSTADE_EGG_DETAIL_TUPLE_FUSE_HPP
namespace pstade { namespace egg { namespace detail {
template<class Base>
struct little_tuple_fuse_result
{
Base m_base;
Base const &base() const
{
return m_base;
}
template<class Tuple, class Arity>
struct apply_aux;
template<class Me, class Tuple>
struct apply :
apply_aux<Tuple, typename tuple_length<Tuple>::type>
{ };
template<class Re, class Tuple>
Re call(Tuple &t) const
{
return call_aux<Re>(t, typename tuple_length<Tuple>::type());
}
#define PSTADE_result_of_get(Z, N, _) typename result_of_tuple_get<N, Tuple>::type
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, PSTADE_EGG_MAX_LINEAR_ARITY, <pstade/egg/detail/tuple_fuse.hpp>))
#include BOOST_PP_ITERATE()
#undef PSTADE_result_of_get
};
typedef
generator<
function<little_tuple_fuse_result< deduce<mpl_1, as_value> >, by_cref>,
by_value,
X_construct_braced2<>
>::type
T_tuple_fuse;
PSTADE_POD_CONSTANT((T_tuple_fuse), tuple_fuse) = PSTADE_EGG_GENERATOR();
} } } // namespace pstade::egg::detail
#endif
#else
#define n BOOST_PP_ITERATION()
template<class Tuple>
struct apply_aux< Tuple, boost::mpl::int_<n> > :
result_of<
Base const( BOOST_PP_ENUM(n, PSTADE_result_of_get, ~) )
>
{ };
template<class Re, class Tuple>
Re call_aux(Tuple &t, boost::mpl::int_<n>) const
{
(void)t; // for n == 0.
return m_base( PSTADE_PP_ENUM_PARAMS_WITH(n, boost::tuples::get<PSTADE_PP_INT_, >(t)) );
}
#undef n
#endif
//pstade/oven/filterd.hpp
namespace pstade { namespace oven {
namespace filtered_detail {
template< class Range, class Predicate >
struct base
{
typedef
detail::filter_iterator<
typename pass_by_value<Predicate>::type,
typename range_iterator<Range>::type
>
iter_t;
typedef
iter_range<iter_t> const
result_type;
result_type operator()(Range& rng, Predicate& pred) const
{
PSTADE_CONCEPT_ASSERT((SinglePass<Range>));
return aux(boost::begin(rng), boost::end(rng), pred);
}
template< class Iterator >
result_type aux(Iterator first, Iterator last, Predicate& pred) const
{
return result_type(iter_t(pred, first, last), iter_t(pred, last, last));
}
};
} // namespace filtered_detail
PSTADE_OVEN_BASE_TO_ADAPTOR(filtered, (filtered_detail::base<_, _>))
} } // namespace pstade::oven
//pstade/oven/transformed.hpp
namespace pstade { namespace oven {
namespace transformed_detail {
template< class Reference, class Value >
struct little
{
template< class Myself, class Range, class UnaryFun >
struct apply
{
typedef typename
range_iterator<Range>::type
base_iter_t;
typedef typename
pass_by_value<UnaryFun>::type
fun_t;
typedef typename
iterator_read<base_iter_t>::type
read_t;
typedef typename
eval_if_use_default<
Reference,
result_of<fun_t const(read_t)>
>::type
ref_t;
typedef typename
eval_if_use_default<
Value,
plain<ref_t>
>::type
val_t;
typedef
detail::transform_iterator<
fun_t,
base_iter_t,
ref_t,
val_t
>
iter_t;
typedef
iter_range<iter_t> const
type;
};
template< class Result, class Range, class UnaryFun >
Result call(Range& rng, UnaryFun& fun) const
{
PSTADE_CONCEPT_ASSERT((SinglePass<Range>));
typedef typename Result::iterator iter_t;
return Result(
iter_t(boost::begin(rng), fun),
iter_t(boost::end(rng), fun)
);
}
};
} // namespace transformed_detail
template<
class Reference = boost::use_default,
class Value = boost::use_default
>
struct X_make_transformed :
egg::function< transformed_detail::little<Reference, Value> >
{ };
PSTADE_OVEN_LITTLE_TO_ADAPTOR(transformed, (X_make_transformed<>::little_type))
} } // namespace pstade::oven
//pstade/oven/read.hpp
// What:
//
// A dereference of ReadableIterator returns a type "convertible" to
// associated 'value_type', but it is useless for writing generic code.
//
// Once 'read' is applied to non-Lvalue one, the result is not Assignable,
// meaning that the iterator loses Writability."
namespace pstade { namespace oven {
template< class ReadableOrLvalueIter >
struct iterator_read :
boost::mpl::eval_if< detail::is_reference_iterator<ReadableOrLvalueIter>,
boost::iterator_reference<ReadableOrLvalueIter>,
boost::iterator_value<ReadableOrLvalueIter>
>
{ };
namespace read_detail {
template< class ReadableOrLvalueIter >
struct base
{
typedef typename
iterator_read<
typename boost::remove_cv<ReadableOrLvalueIter>::type
>::type
result_type;
// Pass by reference; see "./reverse_iterator.hpp"
result_type operator()(ReadableOrLvalueIter& it) const
{
return *it;
}
};
} // namespace read_detail
typedef egg::poly< read_detail::base<boost::mpl::_> >::type T_read;
PSTADE_POD_CONSTANT((T_read), read) = PSTADE_EGG_POLY();
} } // namespace pstade::oven
//pstade/oven/detail/transform_iterator.hpp
// Reason why 'boost::transform_iterator' rejected:
//
// IteratorCategory must be recomputed using 'detail::pure_traversal'.
// For example, consider 'rng|zipped|unzipped'.
// 'UnaryFun' may resurrect lvalue-ness of the base range,
// then a RandomAccess*Input* Iterator can turn into the RandomAccess.
// Though 'identities' can do the same thing, this will compile faster.
// Note:
//
// Consider the following simple functor.
//
// struct id
// {
// typedef int const& result_type;
// result_type operator()(int const& x) const
// { return x; }
// };
//
// A transformed range whose 'reference' is 'int'(non-reference)
// cannot work with this functor because of dangling reference.
// A transformed range's 'reference' type is sometimes
// orthogonal to functor's 'result_type'.
// References:
//
// [1] Eric Niebler, transform_range, Boost.RangeEx, 2004.
// [2] David Abrahams, Jeremy Siek, Thomas Witt, transform_iterator, Boost.Iterator, 2003.
namespace pstade { namespace oven { namespace detail {
template< class UnaryFun, class Iterator, class Reference, class Value >
struct transform_iterator;
template< class UnaryFun, class Iterator, class Reference, class Value >
struct transform_iterator_super
{
typedef
boost::iterator_adaptor<
transform_iterator<UnaryFun, Iterator, Reference, Value>,
Iterator,
Value,
typename pure_traversal<Iterator>::type,
Reference
>
type;
};
template< class UnaryFun, class Iterator, class Reference, class Value >
struct transform_iterator :
transform_iterator_super<UnaryFun, Iterator, Reference, Value>::type
{
private:
typedef typename transform_iterator_super<UnaryFun, Iterator, Reference, Value>::type super_t;
public:
transform_iterator()
{ }
transform_iterator(Iterator it, UnaryFun fun) :
super_t(it), m_fun(fun)
{ }
template< class I, class R, class V >
transform_iterator(transform_iterator<UnaryFun, I, R, V> const& other,
typename boost::enable_if_convertible<I, Iterator>::type * = 0
) :
super_t(other.base()), m_fun(other.function())
{ }
UnaryFun function() const
{
return m_fun;
}
// boost compatible
UnaryFun functor() const
{
return function();
}
private:
UnaryFun m_fun;
friend class boost::iterator_core_access;
typename super_t::reference dereference() const
{
// 'read' seems not so bad idea.
return m_fun(read(this->base()));
}
};
} } } // namespace pstade::oven::detail
#endif
//pstade/oven/detail/little_to_adaptor.hpp
#define PSTADE_OVEN_LITTLE_TO_ADAPTOR(O, F) \
typedef pstade::egg::function<PSTADE_UNPARENTHESIZE(F)> BOOST_PP_CAT(T_make_, O); \
PSTADE_POD_CONSTANT((BOOST_PP_CAT(T_make_, O)), BOOST_PP_CAT(make_, O)) = {{}}; \
PSTADE_POD_CONSTANT((pstade::egg::result_of_pipable<BOOST_PP_CAT(T_make_, O)>::type), O) = PSTADE_EGG_PIPABLE({{}}); \
/**/
//pstade/oven/algorithm.hpp
//<<抜粋>>
// Note:
//
// I doubt the optimization using member functions is useful.
// Adaptors easily loses the base range type.
// References:
//
// [1] Eric Niebler, Boost.RangeEx, 2004.
// http://www.boost-consulting.com/vault/index.php?directory=Algorithms
namespace pstade { namespace oven {
#define PSTADE_nonmodifying1 \
(for_each)(find)(find_if)(adjacent_find)(count)(count_if)(mismatch)(equal) \
/**/
PSTADE_ADL_BARRIER(algorithm) {
BOOST_PP_SEQ_FOR_EACH(PSTADE_OVEN_RANGE_BASED1_LL, ~, PSTADE_nonmodifying1)
} // ADL barrier
#undef PSTADE_nonmodifying1
} } // namespace pstade::oven
//pstade/oven/detail/range_based_ll.hpp
<<抜粋>>
namespace pstade { namespace oven { namespace detail {
// Pass by_cref; large arity is needed.
template< class SigFun >
struct range_based1_sig_fun :
result_of_range_based1<
typename egg::result_of_bll_poly<SigFun, egg::by_cref>::type
>
{ };
#define PSTADE_OVEN_RANGE_BASED1_LL(R, _, Name) \
typedef \
pstade::oven::detail::range_based1_sig_fun< boost::lambda::ll::Name >::type \
BOOST_PP_CAT(T_, Name); \
\
PSTADE_POD_CONSTANT((BOOST_PP_CAT(T_, Name)), Name) \
= PSTADE_OVEN_RANGE_BASED1_L PSTADE_OVEN_RANGE_BASED_LL_init PSTADE_OVEN_RANGE_BASED1_R; \
/**/
#define PSTADE_OVEN_RANGE_BASED_LL_init \
PSTADE_EGG_BLL_POLY({}) \
/**/
} } } // namespace pstade::oven::detail
//pstade/egg/bll/poly.hpp
#ifndef PSTADE_EGG_BLL_POLY_HPP
#define PSTADE_EGG_BLL_POLY_HPP
#include "../detail/prefix.hpp"
// What:
//
// Converts a poor functor type holding 'sig'
// into the function which supports 'boost::result_of'.
//
// As we can't detect the arity without 'lambda::bind',
// a nullary-callable function must be identified by 'bll_poly_nullary'.
namespace pstade { namespace egg {
template<class Bindable, class Strategy = by_perfect>
struct result_of_bll_poly
{
typedef
function<detail::little_bll_poly_result<Bindable, boost::mpl::false_>, Strategy>
type;
};
#define PSTADE_EGG_BLL_POLY_L { {
#define PSTADE_EGG_BLL_POLY_R } }
#define PSTADE_EGG_BLL_POLY(F) PSTADE_EGG_BLL_POLY_L F PSTADE_EGG_BLL_POLY_R
typedef
generator<
result_of_bll_poly< deduce<mpl_1, as_value> >::type,
by_value,
X_construct_braced2<>
>::type
T_bll_poly;
PSTADE_POD_CONSTANT((T_bll_poly), bll_poly) = PSTADE_EGG_GENERATOR();
template<class Bindable>
struct result_of_bll_poly_nullary
{
typedef
function<detail::little_bll_poly_result<Bindable, boost::mpl::true_>, by_ref>
type;
};
typedef
generator<
result_of_bll_poly_nullary< deduce<mpl_1, as_value> >::type,
by_value,
X_construct_braced2<>
>::type
T_bll_poly_nullary;
PSTADE_POD_CONSTANT((T_bll_poly_nullary), bll_poly_nullary) = PSTADE_EGG_GENERATOR();
} } // namespace pstade::egg
#include "../detail/suffix.hpp"
#endif
//pstade/oven/deti/range_based1.hpp
#ifndef BOOST_PP_IS_ITERATING
#ifndef PSTADE_OVEN_DETAIL_RANGE_BASED1_HPP
#define PSTADE_OVEN_DETAIL_RANGE_BASED1_HPP
// Note:
//
// Yet another implementation using 'fuse/unfuse' and
// Boost.Fusion will be interesting.
namespace pstade { namespace oven { namespace detail {
template< class IterBased >
struct little_range_based1_result
{
IterBased m_base;
typedef IterBased base_type;
IterBased base() const
{
return m_base;
}
template< class Myself, class Range0, PSTADE_PP_ENUM_PARAMS_WITH(PSTADE_EGG_MAX_ARITY, class A, = void) >
struct PSTADE_EGG_APPLY_DECL;
// rng0 + 0ary
template< class Myself, class Range0 >
struct apply<Myself, Range0> :
result_of<
IterBased const(
typename range_iterator<Range0>::type,
typename range_iterator<Range0>::type
)
>
{ };
template< class Result, class Range0 >
Result call(Range0& rng0) const
{
return m_base(
boost::begin(rng0),
boost::end(rng0)
);
}
// rng0 + 1ary-
#define PSTADE_max_arity BOOST_PP_DEC(PSTADE_EGG_MAX_ARITY)
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, PSTADE_max_arity, <pstade/oven/detail/range_based1.hpp>))
#include BOOST_PP_ITERATE()
#undef PSTADE_max_arity
template<class FunArgs>
struct sig :
egg::bll_sig_impl<FunArgs>
{ };
};
template< class IterBased >
struct result_of_range_based1
{
typedef
egg::function< little_range_based1_result<IterBased> >
type;
};
#define PSTADE_OVEN_RANGE_BASED1_L { {
#define PSTADE_OVEN_RANGE_BASED1_R } }
#define PSTADE_OVEN_RANGE_BASED1(F) PSTADE_OVEN_RANGE_BASED1_L F PSTADE_OVEN_RANGE_BASED1_R
typedef
egg::generator<
result_of_range_based1< egg::deduce<boost::mpl::_1, egg::as_value> >::type,
egg::by_value,
egg::X_construct_braced2<>
>::type
T_range_based1;
PSTADE_POD_CONSTANT((T_range_based1), range_based1) = PSTADE_EGG_GENERATOR();
} } } // namespace pstade::oven::detail
#endif
#else
#define n BOOST_PP_ITERATION()
template< class Myself, class Range0, BOOST_PP_ENUM_PARAMS(n, class A) >
struct apply<Myself, Range0, BOOST_PP_ENUM_PARAMS(n, A)> :
result_of<
IterBased const(
typename range_iterator<Range0>::type,
typename range_iterator<Range0>::type,
PSTADE_PP_ENUM_PARAMS_WITH(n, A, &)
)
>
{ };
template< class Result, class Range0, BOOST_PP_ENUM_PARAMS(n, class A) >
Result call(Range0& rng0, BOOST_PP_ENUM_BINARY_PARAMS(n, A, & a)) const
{
return m_base(
boost::begin(rng0),
boost::end(rng0),
BOOST_PP_ENUM_PARAMS(n, a)
);
}
#undef n
#endif
oven::copy(
x
| oven::filtered(isalpha)
| oven::transformed(toupper),
std::ostream_iterator<char>(std::cout) );
read:
egg::function 引数に渡されたイテレータがis_reference_iteratorならイテレータの値を参照で。
そうでないなら値をコピーで返す。
//pstade/oven/detail/base_to_adaptor.hpp
#define PSTADE_OVEN_BASE_TO_ADAPTOR(O, B) \
namespace BOOST_PP_CAT(adaptor_workarea_of_, O) { \
using boost::mpl::_; \
typedef pstade::egg::poly<boost::mpl::lambda<PSTADE_UNPARENTHESIZE(B)>::type>::type op; \
} \
typedef BOOST_PP_CAT(adaptor_workarea_of_, O)::op BOOST_PP_CAT(T_make_, O); \
PSTADE_POD_CONSTANT((BOOST_PP_CAT(T_make_, O)), BOOST_PP_CAT(make_, O)) = PSTADE_EGG_POLY(); \
PSTADE_POD_CONSTANT((pstade::egg::result_of_pipable<BOOST_PP_CAT(T_make_, O)>::type), O) = PSTADE_EGG_PIPABLE_L PSTADE_EGG_POLY() PSTADE_EGG_PIPABLE_R; \
/**/
functionとは?
()付きで渡されてきたマクロの引数の()を取る
namespace pstade {
template< class X, class Then, class Else = X >
struct if_use_default :
boost::mpl::if_< boost::is_same<X, boost::use_default>,
Then,
Else
>
{ };
template< class X, class Then, class Else = boost::mpl::identity<X> >
struct eval_if_use_default :
boost::mpl::eval_if< boost::is_same<X, boost::use_default>,
Then,
Else
>
{ };
Nameにはalgorithmの関数名が渡されている