[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Some std::filesystem usage questions
From: |
Greg Chicares |
Subject: |
Re: [lmi] Some std::filesystem usage questions |
Date: |
Thu, 24 Sep 2020 10:37:00 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 |
On 2020-09-23 23:06, Vadim Zeitlin wrote:
> On Wed, 23 Sep 2020 22:33:53 +0000 Greg Chicares <gchicares@sbcglobal.net>
> wrote:
[...non-POSIX paths petulantly dismissed...]
> GC> And we'll quote things as we please.
>
> Note that this means that we'll have to take care of spaces in the path
> too, if we ever read them from somewhere, though. I.e. I understand the
> decision to quote the output value, even if I'm not sure I agree with it.
I don't get it. The stream inserter for std::string doesn't quote strings
that contain spaces, so why should a standard library quote paths? So that
they can be passed to std::fopen()?
> GC> We want what origin/master does today, because it's perfect as is.
>
> It's definitely not perfect in at least one aspect: it mangles non-ASCII
> file names. I didn't want to raise this issue right now, but I did want to
> return to it later and this was just a too perfect opportunity to let it
> pass. So, even though I know that lmi is exclusively US-centric, I still
> think it's a good idea to be able to open file names with "©" or similar
> non-ASCII symbols used even in the US in their names. So I'd also like to
> suggest using UTF-8, as long as we're breaking^W improving things.
I like the idea of UTF-8 everywhere, and hope that someday we might do
:%s/std::string/std::u8string/g
everywhere. Meanwhile, for printing non-ASCII std::filesystem::paths
in error messages, would we need to use something like std::mbrtoc8()?
> GC> IIRC, boost-1.33.1 didn't provide an inserter, so 'path_utility.hpp'
> GC> does [reformatted here for brevity]:
> GC>
> GC> namespace boost{ namespace filesystem{
> GC> inline std::ostream& operator<<(std::ostream& os, fs::path const& z)
> GC> {return os << z.string();}
> GC> } }
>
> However the standard class does define operator<<() (and also >>) and we
> can't opt out from using it, to the best of my knowledge, because it's
> always found using ADL as soon as the argument is a std::filesystem::path.
Can we write a manipulator that causes the "generic" format to be used?
I don't know if that's even possible with what got standardized, but if
not, perhaps someday they'll realize that there's a valid use case for it.
> GC> but I hope there's some elegant way to force our own
> GC>
> GC> inline std::ostream& operator<<(std::ostream& os, std::filesystem::path
> const& z)
> GC> {return os << z.generic_string();}
> GC>
> GC> to take precedence over whatever the standard library provides.
>
> Maybe you have some better ideas, but the only way I see to do it is to
> define our own fs::path as a _wrapper_ around std::filesystem::path, rather
> than a synonym for it. This would definitely allow us to define an
> operator<<() for it behaving as we want and would also allow us to tweak
> its behaviour in other ways.
That sounds like the cleanest solution.
> Initially I thought that having our own class would be an overkill, but
> more I think about having to use generic_string() manually everywhere, more
> I like this idea. It's not like there is going to be much code in this
> class, after all, and it will be practically indistinguishable from the
> standard class anyhow. So, unless you are strongly allergic to this idea,
> I'd like to at least try implementing it.
That's fine by me.