// Boost Lambda Library -- loops.hpp ---------------------------------------- | |
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) | |
// Copyright (C) 2000 Gary Powell (powellg@amazon.com) | |
// Copyright (c) 2001-2002 Joel de Guzman | |
// | |
// 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) | |
// | |
// For more information, see www.boost.org | |
// -------------------------------------------------------------------------- | |
#if !defined(BOOST_LAMBDA_LOOPS_HPP) | |
#define BOOST_LAMBDA_LOOPS_HPP | |
#include "boost/lambda/core.hpp" | |
namespace boost { | |
namespace lambda { | |
// -- loop control structure actions ---------------------- | |
class forloop_action {}; | |
class forloop_no_body_action {}; | |
class whileloop_action {}; | |
class whileloop_no_body_action {}; | |
class dowhileloop_action {}; | |
class dowhileloop_no_body_action {}; | |
// For loop | |
template <class Arg1, class Arg2, class Arg3, class Arg4> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
forloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, | |
lambda_functor<Arg3>, lambda_functor<Arg4> > | |
> | |
> | |
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, | |
const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) { | |
return | |
lambda_functor_base< | |
forloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, | |
lambda_functor<Arg3>, lambda_functor<Arg4> > | |
> | |
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, | |
lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4) | |
); | |
} | |
// No body case. | |
template <class Arg1, class Arg2, class Arg3> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
forloop_no_body_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> > | |
> | |
> | |
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, | |
const lambda_functor<Arg3>& a3) { | |
return | |
lambda_functor_base< | |
forloop_no_body_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, | |
lambda_functor<Arg3> > | |
> | |
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, | |
lambda_functor<Arg3> >(a1, a2, a3) ); | |
} | |
// While loop | |
template <class Arg1, class Arg2> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
whileloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > | |
> | |
> | |
while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) { | |
return | |
lambda_functor_base< | |
whileloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > | |
> | |
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2)); | |
} | |
// No body case. | |
template <class Arg1> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
whileloop_no_body_action, | |
tuple<lambda_functor<Arg1> > | |
> | |
> | |
while_loop(const lambda_functor<Arg1>& a1) { | |
return | |
lambda_functor_base< | |
whileloop_no_body_action, | |
tuple<lambda_functor<Arg1> > | |
> | |
( tuple<lambda_functor<Arg1> >(a1) ); | |
} | |
// Do While loop | |
template <class Arg1, class Arg2> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
dowhileloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > | |
> | |
> | |
do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) { | |
return | |
lambda_functor_base< | |
dowhileloop_action, | |
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > | |
> | |
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2)); | |
} | |
// No body case. | |
template <class Arg1> | |
inline const | |
lambda_functor< | |
lambda_functor_base< | |
dowhileloop_no_body_action, | |
tuple<lambda_functor<Arg1> > | |
> | |
> | |
do_while_loop(const lambda_functor<Arg1>& a1) { | |
return | |
lambda_functor_base< | |
dowhileloop_no_body_action, | |
tuple<lambda_functor<Arg1> > | |
> | |
( tuple<lambda_functor<Arg1> >(a1)); | |
} | |
// Control loop lambda_functor_base specializations. | |
// Specialization for for_loop. | |
template<class Args> | |
class | |
lambda_functor_base<forloop_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); | |
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); | |
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) | |
detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS); | |
} | |
}; | |
// No body case | |
template<class Args> | |
class | |
lambda_functor_base<forloop_no_body_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); | |
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); | |
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {} | |
} | |
}; | |
// Specialization for while_loop. | |
template<class Args> | |
class | |
lambda_functor_base<whileloop_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) | |
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); | |
} | |
}; | |
// No body case | |
template<class Args> | |
class | |
lambda_functor_base<whileloop_no_body_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {} | |
} | |
}; | |
// Specialization for do_while_loop. | |
// Note that the first argument is the condition. | |
template<class Args> | |
class | |
lambda_functor_base<dowhileloop_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
do { | |
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); | |
} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); | |
} | |
}; | |
// No body case | |
template<class Args> | |
class | |
lambda_functor_base<dowhileloop_no_body_action, Args> { | |
public: | |
Args args; | |
template <class T> struct sig { typedef void type; }; | |
public: | |
explicit lambda_functor_base(const Args& a) : args(a) {} | |
template<class RET, CALL_TEMPLATE_ARGS> | |
RET call(CALL_FORMAL_ARGS) const { | |
do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ); | |
} | |
}; | |
// The code below is from Joel de Guzman, some name changes etc. | |
// has been made. | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// while_composite | |
// | |
// This composite has the form: | |
// | |
// while_(condition) | |
// [ | |
// statement | |
// ] | |
// | |
// While the condition (an lambda_functor) evaluates to true, statement | |
// (another lambda_functor) is executed. The result type of this is void. | |
// Note the trailing underscore after while_. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
template <typename CondT, typename DoT> | |
struct while_composite { | |
typedef while_composite<CondT, DoT> self_t; | |
template <class SigArgs> | |
struct sig { typedef void type; }; | |
while_composite(CondT const& cond_, DoT const& do__) | |
: cond(cond_), do_(do__) {} | |
template <class Ret, CALL_TEMPLATE_ARGS> | |
Ret call(CALL_FORMAL_ARGS) const | |
{ | |
while (cond.internal_call(CALL_ACTUAL_ARGS)) | |
do_.internal_call(CALL_ACTUAL_ARGS); | |
} | |
CondT cond; | |
DoT do_; | |
}; | |
////////////////////////////////// | |
template <typename CondT> | |
struct while_gen { | |
while_gen(CondT const& cond_) | |
: cond(cond_) {} | |
template <typename DoT> | |
lambda_functor<while_composite< | |
typename as_lambda_functor<CondT>::type, | |
typename as_lambda_functor<DoT>::type> > | |
operator[](DoT const& do_) const | |
{ | |
typedef while_composite< | |
typename as_lambda_functor<CondT>::type, | |
typename as_lambda_functor<DoT>::type> | |
result; | |
return result( | |
to_lambda_functor(cond), | |
to_lambda_functor(do_)); | |
} | |
CondT cond; | |
}; | |
////////////////////////////////// | |
template <typename CondT> | |
inline while_gen<CondT> | |
while_(CondT const& cond) | |
{ | |
return while_gen<CondT>(cond); | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// do_composite | |
// | |
// This composite has the form: | |
// | |
// do_ | |
// [ | |
// statement | |
// ] | |
// .while_(condition) | |
// | |
// While the condition (an lambda_functor) evaluates to true, statement | |
// (another lambda_functor) is executed. The statement is executed at least | |
// once. The result type of this is void. Note the trailing | |
// underscore after do_ and the the leading dot and the trailing | |
// underscore before and after .while_. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
template <typename DoT, typename CondT> | |
struct do_composite { | |
typedef do_composite<DoT, CondT> self_t; | |
template <class SigArgs> | |
struct sig { typedef void type; }; | |
do_composite(DoT const& do__, CondT const& cond_) | |
: do_(do__), cond(cond_) {} | |
template <class Ret, CALL_TEMPLATE_ARGS> | |
Ret call(CALL_FORMAL_ARGS) const | |
{ | |
do | |
do_.internal_call(CALL_ACTUAL_ARGS); | |
while (cond.internal_call(CALL_ACTUAL_ARGS)); | |
} | |
DoT do_; | |
CondT cond; | |
}; | |
//////////////////////////////////// | |
template <typename DoT> | |
struct do_gen2 { | |
do_gen2(DoT const& do__) | |
: do_(do__) {} | |
template <typename CondT> | |
lambda_functor<do_composite< | |
typename as_lambda_functor<DoT>::type, | |
typename as_lambda_functor<CondT>::type> > | |
while_(CondT const& cond) const | |
{ | |
typedef do_composite< | |
typename as_lambda_functor<DoT>::type, | |
typename as_lambda_functor<CondT>::type> | |
result; | |
return result( | |
to_lambda_functor(do_), | |
to_lambda_functor(cond)); | |
} | |
DoT do_; | |
}; | |
//////////////////////////////////// | |
struct do_gen { | |
template <typename DoT> | |
do_gen2<DoT> | |
operator[](DoT const& do_) const | |
{ | |
return do_gen2<DoT>(do_); | |
} | |
}; | |
do_gen const do_ = do_gen(); | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// for_composite | |
// | |
// This statement has the form: | |
// | |
// for_(init, condition, step) | |
// [ | |
// statement | |
// ] | |
// | |
// Where init, condition, step and statement are all lambda_functors. init | |
// is executed once before entering the for-loop. The for-loop | |
// exits once condition evaluates to false. At each loop iteration, | |
// step and statement is called. The result of this statement is | |
// void. Note the trailing underscore after for_. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
template <typename InitT, typename CondT, typename StepT, typename DoT> | |
struct for_composite { | |
template <class SigArgs> | |
struct sig { typedef void type; }; | |
for_composite( | |
InitT const& init_, | |
CondT const& cond_, | |
StepT const& step_, | |
DoT const& do__) | |
: init(init_), cond(cond_), step(step_), do_(do__) {} | |
template <class Ret, CALL_TEMPLATE_ARGS> | |
Ret | |
call(CALL_FORMAL_ARGS) const | |
{ | |
for (init.internal_call(CALL_ACTUAL_ARGS); cond.internal_call(CALL_ACTUAL_ARGS); step.internal_call(CALL_ACTUAL_ARGS)) | |
do_.internal_call(CALL_ACTUAL_ARGS); | |
} | |
InitT init; CondT cond; StepT step; DoT do_; // lambda_functors | |
}; | |
////////////////////////////////// | |
template <typename InitT, typename CondT, typename StepT> | |
struct for_gen { | |
for_gen( | |
InitT const& init_, | |
CondT const& cond_, | |
StepT const& step_) | |
: init(init_), cond(cond_), step(step_) {} | |
template <typename DoT> | |
lambda_functor<for_composite< | |
typename as_lambda_functor<InitT>::type, | |
typename as_lambda_functor<CondT>::type, | |
typename as_lambda_functor<StepT>::type, | |
typename as_lambda_functor<DoT>::type> > | |
operator[](DoT const& do_) const | |
{ | |
typedef for_composite< | |
typename as_lambda_functor<InitT>::type, | |
typename as_lambda_functor<CondT>::type, | |
typename as_lambda_functor<StepT>::type, | |
typename as_lambda_functor<DoT>::type> | |
result; | |
return result( | |
to_lambda_functor(init), | |
to_lambda_functor(cond), | |
to_lambda_functor(step), | |
to_lambda_functor(do_)); | |
} | |
InitT init; CondT cond; StepT step; | |
}; | |
////////////////////////////////// | |
template <typename InitT, typename CondT, typename StepT> | |
inline for_gen<InitT, CondT, StepT> | |
for_(InitT const& init, CondT const& cond, StepT const& step) | |
{ | |
return for_gen<InitT, CondT, StepT>(init, cond, step); | |
} | |
} // lambda | |
} // boost | |
#endif // BOOST_LAMBDA_LOOPS_HPP |