|
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