Boost logo

Boost :

Subject: [boost] FW: [filesystem] : basic_path : Feature request
From: Rob (robrimmer_at_[hidden])
Date: 2009-02-07 05:55:49


> These seem like reasonable requests, although I'd have to check the
> std::back_inserter to be 100% sure.
>
I have checked this using a wrapper around path as follows

template<class String, class Traits>
struct rob_basicpath
  : boost::filesystem::basic_path<String, Traits>
{
  typedef string_type& reference;
  typedef const string_type& const_reference;
        
  inline void push_back(const_reference path)
  {
    *this /= path;
  }
};

This allowed me to use the following code as expected (which strips .
characters from the path)

const boost::filesystem::path path("dir1/./dir2/./dir3");
rob_path rpath;
std::remove_copy(path.begin(), path.end(), std::back_inserter(rpath), ".");

> Note however that path has some but not all of the characteristics of
> a standard container. I'd want to see persuasive use cases for adding
> functionality - just making path more like a std container without
> good reason is likely to lead to interface bloat without offsetting
> benefits.

My reasoning for this is as follows:

1. path is wrapper around a string, which is what would be used in the
absence of path object. String supports this interface and using path
should not be a step backwards.

2. A variety of tasks I envisage on a path can be neatly and succinctly
implemented using std algorithms. In particular, I have several uses for
copy or remove_copy to create similar paths with a slight difference. The
ability to use a back_inserter allow paths to be built up from other paths
or any container of strings. Without this, my solution for removing '.'
involved the same code but I had to insert into a vector first and later
iterate through this to create the new path.

> A use case would make this [pop_back()] more compelling.

My code above to remove '.' was part of a 'canonicalize' function which
removed both '.' and '..' where possible. (This may be a candidate for a
convenience function within the library?)
My solution was as follows

std::vector<std::wstring> parts;
BOOST_FOREACH(std::wstring part, path)
{
  if (L"." == part) continue;
  if (L".." == part && parts.size() && L".." != parts.back())
parts.pop_back();
  else parts.push_back(part);
}
boost::filesystem::wpath simple;
BOOST_FOREACH(std::wstring part, parts) simple /= part;
return simple;

Whilst this is IMO reasonably elegant, I still have the extra step of
building my new path in a vector, then creating the path from this. The
addition of pop_back() to path would allow the path to be built up without
the vector.
Given that path allows the path to be considered as a container of path
elements, I would like to see this extended.
A reverse iterator would be nice to step back from the given path up to the
root.
Pop_back would equate to stepping back to the parent directory and seems a
useful feature. Given that there exists a function to remove the filename,
this also seems to be relatively easy to implement (as an inlined function?)

I have only recently discovered filesystem::path and, given my current
project's requirements for directory manipulation, this is a fantastic help.

Cheers

Rob


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