|
Boost : |
From: Andrei Alexandrescu (andrewalex_at_[hidden])
Date: 2002-04-11 17:19:52
"Aleksey Gurtovoy" <agurtovoy_at_[hidden]> wrote in message
news:a94t5n$dbf$1_at_main.gmane.org...
> Joel de Guzman wrote:
> > Two points:
> >
> > 1) Unlike STL's algorithms, writing an MPL algorithm is not as
> > straightforward
>
> Why do you think so? Sure, it's different, due to functional flavor of the
> domain, but it is straightforward in MPL terms. For example, here's (a
> little bit simplified) 'count_if' algorithm implementation:
>
> namespace aux {
>
> template< typename Predicate >
> struct next_if
> {
> template<
> typename N
> , typename T
> >
> struct apply
> {
> typedef typename select_if<
> apply<Predicate,T>::value
> , typename next<N>::type
> , N
> >::type type;
> };
> };
>
> } // namespace aux
>
> template<
> typename Sequence
> , typename Predicate
> >
> struct count_if
> {
> typedef typename fold<
> Sequence
> , integral_c<unsigned long, 0>
> , aux::next_if<Predicate>
> >::type type;
>
> BOOST_STATIC_CONSTANT(unsigned long
> , value = type::value
> );
> };
>
> > and there indeed is a core infrastructure that one
> > needs to learn in order to write one.
>
> Well, yes, you'll have to learn a couple of things :).
I don't have access to MPL here, could anyone tell me how I can download it
again?
I forgot what the convention for Predicate was, but I recall it has a nested
template class 'apply' that exposes 'value'. Assuming that that's the case,
the following code implements count_if, in a slightly terser manner (it also
relies on first principles only - there's no core infrastructure to learn).
The code maps to the algorithm like this: for a null typelist, count_if is
zero; for any other typelist, count_if returns an optional one (if the
predicate is true for the head) plus the result of count_if, applied to the
tail of the typelist.
template <class TList, class Predicate> struct count_if;
template <class Predicate>
struct count_if<Nulltype, Predicate>
{
BOOST_STATIC_CONSTANT(
unsigned long,
value = 0);
};
template <class H, class T, class Predicate>
struct count_if<typelist<H, T>, Predicate>
{
BOOST_STATIC_CONSTANT(
unsigned long,
value = (Predicate::apply<H>::value ? 1 : 0) + count_if<T,
Predicate>::value);
};
Andrei
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk