-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
of::filesystem::path with implicit narrow string conversion #8162
base: master
Are you sure you want to change the base?
Conversation
NOTE: Core OF compiles in VS CI; some ofxTests are failing when comparing empty «default directory» paths, but it might be due to transitionary process within ofFileUtils. Before digging into that it would be preferable to assess if this approach is worthwhile. Also seems |
Also, i guess this raises another question: do we need to import we could just have an the advantage of not overlaying is that it's just a new class and no funny [edit to add]: on non-windows, |
Thank you so much @artificiel - this is really exciting to see. I do like the idea of That said if its clearly its own thing which can return a string, a wstring and a std::filesystem::path then maybe if you need the std::filesystem::path functionality you can always do that explicitly. Are you mimicking all the std::filesystem::path functionality? I'd be curious what @dimitre thinks. A few errors in the tests: This is the error on emscripten:
And it looks like some of the filesystem tests are failing on linux.
|
@ofTheo: it's at the point that OF itself and common/example apps compiles. the API is not so complex, and the data somewhat immutable-ish (very few operations change the actual path). so, assuming someone with MSVC takes this and compiles stuff and tests the limits and we decide to go forward with this approach, i'm not seeing so many edge cases we won't catch. and concretely in the OF context, we are targeting the transparent upgrade of about the failing tests: some are involving the empty string error ] #4563 test2 failed
[ error ] test_eq(ofToDataPath("data.txt"), "data/data.txt")
[ error ] value1: ofToDataPath("data.txt") is data/data.txt
[ error ] value2: "data/data.txt" is data/data.txt
but again, if the design decision to go ahead with something like this is taken, i'm sure these kinks will be fixable. |
I do notice that paths print out via cout with quotes vs string. Not sure if that is the reason the test_eq is failing but agree most likely fixable. @roymacdonald, would you feel like giving this PR a whirl on Windows? |
@dimitre your point makes it a good to summarize (I understand the comment thread here is a bit messy!) so there are 2 independent questions:
in essence, I focus my view on the notion of removing as much as possible surface, unless required. |
now std::filesystem is mature we can surely stick to it if we choose OF to be c++17 or newer. |
Can we add std::string as input path as well.
We just want to type like the old days...
Happy to add a PR btw let me know |
@GitBruno the current git/nightly already implements std::string ofToDataPath(const of::filesystem::path & path, bool absolute = false); as both the real feature here is to change the return type to of::filesystem::path ofToDataPath(const of::filesystem::path & path, bool absolute = false); in a manner that will implictely convert to narrow auto aaa = ofToDataPath("yes.txt"); // aaa is of::filesystem::path everywhere
std::string bad = ofToDataPath("no.txt"); // FAILS in windows without this PR
std::string good = ofToDataPath("yes.txt"); // works in windows with this PR the correct way of working with filesystem path representation in a complete safe crossplatform manner is to adopt it's unfortunate that MS did not envision the crossplatformability of BTW if you are in a position to test this branch on actual windows it would be great, even more so if you happen to use unicode files and directories! any code that represent filesystem paths as |
Yes the current implementation is a problem for me as Current Implementation as mentioned:
Therefore I was suggesting to add the following overload function:
of::filesystem::path might have an overloading operator for std::string() but std::string does not have an overloading operator for of::filesystem::path(). On a side note, it might also be good to be able to write like this:
However with a const& I'll have to resort to this:
As far as I know the reference is not used as a reference and get copied anyway? So I do not see any benefits to use a reference here. |
@GitBruno just to be sure, if you are having a problem with what is in the current branch (not specifically this PR) please post a freestanding issue as this PR is only adding an implicit conversion operator for (to clarify things, outside of this PR, |
FOR DISCUSSION
[edited (
strikethroughvs bold) to take into account the progress done vs discussions below]I’m not sure what is the current "future view" of
of::filesystem::path
(topic is addressed in a few different PR/issues) but after considering the fact that MSVC does not provide an implicit narrow string conversion operator,and considering we are already importing[edit: the proposal morphed from the initialstd::filesystem
asof::filesystem
, the idea of overlaying a customof::filesystem::path
, based exactly onstd::filesystem::path
interface but adding the «missing» conversion, sounds feasible.of::filesystem
clone ofstd::filesystem
, to embracingstd::filesystem
and provide a single classof::filesystem::path
that covers the missing implicit conversion on windows]The goal is to support MSVC where
std::string
is implied in variables or arguments, without arguing against the design ofstd::filesystem
or::path
, and letting modernization occur in parallel with backwards-compatibility.I unfortunately am not in a position to try things in MSVC so it’s not the most productive process, but this PR implements such a «wrapper» class, where
string
andwstring
can be thrown in & out ofof::filesystem::path
implicitly and explicitly. [edit: also our methods take and produce of::filesystem::path, which can accept a std::filesystem::path, and will implicitely convert to std::filesystem::path (bascially extracting the underlying path_) when dropped into std::filesystem::exists() et al. this leverages all the work already done to supportof::filesystem::path
]Note: the idea of composing with a private
std::filesystem::path path_
has been made for 2 reasons: (1) std stuff is generally not inheritance-friendly and (2) have the path inheriting path might cause confusion — having a member with a fully-qualified, privatestd::filesystem::path
type makes things unambiguous.Note2: it's a bit cumbersome as it's mostly boiler-plate (and maybe some stuff is still missing; this is for discussion/experimentation),
but allows the flexibility of augmenting[edit: this is now discouraged, the idea is to be as 1:1 as possible with std::filesystem::path], while maintaining compatibility with any generic::path
with useful features in the OF contextstd::filesystem::path
documentation and examples.If someone with MSVC can try this and see what happens it would be great (some methods involving ofFile had to be tweaked, and for some reasons comparison operator are finicky too, if you get errors please check if it's only missing a bit of API)
Also, in
ofConstants.h
I simply inserted the mod at the place where the various#ifdef
are true in my position; please double-check you end up in the same spot.[edit]: a possible
ofConstants.h
implementation:test snippet: