
On Mon, Aug 30, 2004 at 12:12:58PM -0400, Beman Dawes wrote:
My idea is therefore that there should be two types: - An absolute/native path type and - A relative/portable path type
We looked at that approach during initial design, and it just didn't work. The added complexity was really messy, yet the benefits were few.
For example, what does the signature of the exists() function look like if there are two path types? Do we now need two exists() functions? What about functions that take two path arguments? Do those now need four versions? That might just barely be acceptable in the filesystem library itself, but you couldn't inflict that sort of argument explosion on user code. Instead, you would need a base class. That adds complexity. It just gets too messy, and tests to break use cases we really want to work. We really want the user to be able to write:
if fs::exists("foo") ...
rather than:
if fs::exists(fs::relative_path("foo")) ...
--Beman
My idea on this was (and still is) that it is possible to convert a relative path to an absolute path (automatically) by adding an absolute path object reference to the relative path object. This should make sense in every application imho. As a result, you can simply use absolute path types for all those functions that will pass that parameter to a system call. In the case of fs::exists, you would have only fs::exists(fs::native_path const&) and when calling that with a fs::relative_path - it would get expanded to the absolute path even before entering fs::exists (this expanding is necessary anyway - so why not before you do the actual call?). That way there is always only one function needed. Calling fs::exists("foo") would cause the constructor fs::native_path(char const*) to be called, in which case fs::exists would do the expansion internally after seeing that it is not a complete path, using the fs::initial_directory() (or whatever it was called.. the pwd). Same thing for relative_path objects not associated with an absolute fs::native_path object already. Recall that my proposal was that you can do either fs::native_path np("foo%$#@!"); // A relative path using weird chars. if (exists(np)) // Will expand `np' by prepending fs::initial_directory(). or fs::native_path absolute_node; fs::relative_path rp(absolute_node); // Tie `rp' to `absolute_node'. absolute_node = "C:\Program Files"; if (exists(rp)) // Throws if absolute_node is not complete. for the same reason, this should _throw_ and not, like it currently does - just return false because the path doesn't exist: fs::native_path np("/usr/src"); // Note, not possible to use fs::relative_path here (would throw). if (exists(np)) // Should throw on cygwin (with BOOST_WINDOWS) // because the path is not complete! Correct would be for example: #ifdef BOOST_WINDOWS fs::native_path root("C:/cygwin"); #else // ... #endif fs::native_path np = root / "usr/src"; if (exists(np)) // Ok -- Carlo Wood <carlo@alinoe.com>