-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[libc++] Implement LWG3430 disallow implicit conversion of the source arguments to std::filesystem::path
when constructing std::basic_*fstream
#85079
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
Changes from 1 commit
50656d0
5e995e9
3090674
0116f4a
af85858
44b09c5
41aab57
eca5675
2babb84
fe70853
79a0973
e59fcb2
8da6092
bae96cf
917f988
1e073cd
aaad833
616c732
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -78,8 +78,7 @@ public: | |||||||
basic_ifstream(); | ||||||||
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); | ||||||||
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); | ||||||||
explicit basic_ifstream(const filesystem::path& p, | ||||||||
ios_base::openmode mode = ios_base::in); // C++17 | ||||||||
template<class T> explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++17 | ||||||||
basic_ifstream(basic_ifstream&& rhs); | ||||||||
|
||||||||
basic_ifstream& operator=(basic_ifstream&& rhs); | ||||||||
|
@@ -117,8 +116,7 @@ public: | |||||||
basic_ofstream(); | ||||||||
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); | ||||||||
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); | ||||||||
explicit basic_ofstream(const filesystem::path& p, | ||||||||
ios_base::openmode mode = ios_base::out); // C++17 | ||||||||
template<class T> explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17 | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||||||||
basic_ofstream(basic_ofstream&& rhs); | ||||||||
|
||||||||
basic_ofstream& operator=(basic_ofstream&& rhs); | ||||||||
|
@@ -158,8 +156,8 @@ public: | |||||||
basic_fstream(); | ||||||||
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); | ||||||||
explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); | ||||||||
explicit basic_fstream(const filesystem::path& p, | ||||||||
ios_base::openmode mode = ios_base::in|ios_base::out); C++17 | ||||||||
template<class T> | ||||||||
explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17 | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, https://en.cppreference.com/w/cpp/io/basic_fstream/basic_fstream mentions a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That constructor already exists: llvm-project/libcxx/include/fstream Lines 1413 to 1415 in a417b9b
It's definitely expected that you can't open an fstream with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want that conversion, you can still do it explicitly: std::fstream model_file(filesystem::path(ml_package_dir()
.Append(kMlPackageDataDir)
.Append(kMlPackageModelFileName)
.value()),
std::ios::out | std::ios::binary); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I suppose I need to call (The point stands that this breaks existing code, though.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's indeed correct this may break existing code. Louis tested this at Apple, based on the results we applied the possibly breaking change. Is the breakage for you worse? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like it's just one file so far (). I got a bit confused because the wchar_t ctor is missing from the synopsis comment at the top. So all good. *: But actually rolling this in is blocked on #86843 (comment) , so not 100% sure yet. But very likely that's all. |
||||||||
basic_fstream(basic_fstream&& rhs); | ||||||||
|
||||||||
basic_fstream& operator=(basic_fstream&& rhs); | ||||||||
|
@@ -1043,8 +1041,9 @@ public: | |||||||
# endif | ||||||||
_LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); | ||||||||
# if _LIBCPP_STD_VER >= 17 | ||||||||
template <class _Tp, std::enable_if_t<std::is_same_v<_Tp, std::filesystem::path>>* = nullptr> | ||||||||
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream( | ||||||||
const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) | ||||||||
const _Tp& __p, ios_base::openmode __mode = ios_base::in) | ||||||||
mordante marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
: basic_ifstream(__p.c_str(), __mode) {} | ||||||||
# endif // _LIBCPP_STD_VER >= 17 | ||||||||
_LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs); | ||||||||
|
@@ -1197,8 +1196,9 @@ public: | |||||||
_LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); | ||||||||
|
||||||||
# if _LIBCPP_STD_VER >= 17 | ||||||||
template <class _Tp, std::enable_if_t<std::is_same_v<_Tp, std::filesystem::path>>* = nullptr> | ||||||||
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream( | ||||||||
const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) | ||||||||
const _Tp& __p, ios_base::openmode __mode = ios_base::out) | ||||||||
: basic_ofstream(__p.c_str(), __mode) {} | ||||||||
# endif // _LIBCPP_STD_VER >= 17 | ||||||||
|
||||||||
|
@@ -1356,8 +1356,9 @@ public: | |||||||
ios_base::openmode __mode = ios_base::in | ios_base::out); | ||||||||
|
||||||||
# if _LIBCPP_STD_VER >= 17 | ||||||||
template <class _Tp, std::enable_if_t<std::is_same_v<_Tp, std::filesystem::path>>* = nullptr> | ||||||||
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream( | ||||||||
const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) | ||||||||
const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) | ||||||||
: basic_fstream(__p.c_str(), __mode) {} | ||||||||
# endif // _LIBCPP_STD_VER >= 17 | ||||||||
|
||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,11 +21,18 @@ | |
#include <fstream> | ||
#include <filesystem> | ||
#include <cassert> | ||
#include <type_traits> | ||
mordante marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#include "test_macros.h" | ||
#include "platform_support.h" | ||
|
||
namespace fs = std::filesystem; | ||
|
||
struct fake_path {}; | ||
|
||
static_assert(std::is_constructible_v<std::fstream, fs::path>); | ||
static_assert(!std::is_constructible_v<std::fstream, fake_path>); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that these code compiles even without this pull request because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! And thanks for your review! I've refined the test cases, also the title need update.
|
||
|
||
int main(int, char**) { | ||
fs::path p = get_temp_file_name(); | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done