|
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