From 1a22c9c113dc8b3f05d1a8c68080f7e97785538d Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Sat, 13 Jul 2019 22:42:30 +0200 Subject: [PATCH 1/6] Fixed the two constructors with locale for path. --- libcxx/include/filesystem | 124 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 5 deletions(-) diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index 3aaa7988a8722..a572b34086113 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -565,6 +565,12 @@ struct _NullSentinal {}; template using _Void = void; +template +struct __is_char : public false_type {}; + +template <> +struct __is_char : public true_type {}; + template struct __is_pathable_string : public false_type {}; @@ -735,11 +741,113 @@ struct _PathCVT { } }; +template ::type>::type> +struct __widen_from_char_iter_pair { + static wstring __convert(_InputIt __b, _InputIt __e, const locale& __loc) { + using _Widener = __widen_from_char_iter_pair; + string __s(__b, __e); + return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); + } +}; + +template +struct __widen_from_char_iter_pair<_InputIt, char> { + static wstring __convert(const char* __b, const char* __e, const locale& __loc) { + // TODO: + } +}; + +template +struct __is_widenable_from_char_string : public false_type {}; + +template +struct __is_widenable_from_char_string< + basic_string> + : true_type { + using _Str = basic_string; + + static wstring __convert(_Str const& __s, const locale& __loc) { + using _Widener = __widen_from_char_iter_pair; + return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); + } +}; + +template +struct __is_widenable_from_char_string< + basic_string_view> + : true_type { + using _Str = basic_string_view; + static wstring __convert(_Str const& __sv, const locale& __loc) { + using _Widener = __widen_from_char_iter_pair; + return _Widener::__convert(__sv.data(), __sv.data() + __sv.size(), __loc); + } +}; + +template ::type, + class _UnqualPtrType = + typename remove_const::type>::type> +struct __is_widenable_from_char_array : false_type {}; + +template +struct __is_widenable_from_char_array<_Source, _ECharT*, char> + : true_type { + + static wstring __convert(const char* __b, const locale& __loc) { + using _Widener = __widen_from_char_iter_pair; + const char __sentinal = char{}; + const char* __e = __b; + for (; *__e != __sentinal; ++__e) + ; + return _Widener::__convert(__b, __e, __loc); + } +}; + +template ::value, + class = char> +struct __is_widenable_from_char_iter : false_type {}; + +template +struct __is_widenable_from_char_iter < + _Iter, true, + typename iterator_traits<_Iter>::value_type > + : true_type { + + static wstring __convert(_Iter __i, const locale& __loc) { + using _Widener = __widen_from_char_iter_pair; + const char __sentinal = char{}; + string __s; + for (; *__i != __sentinal; ++__i) + __s.push_back(*__i); + return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); + } +}; + +template ::value, + bool IsCharArray = __is_widenable_from_char_array<_Tp>::value, + bool _IsIterT = !IsCharArray && __is_widenable_from_char_iter<_Tp>::value> +struct __is_widenable_from_char_source : false_type { + static_assert(!_IsStringT && !IsCharArray && !_IsIterT, "Must all be false"); +}; + +template +struct __is_widenable_from_char_source<_Tp, true, false, false> : __is_widenable_from_char_string<_Tp> {}; + +template +struct __is_widenable_from_char_source<_Tp, false, true, false> : __is_widenable_from_char_array<_Tp> { +}; + +template +struct __is_widenable_from_char_source<_Tp, false, false, true> : __is_widenable_from_char_iter<_Tp> {}; + class _LIBCPP_TYPE_VIS path { template using _EnableIfPathable = typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + template + using _EnableIfWidenableFromCharSource = + typename enable_if<__is_widenable_from_char_source<_SourceOrIter>::value, _Tp>::type; + template using _SourceChar = typename __is_pathable<_Tp>::__char_type; @@ -779,12 +887,18 @@ public: _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); } - // TODO Implement locale conversions. - template > - path(const _Source& __src, const locale& __loc, format = format::auto_format); + template > + path(const _Source& __src, const locale& __loc, + format = format::auto_format) { + using _Widener = __is_widenable_from_char_source<_Source>; + _SourceCVT<_VSTD::wstring>::__append_source(__pn_, _Widener::__convert(__src, __loc)); + } + template - path(_InputIt __first, _InputIt _last, const locale& __loc, - format = format::auto_format); + path(_InputIt __first, _InputIt __last, const locale& __loc, + format = format::auto_format) { + _SourceCVT<_VSTD::wstring>::__append_source(__pn_, __widen_from_char_iter_pair<_InputIt>::__convert(__first, __last, __loc)); + } _LIBCPP_INLINE_VISIBILITY ~path() = default; From ed97fcb1988f1361655ab7432a7187a9aafdf211 Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Sun, 14 Jul 2019 12:53:51 +0200 Subject: [PATCH 2/6] Added proper string widening. --- libcxx/include/__locale | 62 ++++++++++++++++++--------------------- libcxx/include/filesystem | 13 ++++---- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/libcxx/include/__locale b/libcxx/include/__locale index d382e4d8a94be..6aeddf29ecbe2 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -1352,6 +1352,32 @@ struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> } }; +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__widen_using_codecvt(codecvt<_InternT, _ExternT, _StateT> const& __cvt, + _OutputIterator __s, + const char* __nb, const char* __ne) +{ + codecvt_base::result __r = codecvt_base::ok; + mbstate_t __mb; + while (__nb < __ne && __r != codecvt_base::error) + { + const int __sz = 32; + _InternT __buf[__sz]; + _InternT* __bn; + const char* __nn = __nb; + __r = __cvt.in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __nn == __nb) + __throw_runtime_error("locale not supported"); + for (const _InternT* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = (wchar_t)*__p; + __nb = __nn; + } + return __s; +} + template struct __widen_from_utf8 { @@ -1388,23 +1414,7 @@ struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { - result __r = ok; - mbstate_t __mb; - while (__nb < __ne && __r != error) - { - const int __sz = 32; - char16_t __buf[__sz]; - char16_t* __bn; - const char* __nn = __nb; - __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, - __buf, __buf+__sz, __bn); - if (__r == codecvt_base::error || __nn == __nb) - __throw_runtime_error("locale not supported"); - for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) - *__s = (wchar_t)*__p; - __nb = __nn; - } - return __s; + return __widen_using_codecvt(*this, __s, __nb, __ne); } }; @@ -1422,23 +1432,7 @@ struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { - result __r = ok; - mbstate_t __mb; - while (__nb < __ne && __r != error) - { - const int __sz = 32; - char32_t __buf[__sz]; - char32_t* __bn; - const char* __nn = __nb; - __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, - __buf, __buf+__sz, __bn); - if (__r == codecvt_base::error || __nn == __nb) - __throw_runtime_error("locale not supported"); - for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) - *__s = (wchar_t)*__p; - __nb = __nn; - } - return __s; + return __widen_using_codecvt(*this, __s, __nb, __ne); } }; diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index a572b34086113..f057dac567dec 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -565,12 +565,6 @@ struct _NullSentinal {}; template using _Void = void; -template -struct __is_char : public false_type {}; - -template <> -struct __is_char : public true_type {}; - template struct __is_pathable_string : public false_type {}; @@ -753,7 +747,12 @@ struct __widen_from_char_iter_pair { template struct __widen_from_char_iter_pair<_InputIt, char> { static wstring __convert(const char* __b, const char* __e, const locale& __loc) { - // TODO: + wstring __r; + if (has_facet>(__loc)) + return __r; + __r.reserve(__e - __b); + __widen_using_codecvt(use_facet>(__loc) , back_inserter(__r), __b, __e); + return __r; } }; From d8d0d4446a05d3bc977740a78eb71b8702be4dda Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Sun, 14 Jul 2019 23:02:33 +0200 Subject: [PATCH 3/6] Fixed issues. --- libcxx/include/filesystem | 49 +++---- .../path.construct/source_and_locale.pass.cpp | 133 ++++++++++++++++++ 2 files changed, 154 insertions(+), 28 deletions(-) create mode 100644 libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index f057dac567dec..e52d52d6d2999 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -735,26 +735,23 @@ struct _PathCVT { } }; -template ::type>::type> -struct __widen_from_char_iter_pair { - static wstring __convert(_InputIt __b, _InputIt __e, const locale& __loc) { - using _Widener = __widen_from_char_iter_pair; - string __s(__b, __e); - return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); - } -}; - -template -struct __widen_from_char_iter_pair<_InputIt, char> { - static wstring __convert(const char* __b, const char* __e, const locale& __loc) { - wstring __r; - if (has_facet>(__loc)) - return __r; - __r.reserve(__e - __b); - __widen_using_codecvt(use_facet>(__loc) , back_inserter(__r), __b, __e); +inline _LIBCPP_INLINE_VISIBILITY +wstring __widen_from_char_iter_pair(const char* __b, const char* __e, const locale& __loc) { + wstring __r; + if (has_facet>(__loc)) return __r; - } -}; + __r.reserve(__e - __b); + __widen_using_codecvt(use_facet>(__loc) , back_inserter(__r), __b, __e); + return __r; +} + +template ::value, class _Tp>> +inline _LIBCPP_INLINE_VISIBILITY +wstring __widen_from_char_iter_pair(_InputIt __b, _InputIt __e, const locale& __loc) { + const string __s(__b, __e); + return __widen_from_char_iter_pair(__s.data(), __s.data() + __s.size(), __loc); +} template struct __is_widenable_from_char_string : public false_type {}; @@ -766,8 +763,7 @@ struct __is_widenable_from_char_string< using _Str = basic_string; static wstring __convert(_Str const& __s, const locale& __loc) { - using _Widener = __widen_from_char_iter_pair; - return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); + return __widen_from_char_iter_pair(__s.data(), __s.data() + __s.size(), __loc); } }; @@ -777,8 +773,7 @@ struct __is_widenable_from_char_string< : true_type { using _Str = basic_string_view; static wstring __convert(_Str const& __sv, const locale& __loc) { - using _Widener = __widen_from_char_iter_pair; - return _Widener::__convert(__sv.data(), __sv.data() + __sv.size(), __loc); + return __widen_from_char_iter_pair(__sv.data(), __sv.data() + __sv.size(), __loc); } }; @@ -792,12 +787,11 @@ struct __is_widenable_from_char_array<_Source, _ECharT*, char> : true_type { static wstring __convert(const char* __b, const locale& __loc) { - using _Widener = __widen_from_char_iter_pair; const char __sentinal = char{}; const char* __e = __b; for (; *__e != __sentinal; ++__e) ; - return _Widener::__convert(__b, __e, __loc); + return __widen_from_char_iter_pair(__b, __e, __loc); } }; @@ -812,12 +806,11 @@ struct __is_widenable_from_char_iter < : true_type { static wstring __convert(_Iter __i, const locale& __loc) { - using _Widener = __widen_from_char_iter_pair; const char __sentinal = char{}; string __s; for (; *__i != __sentinal; ++__i) __s.push_back(*__i); - return _Widener::__convert(__s.data(), __s.data() + __s.size(), __loc); + return __widen_from_char_iter_pair(__s.data(), __s.data() + __s.size(), __loc); } }; @@ -896,7 +889,7 @@ public: template path(_InputIt __first, _InputIt __last, const locale& __loc, format = format::auto_format) { - _SourceCVT<_VSTD::wstring>::__append_source(__pn_, __widen_from_char_iter_pair<_InputIt>::__convert(__first, __last, __loc)); + _SourceCVT<_VSTD::wstring>::__append_source(__pn_, __widen_from_char_iter_pair(__first, __last, __loc)); } _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp new file mode 100644 index 0000000000000..94078c65b2452 --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// + +// class path + +// template +// path(const Source& source); +// template +// path(InputIterator first, InputIterator last); + + +#include "filesystem_include.hpp" +#include +#include +#include +#include + +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +std::ofstream ofs ("/tmp/test.txt", std::ofstream::out); + +template +void RunTestCaseImpl(MultiStringType const& MS, Args... args) { + using namespace fs; + std::locale Locale; + const char* Expect = MS; + const CharT* TestPath = MS; + const CharT* TestPathEnd = StrEnd(TestPath); + const std::size_t Size = TestPathEnd - TestPath; + const std::size_t SSize = StrEnd(Expect) - Expect; + assert(Size == SSize); + // StringTypes + { + const std::basic_string S(TestPath); + path p(S, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + assert(p.string() == S); + } + { + const std::basic_string_view S(TestPath); + path p(S, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + assert(p.string() == S); + } + // Char* pointers + { + path p(TestPath, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + } + { + path p(TestPath, TestPathEnd, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + } + // Iterators + { + using It = input_iterator; + path p(It{TestPath}, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + } + { + using It = input_iterator; + path p(It{TestPath}, It{TestPathEnd}, Locale, args...); + assert(p.native() == Expect); + assert(p.string() == TestPath); + } +} + +template +void RunTestCase(MultiStringType const& MS) { + RunTestCaseImpl(MS); + RunTestCaseImpl(MS, fs::path::format::auto_format); + RunTestCaseImpl(MS, fs::path::format::native_format); + RunTestCaseImpl(MS, fs::path::format::generic_format); +} + +void test_sfinae() { + using namespace fs; + { + using It = const char* const; + static_assert(std::is_constructible::value, ""); + } + { + using It = input_iterator; + static_assert(std::is_constructible::value, ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const char; + using pointer = const char*; + using reference = const char&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator; + static_assert(std::is_constructible::value, ""); + } + { + using It = output_iterator; + static_assert(!std::is_constructible::value, ""); + + } + { + static_assert(!std::is_constructible::value, ""); + } +} + +int main(int, char**) { + for (auto const& MS : PathList) { + const char* s = MS; + ofs << "YOooooooooooooooooooo" << s << std::endl; + RunTestCase(MS); + } + test_sfinae(); + + return 0; +} From 4773c89fa7947a297c9661cc20c88a66a435e301 Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Mon, 15 Jul 2019 23:17:03 +0200 Subject: [PATCH 4/6] Fixed bad early return. --- libcxx/include/filesystem | 4 +- .../path.construct/source_and_locale.pass.cpp | 82 +++++++++++-------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index e52d52d6d2999..0b482d53bbac8 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -738,7 +738,7 @@ struct _PathCVT { inline _LIBCPP_INLINE_VISIBILITY wstring __widen_from_char_iter_pair(const char* __b, const char* __e, const locale& __loc) { wstring __r; - if (has_facet>(__loc)) + if (!has_facet>(__loc)) return __r; __r.reserve(__e - __b); __widen_using_codecvt(use_facet>(__loc) , back_inserter(__r), __b, __e); @@ -746,7 +746,7 @@ wstring __widen_from_char_iter_pair(const char* __b, const char* __e, const loca } template ::value, class _Tp>> + class = typename enable_if::value>::type> inline _LIBCPP_INLINE_VISIBILITY wstring __widen_from_char_iter_pair(_InputIt __b, _InputIt __e, const locale& __loc) { const string __s(__b, __e); diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp index 94078c65b2452..2a45ed013d9d2 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp @@ -29,67 +29,54 @@ #include "min_allocator.h" #include "filesystem_test_helper.hpp" -std::ofstream ofs ("/tmp/test.txt", std::ofstream::out); - -template -void RunTestCaseImpl(MultiStringType const& MS, Args... args) { +template +void RunTestCase(const char* TestPath, const char* Expect, std::locale Locale, Args... args) { using namespace fs; - std::locale Locale; - const char* Expect = MS; - const CharT* TestPath = MS; - const CharT* TestPathEnd = StrEnd(TestPath); + const char* TestPathEnd = StrEnd(TestPath); const std::size_t Size = TestPathEnd - TestPath; const std::size_t SSize = StrEnd(Expect) - Expect; assert(Size == SSize); // StringTypes { - const std::basic_string S(TestPath); - path p(S, Locale, args...); + const std::string S(TestPath); + path p(S, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); - assert(p.string() == S); + assert(p.string() == TestPath); + assert(p.string() == S); } { - const std::basic_string_view S(TestPath); - path p(S, Locale, args...); + const std::string_view S(TestPath); + path p(S, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); - assert(p.string() == S); + assert(p.string() == TestPath); + assert(p.string() == S); } // Char* pointers { path p(TestPath, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == TestPath); } { path p(TestPath, TestPathEnd, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == TestPath); } // Iterators { - using It = input_iterator; + using It = input_iterator; path p(It{TestPath}, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == TestPath); } { - using It = input_iterator; + using It = input_iterator; path p(It{TestPath}, It{TestPathEnd}, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == TestPath); } } -template -void RunTestCase(MultiStringType const& MS) { - RunTestCaseImpl(MS); - RunTestCaseImpl(MS, fs::path::format::auto_format); - RunTestCaseImpl(MS, fs::path::format::native_format); - RunTestCaseImpl(MS, fs::path::format::generic_format); -} - void test_sfinae() { using namespace fs; { @@ -121,12 +108,41 @@ void test_sfinae() { } } +struct CustomCodeCvt : std::codecvt { +protected: + result do_in(state_type&, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const override { + for (; __frm < __frm_end && __to < __to_end; ++__frm, ++__to) + *__to = 'o'; + + __frm_nxt = __frm; + __to_nxt = __to; + + return result::ok; + } +}; + int main(int, char**) { + std::locale Locale; + std::locale CustomLocale(Locale, new CustomCodeCvt()); + + // Ensure std::codecvt is used. + std::string TestPath("aaaa"); + std::string Expect("oooo"); + RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale); + RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale, fs::path::format::auto_format); + RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale, fs::path::format::native_format); + RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale, fs::path::format::generic_format); + + // Test on paths with global locale. for (auto const& MS : PathList) { - const char* s = MS; - ofs << "YOooooooooooooooooooo" << s << std::endl; - RunTestCase(MS); + RunTestCase(MS, MS, Locale); + RunTestCase(MS, MS, Locale, fs::path::format::auto_format); + RunTestCase(MS, MS, Locale, fs::path::format::native_format); + RunTestCase(MS, MS, Locale, fs::path::format::generic_format); } + test_sfinae(); return 0; From a3f48749cd13de57b9c8b9ace455c5c1c7804813 Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Tue, 16 Jul 2019 21:36:08 +0200 Subject: [PATCH 5/6] Fixed tests for creating a path from a locale. --- libcxx/include/filesystem | 2 +- .../path.construct/source_and_locale.pass.cpp | 60 ++++++++++++------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index 0b482d53bbac8..29d3a44ec2039 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -802,7 +802,7 @@ struct __is_widenable_from_char_iter : false_type {}; template struct __is_widenable_from_char_iter < _Iter, true, - typename iterator_traits<_Iter>::value_type > + typename remove_reference::value_type>::type > : true_type { static wstring __convert(_Iter __i, const locale& __loc) { diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp index 2a45ed013d9d2..716b26ef6af28 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp @@ -41,39 +41,37 @@ void RunTestCase(const char* TestPath, const char* Expect, std::locale Locale, A const std::string S(TestPath); path p(S, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); - assert(p.string() == S); + assert(p.string() == Expect); } { const std::string_view S(TestPath); path p(S, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); - assert(p.string() == S); + assert(p.string() == Expect); } // Char* pointers { path p(TestPath, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == Expect); } { path p(TestPath, TestPathEnd, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == Expect); } // Iterators { using It = input_iterator; path p(It{TestPath}, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == Expect); } { using It = input_iterator; path p(It{TestPath}, It{TestPathEnd}, Locale, args...); assert(p.native() == Expect); - assert(p.string() == TestPath); + assert(p.string() == Expect); } } @@ -81,11 +79,11 @@ void test_sfinae() { using namespace fs; { using It = const char* const; - static_assert(std::is_constructible::value, ""); + static_assert(std::is_constructible::value, ""); } { using It = input_iterator; - static_assert(std::is_constructible::value, ""); + static_assert(std::is_constructible::value, ""); } { struct Traits { @@ -96,28 +94,47 @@ void test_sfinae() { using difference_type = std::ptrdiff_t; }; using It = input_iterator; - static_assert(std::is_constructible::value, ""); + static_assert(std::__is_input_iterator::value, ""); + //static_assert(std::is_constructible::value, ""); + } + { + using It = const wchar_t* const; + static_assert(!std::is_constructible::value, ""); + } + { + using It = input_iterator; + static_assert(!std::is_constructible::value, ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const wchar_t; + using pointer = const wchar_t*; + using reference = const wchar_t&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator; + static_assert(!std::is_constructible::value, ""); } { using It = output_iterator; - static_assert(!std::is_constructible::value, ""); - + static_assert(!std::is_constructible::value, ""); } { - static_assert(!std::is_constructible::value, ""); + static_assert(!std::is_constructible::value, ""); } } struct CustomCodeCvt : std::codecvt { protected: result do_in(state_type&, - const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, - intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const override { - for (; __frm < __frm_end && __to < __to_end; ++__frm, ++__to) - *__to = 'o'; + const extern_type* from, const extern_type* from_end, const extern_type*& from_next, + intern_type* to, intern_type* to_end, intern_type*& to_next) const override { + for (; from < from_end && to < to_end; ++from, ++to) + *to = 'o'; - __frm_nxt = __frm; - __to_nxt = __to; + from_next = from; + to_next = to; return result::ok; } @@ -125,9 +142,9 @@ struct CustomCodeCvt : std::codecvt { int main(int, char**) { std::locale Locale; - std::locale CustomLocale(Locale, new CustomCodeCvt()); // Ensure std::codecvt is used. + std::locale CustomLocale(Locale, new CustomCodeCvt()); std::string TestPath("aaaa"); std::string Expect("oooo"); RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale); @@ -135,7 +152,6 @@ int main(int, char**) { RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale, fs::path::format::native_format); RunTestCase(TestPath.c_str(), Expect.c_str(), CustomLocale, fs::path::format::generic_format); - // Test on paths with global locale. for (auto const& MS : PathList) { RunTestCase(MS, MS, Locale); RunTestCase(MS, MS, Locale, fs::path::format::auto_format); From 8d0dfaadee5fb68dd42ba874995185e155d58ff7 Mon Sep 17 00:00:00 2001 From: Jean Guegant Date: Tue, 16 Jul 2019 21:51:20 +0200 Subject: [PATCH 6/6] Removed usage of iostream. --- .../path.member/path.construct/source_and_locale.pass.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp index 716b26ef6af28..1de00e824e7d1 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source_and_locale.pass.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include "test_macros.h" #include "test_iterators.h"