Boost logo

Boost :

From: Angus Leeming (angus.leeming_at_[hidden])
Date: 2004-10-01 09:15:57


Martin wrote:

> Hi Angus,
>
>> That's two separate requirements.
>> 1. A simple iterator. By 'simple', you mean one using the underlying
>> API.
>> Right?
>
> The standard fs::directory_iterator iterates over everything (files,
> directories, links, devices) in a directory. My assumption is that most
> applications are only interested in a subset of the entries and that the
> filtering in most cases is "simple". e.g. only files ending with ".txt"
> or only directories. This has nothing to do with the underlying API.

Sorry, by "simple" I meant one that used fnmatch or findfirstfile to
perform the filtering rather than a boost::regex.

> Currently I have to do somthing like this for portable code.
>
> for (fs::directory_iterator itr(p); p!= fs::direcory_iterator(); ++p)
> if (fs::is_directory(p, true) || // my own non-throwing overload
> #ifdef BOOST_POSIX
> fs::extension(p) == ".txt"
> #else
> algorithm::iequals(fs::extension(p), ".txt")
> #endif
> )
> constinue;
> ...
>
> I have no problem with the above code but I was hoping that the
> glob_iterator would simplify it. It just seem like an overkill to pull in
> a glob/regex parser to just match "*.txt" on files in one directory when
> that function is already available in both windows "FindFirstFile" and
> posix "fnmatch".

Martin, I think you need

class filtered_directory_iterator
    : public filter_iterator<filter_predicate,
                             filesystem::directory_iterator>
{
    typedef filter_iterator<filter_predicate,
                            filesystem::directory_iterator>
        base;
    typedef filesystem::directory_iterator
        raw_iterator;

public:
    filtered_directory_iterator() {}
    filtered_directory_iterator(std::string const & pattern,
                                int flags,
                                filesystem::path const & wd)
        : base(filter_predicate(pattern, flags), raw_iterator(wd))
    {}
};

where

class filter_predicate {

    std::string pattern;
    int flags;

public:
    filter_predicate(std::string const & p, int f)
        : pattern(p), flags(f) {}

    bool operator()(filesystem::path const & p) const
    {
        // Insert fnmatch, FindFirstFile magic here.
        ...
    }
};

Doesn't that cover it?

>> Again, how do you *limit* them? That implies that you must prescan the
>> pattern, presumably throwing once you've determined that the thing is
>> breaking your "reasonable" limits.
>
> For me it is enough if the pattern is just passed to
> FindFirstFile/fnmatch without parsing. An option could be to do it like
> the fs library and have different pattern checkers (e.g. native, posix,
> windows, portable).

You mean 'native' as above and 'portable' as in my mess? 'posix' and
'windows' get subsumed by 'native', no?

> Since your library is intended for much more complicated things than what
> I have ever had the need for I think I end the discussion here.
>
> Good Luck with your library submission.

I think that I have a way to go yet ;-)
Angus


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