Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-04-14 15:42:55


Peter Dimov wrote:
> > Well, with a few simplifications, the above could be easily adopted as
an
> > MPL 'count_if' algorithm implementation. In the toy world :).
>
> But that's not the point. Nobody is trying to replace MPL's own count_if.

Somehow I got the opposite impression :).

> This is merely an example of a user-defined algorithm.

That's not how I posted it. Or, at least, that was an example of
user-defined algorithm that targeted the same goals as the library itself -
portability and compile-time efficiency. If you are ready to sacrifice
those, when you can go with explicitly recursive version like the one you
posted before. I wouldn't :).

>
> > Just a few points:
> >
> > 1) The above doesn't work on compilers without partial specialization.
> > 2) There are cases when the above doesn't work on Metrowerks Codewarrior
> > (all versions).
> > 3) When the predicate is complex, the above doesn't work on large
> sequences
> > (> 50) because of the limits on the nested template instantiation depth
> > (some of the compilers don't have a direct (or any) mechanism of
> increasing
> > the limit).
> > 4) The above looses the opportunity to cut down compilation time on
large
> > sequences.
>
> All good and valid points; it's important for a library to be useable in
the
> real world. What's equally important, however, for a library that aspires
to
> become part of the C++ standard, is to scale well, i.e. to provide a
> no-compromises interface on a "perfect" compiler. Compilers aren't going
to
> get worse with time. Therefore, if you design your library with compiler
> deficiencies in mind, it will become obsolete.

No argument here!

>
> > 5) (IMO) The above is too low-level, and harder to parse and understand
> > when the original 'fold' version.
>
> A fold/reduce version of count_if can indeed be easy to understand [1]
given
> the right background, but the version I presented is a simple rewrite of
the
> STL count_if. When in Rome...

".. do as the Romans"? Well, I don't think that _your_ version falls under
that criteria. You've replaced an iteration primitive (something like
'while' statement) by "manual" recursion, while MPL 'fold'-based
implementation replaces it by another, more high-level library-provided
iteration primitive. It's at least arguable which one is close to the
"original".

>
> --
>
> [1] count_if(v, p) :- fold(v, lambda(x, n)(p(x)? n+1: n), 0).
>
> Your rendition of the above was too hard for me to grok, though.

Is this one better?

    template<
          typename Sequence
        , typename Predicate
>
    struct count_if
    {
        typedef typename fold<
              Sequence
            , integral_c<unsigned long, 0>
            , select_if< apply<Predicate,_2>, next<_1>, _1 >
>::type type;
    };

--
Aleksey

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk