Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

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の関数名が渡されている

Learn more about creating dynamic, engaging presentations with Prezi