Fix filesystem::path for iterators with const value_type
authorJonathan Wakely <jwakely@redhat.com>
Fri, 28 Oct 2016 17:47:57 +0000 (18:47 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 28 Oct 2016 17:47:57 +0000 (18:47 +0100)
* include/experimental/bits/fs_path.h
(path::_S_convert<_Iter>(_Iter, _Iter)): Remove cv-qualifiers from
iterator's value_type.
(path::_S_convert<_Iter>(_Iter __first, __null_terminated)): Likewise.
Do not use operation not supported by input iterators.
(path::__is_path_iter_src): Add partial specialization for const
encoded character types.
* testsuite/experimental/filesystem/path/construct/range.cc: Test
construction from input iterators with const value types.

From-SVN: r241654

libstdc++-v3/ChangeLog
libstdc++-v3/include/experimental/bits/fs_path.h
libstdc++-v3/testsuite/experimental/filesystem/path/construct/range.cc

index 61afd6b..37f7455 100644 (file)
@@ -1,5 +1,15 @@
 2016-10-28  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/experimental/bits/fs_path.h
+       (path::_S_convert<_Iter>(_Iter, _Iter)): Remove cv-qualifiers from
+       iterator's value_type.
+       (path::_S_convert<_Iter>(_Iter __first, __null_terminated)): Likewise.
+       Do not use operation not supported by input iterators.
+       (path::__is_path_iter_src): Add partial specialization for const
+       encoded character types.
+       * testsuite/experimental/filesystem/path/construct/range.cc: Test
+       construction from input iterators with const value types.
+
        * doc/xml/manual/status_cxx2017.xml: Update status.
        * doc/html/*: Regenerate.
        * include/std/type_traits (has_unique_object_representations): Guard
index 4d7291f..f6a290d 100644 (file)
@@ -385,7 +385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       _S_convert(_Iter __first, _Iter __last)
       {
        using __value_type = typename std::iterator_traits<_Iter>::value_type;
-       return _Cvt<__value_type>::_S_convert(__first, __last);
+       return _Cvt<remove_cv_t<__value_type>>::_S_convert(__first, __last);
       }
 
     template<typename _InputIterator>
@@ -393,10 +393,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       _S_convert(_InputIterator __src, __null_terminated)
       {
        using _Tp = typename std::iterator_traits<_InputIterator>::value_type;
-       std::basic_string<_Tp> __tmp;
-       while (*__src != _Tp{})
-         __tmp.push_back(*__src++);
-       return _S_convert(__tmp.data(), __tmp.data() + __tmp.size());
+       std::basic_string<remove_cv_t<_Tp>> __tmp;
+       for (; *__src != _Tp{}; ++__src)
+         __tmp.push_back(*__src);
+       return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size());
       }
 
     static string_type
@@ -571,6 +571,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
     struct path::__is_encoded_char<char32_t> : std::true_type
     { using value_type = char32_t; };
 
+  template<typename _Tp>
+    struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { };
+
   struct path::_Cmpt : path
   {
     _Cmpt(string_type __s, _Type __t, size_t __pos)
index b68e65d..3dfec2f 100644 (file)
@@ -24,6 +24,7 @@
 #include <experimental/filesystem>
 #include <string>
 #include <testsuite_fs.h>
+#include <testsuite_iterators.h>
 
 using std::experimental::filesystem::path;
 using __gnu_test::compare_paths;
@@ -54,6 +55,52 @@ test01()
     compare_paths(p1, p7);
     compare_paths(p1, p8);
 #endif
+
+    using __gnu_test::test_container;
+    using __gnu_test::input_iterator_wrapper;
+    // Test with input iterators and const value_types
+    test_container<char, input_iterator_wrapper>
+      r1(&s.front(), &s.front() + s.size());
+    path p9(r1.begin(), r1.end());
+    compare_paths(p1, p9);
+
+    test_container<char, input_iterator_wrapper>
+      r2(&s.front(), &s.front() + s.size() + 1); // includes null-terminator
+    path p10(r2.begin());
+    compare_paths(p1, p10);
+
+    test_container<const char, input_iterator_wrapper>
+      r3(s.c_str(), s.c_str() + s.size());
+    path p11(r3.begin(), r3.end());
+    compare_paths(p1, p11);
+
+    test_container<const char, input_iterator_wrapper>
+      r4(s.c_str(), s.c_str() + s.size() + 1); // includes null-terminator
+    path p12(r4.begin());
+    compare_paths(p1, p12);
+
+#if _GLIBCXX_USE_WCHAR_T
+    // Test with input iterators and const value_types
+    test_container<wchar_t, input_iterator_wrapper>
+      r5(&ws.front(), &ws.front() + ws.size());
+    path p13(r5.begin(), r5.end());
+    compare_paths(p1, p13);
+
+    test_container<wchar_t, input_iterator_wrapper>
+      r6(&ws.front(), &ws.front() + ws.size() + 1); // includes null-terminator
+    path p14(r6.begin());
+    compare_paths(p1, p14);
+
+    test_container<const wchar_t, input_iterator_wrapper>
+      r7(ws.c_str(), ws.c_str() + ws.size());
+    path p15(r7.begin(), r7.end());
+    compare_paths(p1, p15);
+
+    test_container<const wchar_t, input_iterator_wrapper>
+      r8(ws.c_str(), ws.c_str() + ws.size() + 1); // includes null-terminator
+    path p16(r8.begin());
+    compare_paths(p1, p16);
+#endif
   }
 }