Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2002-11-18 12:52:53


On Mon, 18 Nov 2002 09:25:38 +0100, Pavol Droba <droba_at_[hidden]>
wrote:

>You are probably right that some ideas are confusing without explanation.

In fact the reason why I was perplexed is that everybody seems to
focus on minor issues like the names of the templates, while the
design should be addressed first IMHO. That's odd because people here
are not likely to let errors easily pass.

[snip]
>What I want to do in the future is to change default signature of trim to something
>like you're proposing. There will be a variant with predicate and a set of standard
>predicates. This way the locale stuff will be moved out to the predicate and will
>not confuse you any more, I hope :)

Well, I'm confused by definition :-) Anyhow I think what you are
proposing is actually an algorithm library. It provides
*generalizations* of typical string algorithms. As I hinted at, trim()
can be seen as an algorithm that removes the elements that satisfy a
given predicate from the beginning of any sequence. Now, it's a matter
of how much information you need and how you want to provide it. From
the perspective of generic programming the choice I find natural is a
pair of iterators and a predicate. To do the same job with "spaces"
you need ctype<>, but that's easily solved with an appropriate
functor:

// WARNING: completely untested!!!
//
template <std::ctype_base::mask Type, class charT = char>
class is_classified_as : public std::unary_function<charT, bool>
{
    std::ctype<charT> const & m_ctype;

public:

    // ctor from a ctype
    is_classified_as (std::ctype<charT> & ct) : m_ctype(ct) {}

    // ctor from a locale (for convenience)
    is_classified_as (std::locale const & loc = std::locale())
        : m_ctype(std::use_facet< std::ctype<charT> >(loc)) {}

    bool operator() (charT c) const { return m_ctype.is(Type, c);}

};

What I would see is a bunch of trim variants accepting a predicate
and, separately, a bunch of string-specific versions like e.g:

template <typename StringT>
StringT trim_left(StringT const & str,
                  std::locale const & loc = std::locale())
{
    typename StringT::const_iterator it
        = std::find_if(
            str.begin(),
            str.end(),
            std::not1 (is_classified_as<std::ctype_base::space>())
        );
    
   return StringT(it, str.end());
}

Don't stop too much on the details though, because that's just to
explain the idea.

(BTW if there's interest in a collection of functors like the one
above for integration with STL algorithms as well I'm willing to
volunteer)

Genny.


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