Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2002-04-08 15:54:24

At 03:58 PM 4/1/2002, Jan Langer wrote:

>On Mon, 1 Apr 2002, Stewart, Robert wrote:
>>> I also think that reg. exp. matching should be done through a
>>> predicate, if
>>> nothing else to avoid the dependency of the filesystem
>>> library the on reg. exp.
>>> library.
>>That's an excellent reason to rely on a predicate to handle the RE
>>matching. A standard predicate that uses an RE can be supplied in a
>>separate header. (Obviously, an overload of the function could be
>>in that separate header, too.)
>i am also in favour of this. using predicates is more general.
>we need only the predicate version which uses a return_true predicate

>as default argument. this would also solve the RE forward decl.
>problem because you only need the regexp header in the implementation

>of this predicate.
>probably it is possible to drop some of the options in favour of
>predicates. for example using
> remove ("dirpath", optional);
>with a functor optional
> class optional ...
> bool operator () (std::string const &path)
> {
> return exsts (path);
> }
> ...
> };
>and a class non_optional with
> bool operator () (std::string const &path)
> {
> if (!exists (path))
> {
> throw ...;
> }
> return true;
> }
>which is the default argument.
>this could be a easy to use, extendible system which decouples the
>options from the actual filesystem operation itself. the
>of remove has not to care for combinations of certain options a user
>probably uses.

That deals nicely with some of the issues, but might have to be
extended with a more general policy class to be able to take care of
some of the other issues. For example, whether or not to recurse into

One of the reasons I've delayed in answering this is that I wanted to
build more experience actually writing some code.

for a program to generate regression test HTML from the residue left
over from running boost-root/status/Jamfile. An example of the
generated HTML is

The only filesystem features used directly were exists(),
is_directory(), and the directory iterators. Indirectly, via the
iterators, directory_contents was also used.

I wrote this code in the "script" mind set we postulated would be the
common use. It evolved quite a bit over time, but was very easy to
write and at no point became unmanagable. There were very few bugs
during development, even though parts were hacked at night when I was
tired and grouchy.

So I am feeling that exists(), is_directory(), and the
directory_iterator and directory_contents classes are about right.

Notice the find_file function:

// find_file ------------------------------------------//
// given a directory to recursively search

   bool find_file( const string & dir_path, const string & name,
     string & path_found, const string & ignore_dir_named="" )
     for ( fs::directory_iterator itr( dir_path );
           itr != end_itr; ++itr )
       if ( fs::is_directory( itr->path() )
         && itr->name() != ignore_dir_named )
         if ( find_file( itr->path(), name, path_found ) )
            return true;
       else if ( itr->name() == name )
         path_found = itr->path();
         return true;
     return false;

This is a convenience function we never envisioned when we were talking
about remove, copy, etc. But it was so easy to write (and then later
hack by adding the argument ignore_dir_named so the code could be

Now you could say boost/filesystem/directory.hpp should contain a
generalized version of such a function. You could also say "Look how
simple find_file() is! Maybe it shows we don't need the generalized
copy() and replace() functions at all!"



Boost list run by bdawes at, gregod at, cpdaniel at, john at