lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] Some std::filesystem usage questions


From: Vadim Zeitlin
Subject: [lmi] Some std::filesystem usage questions
Date: Wed, 23 Sep 2020 21:09:42 +0200

 Hello,

 Transition from Boost.Filesystem to std::filesystem was mostly painless
and even pleasant, as it allowed to get rid of some not very pretty code,
notably we don't need initialize_filesystem() any more. However there are a
couple of points where the behaviour has changed in a maybe not so great
way and I'd like to ask for your opinion about how should we deal with
them.

 Both problems can be seen with the following snippet:

        std::cout << (fs::path{"/dir/subdir"} / fs::path{"filename"}) << "\n";

The output, under MSW, is

        "/dir/subdir\\file.name"

which shows both of the issues:

1. We get an ugly mixture of slashes and backslashes, as any slashes
   present in the source code remain, but operator/() uses the native
   path separator, i.e. a backslash under MSW.

2. Backslashes are doubled and the entire path is double quoted because
   operator<<(std::ostream, fs::path) uses std::quoted() by default in
   order to round-trip paths with spaces in them successfully and this
   is the result.

 Neither of the problems is fatal, of course, and the simplest solution is
to just ignore them -- and if you don't see anything wrong with this,
please let me know and you don't even need to read the rest of this email.

 If we want to have some nicer output, e.g. in error messages, we first
need to decide what kind of output do we want, i.e. whether we want to
(consistently) use backslashes under MSW, or use slashes there (and
everywhere). In the former case, we need to use lexically_normal() path
member function to normalize it before probably using string() to convert
it to a string explicitly, because while I don't mind the quotes added by
operator<<() too much (we actually already always use single quotes around
the file names we output anyhow), doubling backslashes looks just ugly IMO.
In the latter case, we don't need to normalize it, but we do need to use
generic_string() for string conversion, as the default operator<<()
implementation won't do it for us.

 So I think there are 3 reasonable choices:

0. Do nothing and just rely on the default output format, ugly as it is.
   This is the simplest at the code level as we can just do "oss << path",
   just as we already do. Note that this will still require some changes,
   however, as we'll need to remove the single quotes around the paths in
   the current output code because having both single and double quotes
   around them would be too much.

1. Embrace the dark side and use platform-specific output format, i.e.
   "oss << path.lexically_normal().string()". This should be the most
   familiar to the users, so probably preferable, but would require
   carefully using this construction everywhere (we could define a helper
   function to do it, of course) and not forgetting it. It's also a change
   compared to the current behaviour, which uses slashes even under MSW.

2. Stick to POSIX conventions and use "oss << path.generic_string()". This
   still suffers from a similar problem as the previous solution, i.e. we'd
   need not only add all these calls to generic_string() right now, but
   also keep not forgetting to add them in the future.

 Which one of these solutions would you prefer? Or maybe you see some other
one, that I've missed? For reference, this concise description of fs::path

        https://en.cppreference.com/w/cpp/filesystem/path

can be helpful, as it describes the various formats and contains links to
the documentation of all the functions I mentioned above.

 Thanks in advance for your answer,
VZ

Attachment: pgpwUcfr4_3Tj.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]