Boost logo

Boost :

Subject: [boost] [algorithm] a unified (but unreadable?) alternative
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-09-29 23:25:10


Hello all,

I just sent my review of Boost.Algorithm. I am sending this email
separately because these are just some ideas for "fun" which should
not clutter the actual review of the library.

I was wondering if it could be possible/useful to combine all the
any/all/one/none_of and any/all/one/none_of functions into 1 single
overloaded check function.

Plus and minuses:
- C++11 already uses all/any/none_of
- Can't really read the check() code better...
+ I can pass any predicate, not just equal.
+ I can check for any count of elements that match the predicate not
just for any, all, one, or none (but also for 10, etc).

For example:

#include <functional>
#include <iostream>

template< typename InIter, typename UnaryPred > // any
bool check ( InIter first, InIter last, UnaryPred p ) {
    std::clog << "unary check count any" << std::endl;
    for(InIter i = first; i != last; ++i) if(p(*i)) return true;
    return false;
}
template< typename InIter, typename UnaryPred > // none/one/all/etc
bool check ( unsigned count, InIter first, InIter last, UnaryPred p ) {
    std::clog << "unary check count " << count << std::endl;
    unsigned c = 0;
    for(InIter i = first; i != last; ++i)
        { if(p(*i)) c++; if(count) return false; }
    return c == count;
}

template< typename InIter, typename BinaryPred, typename V > // any
bool check ( InIter first, InIter last, BinaryPred p, V const& v ) {
    std::clog << "binary check count any" << std::endl;
    for(InIter i = first; i != last; ++i) if(p(*i, v)) return true;
    return false;
}
template< typename InIter, typename BinaryPred, typename V > // none/one/all/etc
bool check ( unsigned count, InIter first, InIter last, BinaryPred p,
        V const& v ) {
    std::clog << "binary check count " << count << std::endl;
    unsigned c = 0;
    for(InIter i = first; i != last; ++i)
        { if(p(*i, v)) c++; if(count) return false; }
    return c == count;
}

// could implement predicate ternary, etc

bool less10 ( unsigned x ) { return x < 10; }

int main ( ) {
    int a[3] = { 1, 2, 3};
    int o[3] = {12, 2, 35};
    int y[3] = { 1, 2, 35};
    int n[3] = {10, 20, 30};

    // unary predicate
    std::cout << check(y, y + 3, less10) << std::endl; // any
    std::cout << check(0, n, n + 3, less10) << std::endl; // none
    std::cout << check(1, o, o + 3, less10) << std::endl; // one
    std::cout << check(3, a, a + 3, less10) << std::endl; // all

    // binary predicate
    std::cout << check(0, a, a + 3, std::equal_to<unsigned>(), 22) // none_equal
            << std::endl;
};

I think I can't easily understand what check() is supposed to do
here... while any/one/none/all are more readable...

Just some ideas :)
--Lorenzo


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