PR libstdc++/86756 add std::filesystem::path to libstdc++.so
authorJonathan Wakely <jwakely@redhat.com>
Sun, 6 Jan 2019 22:34:29 +0000 (22:34 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Sun, 6 Jan 2019 22:34:29 +0000 (22:34 +0000)
Move the C++17 std::filesystem::path definitions from the libstdc++fs.a
archive to the main libstdc++ library. The path classes do not depend on
any OS functions, so can be defined unconditionally on all targets
(rather than depending on --enable-libstdcxx-filesystem-ts). The tests
should pass on all targets too.

PR libstdc++/86756
* config/abi/pre/gnu.ver (GLIBCXX_3.4): Make various patterns for
typeinfo and vtables less greedy.
(GLIBCXX_3.4.26): Export symbols for std::filesystem::path.
* src/c++17/Makefile.am: Add fs_path.cc and cow-fs_path.cc.
* src/c++17/Makefile.in: Regenerate.
* src/c++17/cow-fs_path.cc: Move src/filesystem/cow-std-path.cc to
here, and change name of included file.
* src/c++17/fs_path.cc: Move src/filesystem/std-path.cc to here.
* src/filesystem/Makefile.am: Remove std-path.cc and cow-std-path.cc
from sources.
* src/filesystem/Makefile.in: Regenerate.
* src/filesystem/cow-std-path.cc: Move to src/c++17/cow-fs_path.cc.
* src/filesystem/std-path.cc: Move to src/c++17/fs_path.cc.
* testsuite/27_io/filesystem/path/append/path.cc: Remove -lstdc++fs
from dg-options and remove dg-require-filesystem-ts.
* testsuite/27_io/filesystem/path/append/source.cc: Likewise.
* testsuite/27_io/filesystem/path/assign/assign.cc: Likewise.
* testsuite/27_io/filesystem/path/assign/copy.cc: Likewise.
* testsuite/27_io/filesystem/path/compare/compare.cc: Likewise.
* testsuite/27_io/filesystem/path/compare/lwg2936.cc: Likewise.
* testsuite/27_io/filesystem/path/compare/path.cc: Likewise.
* testsuite/27_io/filesystem/path/compare/strings.cc: Likewise.
* testsuite/27_io/filesystem/path/concat/path.cc: Likewise.
* testsuite/27_io/filesystem/path/concat/strings.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/80762.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/copy.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/default.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/format.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/locale.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/range.cc: Likewise.
* testsuite/27_io/filesystem/path/construct/string_view.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/extension.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/filename.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/parent_path.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/relative_path.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/27_io/filesystem/path/decompose/root_name.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/root_path.cc: Likewise.
* testsuite/27_io/filesystem/path/decompose/stem.cc: Likewise.
* testsuite/27_io/filesystem/path/generation/normal.cc: Likewise.
* testsuite/27_io/filesystem/path/generation/normal2.cc: Likewise.
* testsuite/27_io/filesystem/path/generation/proximate.cc: Likewise.
* testsuite/27_io/filesystem/path/generation/relative.cc: Likewise.
* testsuite/27_io/filesystem/path/generic/generic_string.cc: Likewise.
* testsuite/27_io/filesystem/path/itr/components.cc: Likewise.
* testsuite/27_io/filesystem/path/itr/traversal.cc: Likewise.
* testsuite/27_io/filesystem/path/modifiers/clear.cc: Likewise.
* testsuite/27_io/filesystem/path/modifiers/make_preferred.cc:
Likewise.
* testsuite/27_io/filesystem/path/modifiers/remove_filename.cc:
Likewise.
* testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
Likewise.
* testsuite/27_io/filesystem/path/modifiers/replace_filename.cc:
Likewise.
* testsuite/27_io/filesystem/path/modifiers/swap.cc: Likewise.
* testsuite/27_io/filesystem/path/native/string.cc: Likewise.
* testsuite/27_io/filesystem/path/nonmember/append.cc: Likewise.
* testsuite/27_io/filesystem/path/nonmember/hash_value.cc: Likewise.
* testsuite/27_io/filesystem/path/query/empty.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_extension.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_filename.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_parent_path.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_relative_path.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_root_directory.cc:
Likewise.
* testsuite/27_io/filesystem/path/query/has_root_name.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_root_path.cc: Likewise.
* testsuite/27_io/filesystem/path/query/has_stem.cc: Likewise.
* testsuite/27_io/filesystem/path/query/is_absolute.cc: Likewise.
* testsuite/27_io/filesystem/path/query/is_relative.cc: Likewise.

From-SVN: r267615

62 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/src/c++17/Makefile.am
libstdc++-v3/src/c++17/Makefile.in
libstdc++-v3/src/c++17/cow-fs_path.cc [new file with mode: 0644]
libstdc++-v3/src/c++17/fs_path.cc [new file with mode: 0644]
libstdc++-v3/src/filesystem/Makefile.am
libstdc++-v3/src/filesystem/Makefile.in
libstdc++-v3/src/filesystem/cow-std-path.cc [deleted file]
libstdc++-v3/src/filesystem/std-path.cc [deleted file]
libstdc++-v3/testsuite/27_io/filesystem/path/append/path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc
libstdc++-v3/testsuite/27_io/filesystem/path/assign/assign.cc
libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc
libstdc++-v3/testsuite/27_io/filesystem/path/compare/compare.cc
libstdc++-v3/testsuite/27_io/filesystem/path/compare/lwg2936.cc
libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc
libstdc++-v3/testsuite/27_io/filesystem/path/concat/path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/concat/strings.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/80762.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/default.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/format.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/locale.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/range.cc
libstdc++-v3/testsuite/27_io/filesystem/path/construct/string_view.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_name.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/decompose/stem.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/normal.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/normal2.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/proximate.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generation/relative.cc
libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc
libstdc++-v3/testsuite/27_io/filesystem/path/itr/components.cc
libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/clear.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/make_preferred.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc
libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/swap.cc
libstdc++-v3/testsuite/27_io/filesystem/path/native/string.cc
libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc
libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/empty.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/is_absolute.cc
libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc

index fe1643d69cc6374df8f8cfa9ed12bd9e6f3a0d35..dd8939773401579f0ccf7200c42d00414aa13153 100644 (file)
@@ -1,5 +1,79 @@
 2019-01-06  Jonathan Wakely  <jwakely@redhat.com>
 
+       PR libstdc++/86756
+       * config/abi/pre/gnu.ver (GLIBCXX_3.4): Make various patterns for
+       typeinfo and vtables less greedy.
+       (GLIBCXX_3.4.26): Export symbols for std::filesystem::path.
+       * src/c++17/Makefile.am: Add fs_path.cc and cow-fs_path.cc.
+       * src/c++17/Makefile.in: Regenerate.
+       * src/c++17/cow-fs_path.cc: Move src/filesystem/cow-std-path.cc to
+       here, and change name of included file.
+       * src/c++17/fs_path.cc: Move src/filesystem/std-path.cc to here.
+       * src/filesystem/Makefile.am: Remove std-path.cc and cow-std-path.cc
+       from sources.
+       * src/filesystem/Makefile.in: Regenerate.
+       * src/filesystem/cow-std-path.cc: Move to src/c++17/cow-fs_path.cc.
+       * src/filesystem/std-path.cc: Move to src/c++17/fs_path.cc.
+       * testsuite/27_io/filesystem/path/append/path.cc: Remove -lstdc++fs
+       from dg-options and remove dg-require-filesystem-ts.
+       * testsuite/27_io/filesystem/path/append/source.cc: Likewise.
+       * testsuite/27_io/filesystem/path/assign/assign.cc: Likewise.
+       * testsuite/27_io/filesystem/path/assign/copy.cc: Likewise.
+       * testsuite/27_io/filesystem/path/compare/compare.cc: Likewise.
+       * testsuite/27_io/filesystem/path/compare/lwg2936.cc: Likewise.
+       * testsuite/27_io/filesystem/path/compare/path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/compare/strings.cc: Likewise.
+       * testsuite/27_io/filesystem/path/concat/path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/concat/strings.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/80762.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/copy.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/default.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/format.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/locale.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/range.cc: Likewise.
+       * testsuite/27_io/filesystem/path/construct/string_view.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/extension.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/filename.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/parent_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/relative_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/root_directory.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/decompose/root_name.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/root_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/decompose/stem.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generation/normal.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generation/normal2.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generation/proximate.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generation/relative.cc: Likewise.
+       * testsuite/27_io/filesystem/path/generic/generic_string.cc: Likewise.
+       * testsuite/27_io/filesystem/path/itr/components.cc: Likewise.
+       * testsuite/27_io/filesystem/path/itr/traversal.cc: Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/clear.cc: Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/make_preferred.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/remove_filename.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/replace_filename.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/modifiers/swap.cc: Likewise.
+       * testsuite/27_io/filesystem/path/native/string.cc: Likewise.
+       * testsuite/27_io/filesystem/path/nonmember/append.cc: Likewise.
+       * testsuite/27_io/filesystem/path/nonmember/hash_value.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/empty.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_extension.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_filename.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_parent_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_relative_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_root_directory.cc:
+       Likewise.
+       * testsuite/27_io/filesystem/path/query/has_root_name.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_root_path.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/has_stem.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/is_absolute.cc: Likewise.
+       * testsuite/27_io/filesystem/path/query/is_relative.cc: Likewise.
+
        PR libstdc++/87431
        * include/std/variant (_Variant_storage<true, _Types...>::_M_valid):
        Check is_trivially_copyable instead of is_scalar.
index 6c18caa6d8aee07a9a9b8e4b62f8e74af491cfcb..f83d2b1cca9448f393028717436f49fdf80e241c 100644 (file)
@@ -767,19 +767,24 @@ GLIBCXX_3.4 {
     _ZTVSt18basic_stringstreamI*;
     _ZTVSt19basic_istringstreamI*;
     _ZTVSt19basic_ostringstreamI*;
-    _ZTVSt[0-9][0-9][c-d]*;
-    _ZTVSt[0-9][0-9][g-k]*;
+    _ZTVSt10ctype_base;
+    _ZTVSt12codecvt_base;
+    _ZTVSt12ctype_bynameI[cw]E;
+    _ZTVSt14co*_bynameI[cw]*;
+    _ZTVSt12domain_error;
+    _ZTVSt10istrstream;
+    _ZTVSt16invalid_argument;
     _ZTVSt11logic_error;
     _ZTVSt12length_error;
-#   _ZTVSt[0-9][0-9][m-q]*;
-    _ZTVSt[0-9][0-9][m]*;
-    _ZTVSt[0-9][0-9]n[^e]*;
-    _ZTVSt[0-9][0-9][o-q]*;
+    _ZTVSt1[07]money*;
+    _ZTVSt1[35]messages*;
+    _ZTVSt15numpunct_bynameI[cw]E;
+    _ZTVSt1[024]o*;
     _ZTVSt11range_error;
     _ZTVSt13runtime_error;
-    _ZTVSt[0-9][0-9][t-z]*;
-    _ZTVSt[0-9][0-9]e[^r]*;
-    _ZTVSt[0-9][0-9]s[^y]*;
+    _ZTVSt12strstreambuf;
+    _ZTVSt15time*;
+    _ZTVSt15underflow_error;
 
     _ZTVSt11__timepunctI[cw]E;
     _ZTVSt23__codecvt_abstract_baseI[cw]c11__mbstate_tE;
@@ -821,19 +826,24 @@ GLIBCXX_3.4 {
     _ZTISt18basic_stringstreamI*;
     _ZTISt19basic_istringstreamI*;
     _ZTISt19basic_ostringstreamI*;
-    _ZTISt[0-9][0-9][c-d]*;
-    _ZTISt[0-9][0-9][g-k]*;
+    _ZTISt10ctype_base;
+    _ZTISt12codecvt_base;
+    _ZTISt12ctype_bynameI[cw]E;
+    _ZTISt14co*_bynameI[cw]*;
+    _ZTISt12domain_error;
+    _ZTISt10istrstream;
+    _ZTISt16invalid_argument;
     _ZTISt11logic_error;
     _ZTISt12length_error;
-#   _ZTISt[0-9][0-9][m-q]*;
-    _ZTISt[0-9][0-9][m]*;
-    _ZTISt[0-9][0-9]n[^e]*;
-    _ZTISt[0-9][0-9][o-q]*;
+    _ZTISt1[07]money*;
+    _ZTISt1[35]messages*;
+    _ZTISt15numpunct_bynameI[cw]E;
+    _ZTISt1[024]o*;
     _ZTISt11range_error;
     _ZTISt13runtime_error;
-    _ZTISt[0-9][0-9][t-z]*;
-    _ZTISt[0-9][0-9]e[^r]*;
-    _ZTISt[0-9][0-9]s[^y]*;
+    _ZTISt12strstreambuf;
+    _ZTISt15time*;
+    _ZTISt15underflow_error;
     _ZTISt11__timepunctI[cw]E;
     _ZTISt10__num_base;
     _ZTISt21__ctype_abstract_baseI[cw]E;
@@ -869,19 +879,24 @@ GLIBCXX_3.4 {
     _ZTSSt18basic_stringstreamI*;
     _ZTSSt19basic_istringstreamI*;
     _ZTSSt19basic_ostringstreamI*;
-    _ZTSSt[0-9][0-9][c-d]*;
-    _ZTSSt[0-9][0-9][g-k]*;
+    _ZTSSt10ctype_base;
+    _ZTSSt12codecvt_base;
+    _ZTSSt12ctype_bynameI[cw]E;
+    _ZTSSt14co*_bynameI[cw]*;
+    _ZTSSt12domain_error;
+    _ZTSSt10istrstream;
+    _ZTSSt16invalid_argument;
     _ZTSSt11logic_error;
     _ZTSSt12length_error;
-#   _ZTSSt[0-9][0-9][m-q]*;
-    _ZTSSt[0-9][0-9][m]*;
-    _ZTSSt[0-9][0-9]n[^e]*;
-    _ZTSSt[0-9][0-9][o-q]*;
+    _ZTSSt1[07]money*;
+    _ZTSSt1[35]messages*;
+    _ZTSSt15numpunct_bynameI[cw]E;
+    _ZTSSt1[024]o*;
     _ZTSSt11range_error;
     _ZTSSt13runtime_error;
-    _ZTSSt[0-9][0-9][t-z]*;
-    _ZTSSt[0-9][0-9]e[^r]*;
-    _ZTSSt[0-9][0-9]s[^y]*;
+    _ZTSSt12strstreambuf;
+    _ZTSSt15time*;
+    _ZTSSt15underflow_error;
 
     _ZTSSt11__timepunctI[cw]E;
     _ZTSSt10__num_base;
@@ -2099,6 +2114,59 @@ GLIBCXX_3.4.26 {
     _ZNSbIwSt11char_traitsIwESaIwEEC[12]ENS2_12__sv_wrapperERKS1_;
     _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ENS4_12__sv_wrapperERKS3_;
 
+    # std::filesystem symbols
+    _ZNKSt10filesystem16filesystem_error4whatEv;
+    _ZNKSt10filesystem16filesystem_error5path[12]Ev;
+    _ZNKSt10filesystem4path1[1-9][hlpr]*Ev;
+    _ZNKSt10filesystem4path17_M_find_extensionEv;
+    _ZNKSt10filesystem4path1[89]lexically_*ERKS0_;
+    _ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE;
+    _ZNKSt10filesystem4path5_List3endEv;
+    _ZNKSt10filesystem4path5_List5beginEv;
+    _ZNKSt10filesystem4path7compareERKS0_;
+    _ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNKSt10filesystem4path9root_*Ev;
+    _ZNSt10filesystem10hash_valueERKNS_4pathE;
+    _ZNSt10filesystem16filesystem_errorC[12]E*;
+    _ZNSt10filesystem16filesystem_errorD[012]Ev;
+    _ZNSt10filesystem4path14_M_split_cmptsEv;
+    _ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale;
+    _ZNSt10filesystem4path1[567]re*;
+    _ZNSt10filesystem4path5_ListC1ERKS1_;
+    _ZNSt10filesystem4path5_ListC1Ev;
+    _ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNSt10filesystem4pathaSERKS0_;
+    _ZNSt10filesystem4pathdVERKS0_;
+    _ZNSt10filesystem4pathpLERKS0_;
+    _ZT[IV]NSt10filesystem16filesystem_errorE;
+
+    _ZNKSt10filesystem7__cxx1116filesystem_error4whatEv;
+    _ZNKSt10filesystem7__cxx1116filesystem_error5path[12]Ev;
+    _ZNKSt10filesystem7__cxx114path1[1-9][hlpr]*Ev;
+    _ZNKSt10filesystem7__cxx114path17_M_find_extensionEv;
+    _ZNKSt10filesystem7__cxx114path1[89]lexically_*ERKS1_;
+    _ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE;
+    _ZNKSt10filesystem7__cxx114path5_List3endEv;
+    _ZNKSt10filesystem7__cxx114path5_List5beginEv;
+    _ZNKSt10filesystem7__cxx114path7compareERKS1_;
+    _ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNKSt10filesystem7__cxx114path9root_*Ev;
+    _ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE;
+    _ZNSt10filesystem7__cxx1116filesystem_errorC[12]E*;
+    _ZNSt10filesystem7__cxx1116filesystem_errorD[012]Ev;
+    _ZNSt10filesystem7__cxx114path14_M_split_cmptsEv;
+    _ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale;
+    _ZNSt10filesystem7__cxx114path1[567]re*;
+    _ZNSt10filesystem7__cxx114path5_ListC1ERKS2_;
+    _ZNSt10filesystem7__cxx114path5_ListC1Ev;
+    _ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE;
+    _ZNSt10filesystem7__cxx114pathaSERKS1_;
+    _ZNSt10filesystem7__cxx114pathdVERKS1_;
+    _ZNSt10filesystem7__cxx114pathpLERKS1_;
+    _ZT[IV]NSt10filesystem7__cxx1116filesystem_errorE;
+
 } GLIBCXX_3.4.25;
 
 # Symbols in the support library (libsupc++) have their own tag.
index afa119eecb6cd6b4516a37b24ba973e88f0843a3..85883c33f2d8b3d95e6d9a91ea23df458c843bf5 100644 (file)
@@ -27,14 +27,12 @@ noinst_LTLIBRARIES = libc++17convenience.la
 
 headers =
 
-sources = \
-       memory_resource.cc \
-       string-inst.cc
-
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = cow-string-inst.cc
+extra_fs_sources = cow-fs_path.cc
 else
 extra_string_inst_sources =
+extra_fs_sources =
 endif
 
 if ENABLE_EXTERN_TEMPLATE
@@ -46,6 +44,12 @@ else
 inst_sources =
 endif
 
+sources = \
+       fs_path.cc \
+       memory_resource.cc \
+       string-inst.cc \
+       $(extra_fs_sources)
+
 vpath % $(top_srcdir)/src/c++17
 
 libc__17convenience_la_SOURCES = $(sources)  $(inst_sources)
@@ -59,16 +63,12 @@ AM_CXXFLAGS = \
        -std=gnu++17 \
        $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
        $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
-       $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
+       $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
+       -fimplicit-templates
 
 AM_MAKEFLAGS = \
        "gxx_include_dir=$(gxx_include_dir)"
 
-memory_resource.lo: memory_resource.cc
-       $(LTCXXCOMPILE) -fimplicit-templates -c $< -o $@
-memory_resource.o: memory_resource.cc
-       $(CXXCOMPILE) -fimplicit-templates -c $< -o $@
-
 # Libtool notes
 
 # 1) In general, libtool expects an argument such as `--tag=CXX' when
index 0657bdcf9d9e0d3f36205afa5a819569b17c140e..d76580f08aae5347529cbe6bdf1972ecad2f1a1f 100644 (file)
@@ -121,10 +121,12 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__17convenience_la_LIBADD =
-am__objects_1 = memory_resource.lo string-inst.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-string-inst.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = $(am__objects_2)
-am_libc__17convenience_la_OBJECTS = $(am__objects_1) $(am__objects_3)
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-fs_path.lo
+am__objects_2 = fs_path.lo memory_resource.lo string-inst.lo \
+       $(am__objects_1)
+@ENABLE_DUAL_ABI_TRUE@am__objects_3 = cow-string-inst.lo
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = $(am__objects_3)
+am_libc__17convenience_la_OBJECTS = $(am__objects_2) $(am__objects_4)
 libc__17convenience_la_OBJECTS = $(am_libc__17convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -410,12 +412,10 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)
 # Convenience library for C++17 runtime.
 noinst_LTLIBRARIES = libc++17convenience.la
 headers = 
-sources = \
-       memory_resource.cc \
-       string-inst.cc
-
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = cow-string-inst.cc
+@ENABLE_DUAL_ABI_FALSE@extra_fs_sources = 
+@ENABLE_DUAL_ABI_TRUE@extra_fs_sources = cow-fs_path.cc
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -423,6 +423,12 @@ sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  $(extra_string_inst_sources)
 
+sources = \
+       fs_path.cc \
+       memory_resource.cc \
+       string-inst.cc \
+       $(extra_fs_sources)
+
 libc__17convenience_la_SOURCES = $(sources)  $(inst_sources)
 
 # AM_CXXFLAGS needs to be in each subdirectory so that it can be
@@ -434,7 +440,8 @@ AM_CXXFLAGS = \
        -std=gnu++17 \
        $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
        $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
-       $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
+       $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
+       -fimplicit-templates
 
 AM_MAKEFLAGS = \
        "gxx_include_dir=$(gxx_include_dir)"
@@ -732,11 +739,6 @@ uninstall-am:
 
 vpath % $(top_srcdir)/src/c++17
 
-memory_resource.lo: memory_resource.cc
-       $(LTCXXCOMPILE) -fimplicit-templates -c $< -o $@
-memory_resource.o: memory_resource.cc
-       $(CXXCOMPILE) -fimplicit-templates -c $< -o $@
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/libstdc++-v3/src/c++17/cow-fs_path.cc b/libstdc++-v3/src/c++17/cow-fs_path.cc
new file mode 100644 (file)
index 0000000..53539a6
--- /dev/null
@@ -0,0 +1,26 @@
+// Class filesystem::path -*- C++ -*-
+
+// Copyright (C) 2015-2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 0
+#include "fs_path.cc"
diff --git a/libstdc++-v3/src/c++17/fs_path.cc b/libstdc++-v3/src/c++17/fs_path.cc
new file mode 100644 (file)
index 0000000..34de52f
--- /dev/null
@@ -0,0 +1,2007 @@
+// Class filesystem::path -*- C++ -*-
+
+// Copyright (C) 2014-2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_USE_CXX11_ABI 1
+#endif
+
+#ifdef __CYGWIN__
+// Interpret "//x" as a root-name, not root-dir + filename
+# define SLASHSLASH_IS_ROOTNAME 1
+#endif
+
+#include <filesystem>
+#include <algorithm>
+#include <bits/stl_uninitialized.h>
+
+namespace fs = std::filesystem;
+using fs::path;
+
+static inline bool is_dir_sep(path::value_type ch)
+{
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    return ch == L'/' || ch == path::preferred_separator;
+#else
+    return ch == '/';
+#endif
+}
+
+struct path::_Parser
+{
+  using string_view_type = std::basic_string_view<value_type>;
+
+  struct cmpt
+  {
+    string_view_type str;
+    _Type type = _Type::_Multi;
+
+    bool valid() const { return type != _Type::_Multi; }
+  };
+
+  string_view_type input;
+  string_view_type::size_type pos = 0;
+  size_t origin;
+  _Type last_type = _Type::_Multi;
+
+  _Parser(string_view_type s, size_t o = 0) : input(s), origin(o) { }
+
+  pair<cmpt, cmpt> root_path() noexcept
+  {
+    pos = 0;
+    pair<cmpt, cmpt> root;
+
+    const size_t len = input.size();
+
+    // look for root name or root directory
+    if (is_dir_sep(input[0]))
+      {
+#if SLASHSLASH_IS_ROOTNAME
+       // look for root name, such as "//foo"
+       if (len > 2 && input[1] == input[0])
+         {
+           if (!is_dir_sep(input[2]))
+             {
+               // got root name, find its end
+               pos = 3;
+               while (pos < len && !is_dir_sep(input[pos]))
+                 ++pos;
+               root.first.str = input.substr(0, pos);
+               root.first.type = _Type::_Root_name;
+
+               if (pos < len) // also got root directory
+                 {
+                   root.second.str = input.substr(pos, 1);
+                   root.second.type = _Type::_Root_dir;
+                   ++pos;
+                 }
+             }
+           else
+             {
+               // got something like "///foo" which is just a root directory
+               // composed of multiple redundant directory separators
+               root.first.str = input.substr(0, 1);
+               root.first.type = _Type::_Root_dir;
+               pos += 2;
+             }
+         }
+       else
+#endif
+         {
+           root.first.str = input.substr(0, 1);
+           root.first.type = _Type::_Root_dir;
+           ++pos;
+         }
+       // Find the start of the first filename
+       while (pos < len && is_dir_sep(input[pos]))
+         ++pos;
+      }
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    else if (len > 1 && input[1] == L':')
+      {
+       // got disk designator
+       root.first.str = input.substr(0, 2);
+       root.first.type = _Type::_Root_name;
+       if (len > 2 && is_dir_sep(input[2]))
+         {
+           root.second.str = input.substr(2, 1);
+           root.second.type = _Type::_Root_dir;
+         }
+       pos = input.find_first_not_of(L"/\\", 2);
+      }
+#endif
+
+    if (root.second.valid())
+      last_type = root.second.type;
+    else
+      last_type = root.first.type;
+
+    return root;
+  }
+
+  cmpt next() noexcept
+  {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+    string_view_type sep = L"/\\";
+#else
+    char sep = '/';
+#endif
+
+    const int last_pos = pos;
+
+    cmpt f;
+    if (pos != input.npos)
+      {
+       pos = input.find_first_not_of(sep, pos);
+       if (pos != input.npos)
+         {
+           const auto end = input.find_first_of(sep, pos);
+           f.str = input.substr(pos, end - pos);
+           f.type = _Type::_Filename;
+           pos = end;
+         }
+       else if (last_type == _Type::_Filename
+           || (last_pos == 0 && !input.empty()))
+         {
+           // [fs.path.itr]/4 An empty element, if trailing non-root
+           // directory-separator present.
+           __glibcxx_assert(is_dir_sep(input.back()));
+           f.str = input.substr(input.length(), 0);
+           f.type = _Type::_Filename;
+         }
+      }
+    last_type = f.type;
+    return f;
+  }
+
+  string_view_type::size_type
+  offset(const cmpt& c) const noexcept
+  { return origin + c.str.data() - input.data(); }
+};
+
+struct path::_List::_Impl
+{
+  using value_type = _Cmpt;
+
+  _Impl(int cap) : _M_size(0), _M_capacity(cap) { }
+
+  alignas(value_type) int _M_size;
+  int _M_capacity;
+
+  using iterator = value_type*;
+  using const_iterator = const value_type*;
+
+  iterator begin() { return reinterpret_cast<value_type*>(this + 1); }
+  iterator end() { return begin() + size(); }
+
+  const_iterator begin() const
+  { return reinterpret_cast<const value_type*>(this + 1); }
+  const_iterator end() const { return begin() + size(); }
+
+  const value_type& front() const { return *begin(); }
+  const value_type& back() const { return end()[-1]; }
+
+  int size() const { return _M_size; }
+  int capacity() const { return _M_capacity; }
+  bool empty() const { return _M_size == 0; }
+
+  void clear() { std::destroy_n(begin(), _M_size); _M_size = 0; }
+
+  void pop_back()
+  {
+    back().~_Cmpt();
+    --_M_size;
+  }
+
+  void _M_erase_from(const_iterator pos)
+  {
+    iterator first = begin() + (pos - begin());
+    iterator last = end();
+    std::destroy(first, last);
+    _M_size -= last - first;
+  }
+
+  unique_ptr<_Impl, _Impl_deleter> copy() const
+  {
+    const auto n = size();
+    void* p = ::operator new(sizeof(_Impl) + n * sizeof(value_type));
+    unique_ptr<_Impl, _Impl_deleter> newptr(::new (p) _Impl{n});
+    std::uninitialized_copy_n(begin(), n, newptr->begin());
+    newptr->_M_size = n;
+    return newptr;
+  }
+
+  // Clear the lowest two bits from the pointer (i.e. remove the _Type value)
+  static _Impl* notype(_Impl* p)
+  {
+    constexpr uintptr_t mask = ~(uintptr_t)0x3;
+    return reinterpret_cast<_Impl*>(reinterpret_cast<uintptr_t>(p) & mask);
+  }
+};
+
+void path::_List::_Impl_deleter::operator()(_Impl* p) const noexcept
+{
+  p = _Impl::notype(p);
+  if (p)
+    {
+      __glibcxx_assert(p->_M_size <= p->_M_capacity);
+      p->clear();
+      ::operator delete(p, sizeof(*p) + p->_M_capacity * sizeof(value_type));
+    }
+}
+
+path::_List::_List() : _M_impl(reinterpret_cast<_Impl*>(_Type::_Filename)) { }
+
+path::_List::_List(const _List& other)
+{
+  if (!other.empty())
+    _M_impl = other._M_impl->copy();
+  else
+    type(other.type());
+}
+
+path::_List&
+path::_List::operator=(const _List& other)
+{
+  if (!other.empty())
+    {
+      // copy in-place if there is capacity
+      const int newsize = other._M_impl->size();
+      auto impl = _Impl::notype(_M_impl.get());
+      if (impl && impl->capacity() >= newsize)
+       {
+         const int oldsize = impl->_M_size;
+         auto to = impl->begin();
+         auto from = other._M_impl->begin();
+         const int minsize = std::min(newsize, oldsize);
+         for (int i = 0; i < minsize; ++i)
+           to[i]._M_pathname.reserve(from[i]._M_pathname.length());
+         if (newsize > oldsize)
+           {
+             std::uninitialized_copy_n(to + oldsize, newsize - oldsize,
+                                       from + oldsize);
+             impl->_M_size = newsize;
+           }
+         else if (newsize < oldsize)
+           impl->_M_erase_from(impl->begin() + newsize);
+         std::copy_n(from, minsize, to);
+         type(_Type::_Multi);
+       }
+      else
+       _M_impl = other._M_impl->copy();
+    }
+  else
+    {
+      clear();
+      type(other.type());
+    }
+  return *this;
+}
+
+inline void
+path::_List::type(_Type t) noexcept
+{
+  auto val = reinterpret_cast<uintptr_t>(_Impl::notype(_M_impl.release()));
+  _M_impl.reset(reinterpret_cast<_Impl*>(val | (unsigned char)t));
+}
+
+inline int
+path::_List::size() const noexcept
+{
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->size();
+  return 0;
+}
+
+inline int
+path::_List::capacity() const noexcept
+{
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->capacity();
+  return 0;
+}
+
+inline bool
+path::_List::empty() const noexcept
+{
+  return size() == 0;
+}
+
+inline auto
+path::_List::begin() noexcept
+-> iterator
+{
+  __glibcxx_assert(!empty());
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->begin();
+  return nullptr;
+}
+
+inline auto
+path::_List::end() noexcept
+-> iterator
+{
+  __glibcxx_assert(!empty());
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->end();
+  return nullptr;
+}
+
+auto
+path::_List::begin() const noexcept
+-> const_iterator
+{
+  __glibcxx_assert(!empty());
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->begin();
+  return nullptr;
+}
+
+auto
+path::_List::end() const noexcept
+-> const_iterator
+{
+  __glibcxx_assert(!empty());
+  if (auto* ptr = _Impl::notype(_M_impl.get()))
+    return ptr->end();
+  return nullptr;
+}
+
+inline auto
+path::_List::front() noexcept
+-> value_type&
+{
+  return *_M_impl->begin();
+}
+
+inline auto
+path::_List::back() noexcept
+-> value_type&
+{
+  return _M_impl->begin()[_M_impl->size() - 1];
+}
+
+inline auto
+path::_List::front() const noexcept
+-> const value_type&
+{
+  return *_M_impl->begin();
+}
+
+inline auto
+path::_List::back() const noexcept
+-> const value_type&
+{
+  return _M_impl->begin()[_M_impl->size() - 1];
+}
+
+inline void
+path::_List::pop_back()
+{
+  __glibcxx_assert(size() > 0);
+  _M_impl->pop_back();
+}
+
+inline void
+path::_List::_M_erase_from(const_iterator pos)
+{
+  _M_impl->_M_erase_from(pos);
+}
+
+inline void
+path::_List::clear()
+{
+  if (auto ptr = _Impl::notype(_M_impl.get()))
+    ptr->clear();
+}
+
+void
+path::_List::reserve(int newcap, bool exact = false)
+{
+  // __glibcxx_assert(type() == _Type::_Multi);
+
+  _Impl* curptr = _Impl::notype(_M_impl.get());
+
+  int curcap = curptr ? curptr->capacity() : 0;
+
+  if (curcap < newcap)
+    {
+      if (!exact && newcap < int(1.5 * curcap))
+       newcap = 1.5 * curcap;
+
+      void* p = ::operator new(sizeof(_Impl) + newcap * sizeof(value_type));
+      std::unique_ptr<_Impl, _Impl_deleter> newptr(::new(p) _Impl{newcap});
+      const int cursize = curptr ? curptr->size() : 0;
+      if (cursize)
+       {
+         std::uninitialized_move_n(curptr->begin(), cursize, newptr->begin());
+         newptr->_M_size = cursize;
+       }
+      std::swap(newptr, _M_impl);
+    }
+}
+
+path&
+path::operator=(const path& p)
+{
+  _M_pathname.reserve(p._M_pathname.length());
+  _M_cmpts = p._M_cmpts;       // might throw
+  _M_pathname = p._M_pathname; // won't throw because we reserved enough space
+  return *this;
+}
+
+path&
+path::operator/=(const path& __p)
+{
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  if (__p.is_absolute()
+      || (__p.has_root_name() && __p.root_name() != root_name()))
+    return operator=(__p);
+
+  basic_string_view<value_type> __lhs = _M_pathname;
+  bool __add_sep = false;
+
+  if (__p.has_root_directory())
+    {
+      // Remove any root directory and relative path
+      if (_M_type() != _Type::_Root_name)
+       {
+         if (!_M_cmpts.empty()
+             && _M_cmpts.front()._M_type() == _Type::_Root_name)
+           __lhs = _M_cmpts.front()._M_pathname;
+         else
+           __lhs = {};
+       }
+    }
+  else if (has_filename() || (!has_root_directory() && is_absolute()))
+    __add_sep = true;
+
+  basic_string_view<value_type> __rhs = __p._M_pathname;
+  // Omit any root-name from the generic format pathname:
+  if (__p._M_type() == _Type::_Root_name)
+    __rhs = {};
+  else if (!__p._M_cmpts.empty()
+      && __p._M_cmpts.front()._M_type() == _Type::_Root_name)
+    __rhs.remove_prefix(__p._M_cmpts.front()._M_pathname.size());
+
+  const size_t __len = __lhs.size() + (int)__add_sep + __rhs.size();
+  const int __maxcmpts = _M_cmpts.size() + __p._M_cmpts.size();
+  if (_M_pathname.capacity() < __len || _M_cmpts.capacity() < __maxcmpts)
+    {
+      // Construct new path and swap (strong exception-safety guarantee).
+      string_type __tmp;
+      __tmp.reserve(__len);
+      __tmp = __lhs;
+      if (__add_sep)
+       __tmp += preferred_separator;
+      __tmp += __rhs;
+      path __newp = std::move(__tmp);
+      swap(__newp);
+    }
+  else
+    {
+      _M_pathname = __lhs;
+      if (__add_sep)
+       _M_pathname += preferred_separator;
+      _M_pathname += __rhs;
+      __try
+       {
+         _M_split_cmpts();
+       }
+      __catch (...)
+       {
+         __try
+           {
+             // try to restore original state
+             _M_pathname.resize(__lhs.length());
+             _M_split_cmpts();
+           }
+         __catch (...)
+           {
+             // give up, basic exception safety guarantee only:
+             clear();
+             __throw_exception_again;
+           }
+       }
+    }
+#else
+  // POSIX version is simpler than the specification in the standard,
+  // as any path with root-name or root-dir is absolute.
+
+  if (__p.is_absolute() || this->empty())
+    {
+      return operator=(__p);
+    }
+
+  using string_view_type = basic_string_view<value_type>;
+
+  string_view_type sep;
+  if (has_filename())
+    sep = { &preferred_separator, 1 };  // need to add a separator
+#if SLASHSLASH_IS_ROOTNAME
+  else if (_M_type() == _Type::_Root_name) // root-name with no root-dir
+    sep = { &preferred_separator, 1 };  // need to add a separator
+#endif
+  else if (__p.empty())
+    return *this;                          // nothing to do
+
+  const auto orig_pathlen = _M_pathname.length();
+  const auto orig_size = _M_cmpts.size();
+  const auto orig_type = _M_type();
+
+  int capacity = 0;
+  if (_M_type() == _Type::_Multi)
+    capacity += _M_cmpts.size();
+  else if (!empty())
+    capacity += 1;
+  if (__p._M_type() == _Type::_Multi)
+    capacity += __p._M_cmpts.size();
+  else if (!__p.empty() || !sep.empty())
+    capacity += 1;
+#if SLASHSLASH_IS_ROOTNAME
+  if (orig_type == _Type::_Root_name)
+    ++capacity; // Need to insert root-directory after root-name
+#endif
+
+  if (orig_type == _Type::_Multi)
+    {
+      const int curcap = _M_cmpts._M_impl->capacity();
+      if (capacity > curcap)
+       capacity = std::max(capacity, (int) (curcap * 1.5));
+    }
+
+  _M_pathname.reserve(_M_pathname.length() + sep.length()
+                     + __p._M_pathname.length());
+
+  __try
+    {
+      _M_pathname += sep;
+      const auto basepos = _M_pathname.length();
+      _M_pathname += __p.native();
+
+      _M_cmpts.type(_Type::_Multi);
+      _M_cmpts.reserve(capacity);
+      _Cmpt* output = _M_cmpts._M_impl->end();
+
+      if (orig_type == _Type::_Multi)
+       {
+         // Remove empty final component
+         if (_M_cmpts._M_impl->back().empty())
+           {
+             _M_cmpts.pop_back();
+             --output;
+           }
+       }
+      else if (orig_pathlen != 0)
+       {
+         // Create single component from original path
+         string_view_type s(_M_pathname.data(), orig_pathlen);
+         ::new(output++) _Cmpt(s, orig_type, 0);
+         ++_M_cmpts._M_impl->_M_size;
+#if SLASHSLASH_IS_ROOTNAME
+         if (orig_type == _Type::_Root_name)
+           {
+             ::new(output++) _Cmpt(sep, _Type::_Root_dir,
+                                   orig_pathlen + sep.length());
+             ++_M_cmpts._M_impl->_M_size;
+           }
+#endif
+       }
+
+      if (__p._M_type() == _Type::_Multi)
+       {
+         for (auto& c : *__p._M_cmpts._M_impl)
+           {
+             ::new(output++) _Cmpt(c._M_pathname, _Type::_Filename,
+                                   c._M_pos + basepos);
+             ++_M_cmpts._M_impl->_M_size;
+           }
+       }
+      else if (!__p.empty() || !sep.empty())
+       {
+         __glibcxx_assert(__p._M_type() == _Type::_Filename);
+         ::new(output) _Cmpt(__p._M_pathname, __p._M_type(), basepos);
+         ++_M_cmpts._M_impl->_M_size;
+       }
+    }
+  __catch (...)
+    {
+      _M_pathname.resize(orig_pathlen);
+      if (orig_type == _Type::_Multi)
+       _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
+      else
+       _M_cmpts.clear();
+      _M_cmpts.type(orig_type);
+      __throw_exception_again;
+    }
+#endif
+  return *this;
+}
+
+// [fs.path.append]
+void
+path::_M_append(basic_string_view<value_type> s)
+{
+  _Parser parser(s);
+  auto root_path = parser.root_path();
+
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  bool is_absolute = root_path.second.type == _Type::_Root_dir;
+  bool has_root_name = root_path.first.type == _Type::_Root_name;
+  if (is_absolute || (has_root_name && root_path.first.str != root_name()))
+    {
+      operator=(s);
+      return;
+    }
+
+  basic_string_view<value_type> lhs = _M_pathname;
+  bool add_sep = false;
+
+  bool has_root_directory = root_path.first.type == _Type::_Root_dir
+    || root_path.second.type == _Type::_Root_dir;
+
+  if (has_root_directory)
+    {
+      // Remove any root directory and relative path
+      if (_M_type() != _Type::_Root_name)
+       {
+         if (!_M_cmpts.empty()
+             && _M_cmpts.front()._M_type() == _Type::_Root_name)
+           lhs = _M_cmpts.front()._M_pathname;
+         else
+           lhs = {};
+       }
+    }
+  else if (has_filename() || (!has_root_directory && is_absolute))
+    add_sep = true;
+
+  basic_string_view<value_type> rhs = s;
+  // Omit any root-name from the generic format pathname:
+  if (has_root_name)
+    rhs.remove_prefix(root_path.first.str.length());
+
+  // Construct new path and swap (strong exception-safety guarantee).
+  string_type tmp;
+  tmp.reserve(lhs.size() + (int)add_sep + rhs.size());
+  tmp = lhs;
+  if (add_sep)
+    tmp += preferred_separator;
+  tmp += rhs;
+  path newp = std::move(tmp);
+  swap(newp);
+#else
+
+  bool is_absolute = root_path.first.type == _Type::_Root_dir
+    || root_path.second.type == _Type::_Root_dir;
+  if (is_absolute || this->empty())
+    {
+      operator=(s);
+      return;
+    }
+
+  const auto orig_pathlen = _M_pathname.length();
+  const auto orig_size = _M_cmpts.size();
+  const auto orig_type = _M_type();
+
+  basic_string_view<value_type> sep;
+  if (has_filename())
+    sep = { &preferred_separator, 1 };  // need to add a separator
+#if SLASHSLASH_IS_ROOTNAME
+  else if (_M_type() == _Type::_Root_name) // root-name with no root-dir
+    sep = { &preferred_separator, 1 };  // need to add a separator
+#endif
+  else if (s.empty())
+    return;                        // nothing to do
+
+  // Copy the input into _M_pathname:
+  _M_pathname += s;
+  _M_pathname.insert(orig_pathlen, sep);
+  // Update s to refer to the new copy (this ensures s is not a dangling
+  // reference to deallocated characters, in the case where it was referring
+  // into _M_pathname or a member of _M_cmpts).
+  s = _M_pathname;
+  const auto orig_pathname = s.substr(0, orig_pathlen);
+  s.remove_prefix(orig_pathlen + sep.length());
+
+  parser.input = s; // reset parser to use updated string view
+  const auto basepos = orig_pathname.length() + sep.length();
+  parser.origin = basepos;
+
+  std::array<_Parser::cmpt, 64> buf;
+  auto next = buf.begin();
+
+  int capacity = 0;
+  if (_M_type() == _Type::_Multi)
+    capacity += _M_cmpts.size();
+  else if (!empty())
+    capacity += 1;
+
+  auto cmpt = parser.next();
+  if (cmpt.valid())
+    {
+      do
+       {
+         *next++ = cmpt;
+         cmpt = parser.next();
+       }
+      while (cmpt.valid() && next != buf.end());
+
+      capacity += next - buf.begin();
+      if (cmpt.valid()) // filled buffer before parsing whole input
+       {
+         ++capacity;
+         _Parser parser2(parser);
+         while (parser2.next().valid())
+           ++capacity;
+       }
+    }
+  else if (!sep.empty())
+    ++capacity;
+
+#if SLASHSLASH_IS_ROOTNAME
+  if (orig_type == _Type::_Root_name)
+    ++capacity; // Need to insert root-directory after root-name
+#endif
+
+  __try
+    {
+      _M_cmpts.type(_Type::_Multi);
+      _M_cmpts.reserve(capacity);
+      _Cmpt* output = _M_cmpts._M_impl->end();
+
+      if (orig_type == _Type::_Multi)
+       {
+         // Remove empty final component
+         if (_M_cmpts._M_impl->back().empty())
+           {
+             _M_cmpts.pop_back();
+             --output;
+           }
+       }
+      else if (orig_pathlen != 0)
+       {
+         // Create single component from original path
+         ::new(output++) _Cmpt(orig_pathname, orig_type, 0);
+         ++_M_cmpts._M_impl->_M_size;
+
+#if SLASHSLASH_IS_ROOTNAME
+         if (!sep.empty() && orig_type == _Type::_Root_name)
+           {
+             ::new(output++) _Cmpt(sep, _Type::_Root_dir,
+                                   orig_pathlen + sep.length());
+             ++_M_cmpts._M_impl->_M_size;
+           }
+#endif
+       }
+
+      if (next != buf.begin())
+       {
+         for (auto it = buf.begin(); it != next; ++it)
+           {
+             auto c = *it;
+             ::new(output++) _Cmpt(c.str, c.type, parser.offset(c));
+             ++_M_cmpts._M_impl->_M_size;
+           }
+         while (cmpt.valid())
+           {
+             ::new(output++) _Cmpt(cmpt.str, cmpt.type, parser.offset(cmpt));
+             ++_M_cmpts._M_impl->_M_size;
+             cmpt = parser.next();
+           }
+       }
+      else if (!sep.empty())
+       {
+         // Empty filename at the end:
+         ::new(output) _Cmpt({}, _Type::_Filename, basepos);
+         ++_M_cmpts._M_impl->_M_size;
+       }
+    }
+  __catch (...)
+    {
+      _M_pathname.resize(orig_pathlen);
+      if (orig_type == _Type::_Multi)
+       _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
+      else
+       _M_cmpts.clear();
+      _M_cmpts.type(orig_type);
+      __throw_exception_again;
+    }
+#endif
+}
+
+// [fs.path.concat]
+path&
+path::operator+=(const path& p)
+{
+  if (p.empty())
+    return *this;
+
+  if (this->empty())
+    {
+      operator=(p);
+      return *this;
+    }
+
+  const auto orig_pathlen = _M_pathname.length();
+  const auto orig_type = _M_type();
+  const auto orig_size = _M_cmpts.size();
+  int orig_filenamelen = -1;
+  basic_string_view<value_type> extra;
+
+  // Ensure that '_M_pathname += p._M_pathname' won't throw:
+  _M_pathname.reserve(orig_pathlen + p._M_pathname.length());
+
+  _Cmpt c;
+  _Cmpt* it = nullptr;
+  _Cmpt* last = nullptr;
+  if (p._M_type() == _Type::_Multi)
+    {
+      it = p._M_cmpts._M_impl->begin();
+      last = p._M_cmpts._M_impl->end();
+    }
+  else
+    {
+      c = _Cmpt(p._M_pathname, p._M_type(), 0);
+      it = &c;
+      last = it + 1;
+    }
+
+  if (it->_M_type() == _Type::_Filename)
+    {
+      // See if there's a filename or root-name at the end of the original path
+      // that we can add to.
+      if (_M_type() == _Type::_Filename
+#if SLASHSLASH_IS_ROOTNAME
+         || _M_type() == _Type::_Root_name
+#endif
+         )
+       {
+         if (p._M_type() == _Type::_Filename)
+           {
+             // Simplest case where we just add the whole of p to the
+             // original path.
+             _M_pathname += p._M_pathname;
+             return *this;
+           }
+         // Only the first component of s should be appended, do so below:
+         extra = it->_M_pathname;
+         ++it;
+       }
+      else if (_M_type() == _Type::_Multi
+         && _M_cmpts.back()._M_type() == _Type::_Filename)
+       {
+         auto& back = _M_cmpts.back();
+         if (p._M_type() == _Type::_Filename)
+           {
+             basic_string_view<value_type> s = p._M_pathname;
+             back._M_pathname += s;
+             _M_pathname += s;
+             return *this;
+           }
+
+         orig_filenamelen = back._M_pathname.length();
+         back._M_pathname += it->_M_pathname;
+         extra = it->_M_pathname;
+         ++it;
+       }
+    }
+  else if (is_dir_sep(_M_pathname.back()) && _M_type() == _Type::_Multi
+      && _M_cmpts.back()._M_type() == _Type::_Filename)
+    orig_filenamelen = 0; // current path has empty filename at end
+
+  int capacity = 0;
+  if (_M_type() == _Type::_Multi)
+    capacity += _M_cmpts.size();
+  else
+    capacity += 1;
+  if (p._M_type() == _Type::_Multi)
+    capacity += p._M_cmpts.size();
+  else
+    capacity += 1;
+
+  __try
+    {
+      _M_cmpts.type(_Type::_Multi);
+      _M_cmpts.reserve(capacity);
+      _Cmpt* output = _M_cmpts._M_impl->end();
+
+      if (orig_type != _Type::_Multi)
+       {
+         // Create single component from original path
+         auto ptr = ::new(output++) _Cmpt({}, orig_type, 0);
+         ++_M_cmpts._M_impl->_M_size;
+         ptr->_M_pathname.reserve(_M_pathname.length() + extra.length());
+         ptr->_M_pathname = _M_pathname;
+         ptr->_M_pathname += extra;
+
+#if SLASHSLASH_IS_ROOTNAME
+         if (orig_type == _Type::_Root_name)
+           {
+             basic_string_view<value_type> s(p._M_pathname);
+             ::new(output++) _Cmpt(s.substr(extra.length(), 1),
+                 _Type::_Root_dir, orig_pathlen + extra.length());
+             ++_M_cmpts._M_impl->_M_size;
+           }
+#endif
+       }
+      else if (orig_filenamelen == 0 && it != last)
+       {
+         // Remove empty filename at end of original path.
+         _M_cmpts.pop_back();
+         --output;
+       }
+
+      if (it != last && it->_M_type() == _Type::_Root_name)
+       {
+         basic_string_view<value_type> s = it->_M_pathname;
+         auto pos = orig_pathlen;
+#if SLASHSLASH_IS_ROOTNAME
+         s.remove_prefix(2);
+         pos += 2;
+#endif
+         ::new(output++) _Cmpt(s, _Type::_Filename, pos);
+         ++_M_cmpts._M_impl->_M_size;
+         ++it;
+       }
+
+      if (it != last && it->_M_type() == _Type::_Root_dir)
+       {
+         ++it;
+         if (it == last)
+           {
+             // This root-dir becomes a trailing slash
+             auto pos = _M_pathname.length() + p._M_pathname.length();
+             ::new(output++) _Cmpt({}, _Type::_Filename, pos);
+             ++_M_cmpts._M_impl->_M_size;
+           }
+       }
+
+      while (it != last)
+       {
+         auto pos = it->_M_pos + orig_pathlen;
+         ::new(output++) _Cmpt(it->_M_pathname, _Type::_Filename, pos);
+         ++_M_cmpts._M_impl->_M_size;
+         ++it;
+       }
+
+      _M_pathname += p._M_pathname;
+
+      if (is_dir_sep(_M_pathname.back()))
+       {
+         ::new(output++) _Cmpt({}, _Type::_Filename, _M_pathname.length());
+         ++_M_cmpts._M_impl->_M_size;
+       }
+      }
+  __catch (...)
+    {
+      _M_pathname.resize(orig_pathlen);
+      if (orig_type == _Type::_Multi)
+       {
+         if (_M_cmpts.size() > orig_size)
+           _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
+         if (orig_filenamelen != -1)
+           {
+             if (_M_cmpts.size() == orig_size)
+               {
+                 auto& back = _M_cmpts.back();
+                 back._M_pathname.resize(orig_filenamelen);
+                 if (orig_filenamelen == 0)
+                   back._M_pos = orig_pathlen;
+               }
+             else
+               {
+                 auto output = _M_cmpts._M_impl->end();
+                 ::new(output) _Cmpt({}, _Type::_Filename, orig_pathlen);
+                 ++_M_cmpts._M_impl->_M_size;
+               }
+           }
+       }
+      else
+       _M_cmpts.clear();
+      _M_cmpts.type(orig_type);
+      __throw_exception_again;
+    }
+  return *this;
+}
+
+// [fs.path.concat]
+void
+path::_M_concat(basic_string_view<value_type> s)
+{
+  if (s.empty())
+    return;
+
+  if (this->empty())
+    {
+      operator=(s);
+      return;
+    }
+
+  const auto orig_pathlen = _M_pathname.length();
+  const auto orig_type = _M_type();
+  const auto orig_size = _M_cmpts.size();
+  int orig_filenamelen = -1;
+  basic_string_view<value_type> extra;
+
+  // Copy the input into _M_pathname:
+  _M_pathname += s;
+  // Update s to refer to the new copy (this ensures s is not a dangling
+  // reference to deallocated characters, in the case where it was referring
+  // into _M_pathname or a member of _M_cmpts).
+  s = _M_pathname;
+  const auto orig_pathname = s.substr(0, orig_pathlen);
+  s.remove_prefix(orig_pathlen);
+
+  _Parser parser(s, orig_pathlen);
+  auto cmpt = parser.next();
+
+  if (cmpt.str.data() == s.data())
+    {
+      // See if there's a filename or root-name at the end of the original path
+      // that we can add to.
+      if (_M_type() == _Type::_Filename
+#if SLASHSLASH_IS_ROOTNAME
+         || _M_type() == _Type::_Root_name
+#endif
+         )
+       {
+         if (cmpt.str.length() == s.length())
+           {
+             // Simplest case where we just need to add the whole of s
+             // to the original path, which was already done above.
+             return;
+           }
+         // Only the first component of s should be appended, do so below:
+         extra = cmpt.str;
+         cmpt = {}; // so we don't process it again
+       }
+      else if (_M_type() == _Type::_Multi
+         && _M_cmpts.back()._M_type() == _Type::_Filename)
+       {
+         auto& back = _M_cmpts.back();
+         if (cmpt.str.length() == s.length())
+           {
+             back._M_pathname += s;
+             return;
+           }
+
+         orig_filenamelen = back._M_pathname.length();
+         back._M_pathname += cmpt.str;
+         extra = cmpt.str;
+         cmpt = {};
+       }
+    }
+  else if (is_dir_sep(orig_pathname.back()) && _M_type() == _Type::_Multi
+      && _M_cmpts.back()._M_type() == _Type::_Filename)
+    orig_filenamelen = 0; // original path had empty filename at end
+
+  std::array<_Parser::cmpt, 64> buf;
+  auto next = buf.begin();
+
+  if (cmpt.valid())
+    *next++ = cmpt;
+
+  cmpt = parser.next();
+  while (cmpt.valid() && next != buf.end())
+    {
+      *next++ = cmpt;
+      cmpt = parser.next();
+    }
+
+  int capacity = 0;
+  if (_M_type() == _Type::_Multi)
+    capacity += _M_cmpts.size();
+  else
+    capacity += 1;
+
+  capacity += next - buf.begin();
+
+  if (cmpt.valid()) // filled buffer before parsing whole input
+    {
+      ++capacity;
+      _Parser parser2(parser);
+      while (parser2.next().valid())
+       ++capacity;
+    }
+
+#if SLASHSLASH_IS_ROOTNAME
+  if (orig_type == _Type::_Root_name)
+    ++capacity; // Need to insert root-directory after root-name
+#endif
+
+  __try
+    {
+      _M_cmpts.type(_Type::_Multi);
+      _M_cmpts.reserve(capacity);
+      _Cmpt* output = _M_cmpts._M_impl->end();
+      auto it = buf.begin();
+
+      if (orig_type != _Type::_Multi)
+       {
+         // Create single component from original path
+         auto p = ::new(output++) _Cmpt({}, orig_type, 0);
+         ++_M_cmpts._M_impl->_M_size;
+         p->_M_pathname.reserve(orig_pathname.length() + extra.length());
+         p->_M_pathname = orig_pathname;
+         p->_M_pathname += extra;
+
+#if SLASHSLASH_IS_ROOTNAME
+         if (orig_type == _Type::_Root_name)
+           {
+             ::new(output++) _Cmpt(s.substr(extra.length(), 1),
+                 _Type::_Root_dir, orig_pathlen + extra.length());
+             ++_M_cmpts._M_impl->_M_size;
+           }
+#endif
+       }
+      else if (orig_filenamelen == 0 && extra.empty())
+       {
+         // Replace empty filename at end of original path.
+         std::prev(output)->_M_pathname = it->str;
+         std::prev(output)->_M_pos = parser.offset(*it);
+         ++it;
+       }
+
+      while (it != next)
+       {
+         ::new(output++) _Cmpt(it->str, _Type::_Filename, parser.offset(*it));
+         ++_M_cmpts._M_impl->_M_size;
+         ++it;
+       }
+
+      if (next == buf.end())
+       {
+         while (cmpt.valid())
+           {
+             auto pos = parser.offset(cmpt);
+             ::new(output++) _Cmpt(cmpt.str, _Type::_Filename, pos);
+             ++_M_cmpts._M_impl->_M_size;
+             cmpt = parser.next();
+           }
+       }
+    }
+  __catch (...)
+    {
+      _M_pathname.resize(orig_pathlen);
+      if (orig_type == _Type::_Multi)
+       {
+         _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
+         if (orig_filenamelen != -1)
+           {
+             auto& back = _M_cmpts.back();
+             back._M_pathname.resize(orig_filenamelen);
+             if (orig_filenamelen == 0)
+               back._M_pos = orig_pathlen;
+           }
+       }
+      else
+       _M_cmpts.clear();
+      _M_cmpts.type(orig_type);
+      __throw_exception_again;
+    }
+}
+
+path&
+path::remove_filename()
+{
+  if (_M_type() == _Type::_Multi)
+    {
+      if (!_M_cmpts.empty())
+       {
+         auto cmpt = std::prev(_M_cmpts.end());
+         if (cmpt->_M_type() == _Type::_Filename && !cmpt->empty())
+           {
+             _M_pathname.erase(cmpt->_M_pos);
+             auto prev = std::prev(cmpt);
+             if (prev->_M_type() == _Type::_Root_dir
+                 || prev->_M_type() == _Type::_Root_name)
+               {
+                 _M_cmpts.pop_back();
+                 if (_M_cmpts.size() == 1)
+                   {
+                     _M_cmpts.type(_M_cmpts.front()._M_type());
+                     _M_cmpts.clear();
+                   }
+               }
+             else
+               cmpt->clear();
+           }
+       }
+    }
+  else if (_M_type() == _Type::_Filename)
+    clear();
+  return *this;
+}
+
+path&
+path::replace_filename(const path& replacement)
+{
+  remove_filename();
+  operator/=(replacement);
+  return *this;
+}
+
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+const fs::path::value_type dot = L'.';
+#else
+const fs::path::value_type dot = '.';
+#endif
+
+path&
+path::replace_extension(const path& replacement)
+{
+  auto ext = _M_find_extension();
+  // Any existing extension() is removed
+  if (ext.first && ext.second != string_type::npos)
+    {
+      if (ext.first == &_M_pathname)
+       _M_pathname.erase(ext.second);
+      else
+       {
+         const auto& back = _M_cmpts.back();
+         if (ext.first != &back._M_pathname)
+           _GLIBCXX_THROW_OR_ABORT(
+               std::logic_error("path::replace_extension failed"));
+         _M_pathname.erase(back._M_pos + ext.second);
+       }
+    }
+   // If replacement is not empty and does not begin with a dot character,
+   // a dot character is appended
+  if (!replacement.empty() && replacement.native()[0] != dot)
+    _M_pathname += dot;
+  operator+=(replacement);
+  return *this;
+}
+
+int
+path::compare(const path& p) const noexcept
+{
+  if (_M_pathname == p._M_pathname)
+    return 0;
+
+  basic_string_view<value_type> lroot, rroot;
+  if (_M_type() == _Type::_Root_name)
+    lroot = _M_pathname;
+  else if (_M_type() == _Type::_Multi
+      && _M_cmpts.front()._M_type() == _Type::_Root_name)
+    lroot = _M_cmpts.front()._M_pathname;
+  if (p._M_type() == _Type::_Root_name)
+    rroot = p._M_pathname;
+  else if (p._M_type() == _Type::_Multi
+      && p._M_cmpts.front()._M_type() == _Type::_Root_name)
+    rroot = p._M_cmpts.front()._M_pathname;
+  if (int rootNameComparison = lroot.compare(rroot))
+    return rootNameComparison;
+
+  if (!this->has_root_directory() && p.has_root_directory())
+    return -1;
+  else if (this->has_root_directory() && !p.has_root_directory())
+    return +1;
+
+  using Iterator = const _Cmpt*;
+  Iterator begin1, end1, begin2, end2;
+  if (_M_type() == _Type::_Multi)
+    {
+      begin1 = _M_cmpts.begin();
+      end1 = _M_cmpts.end();
+      // Find start of this->relative_path()
+      while (begin1 != end1 && begin1->_M_type() != _Type::_Filename)
+       ++begin1;
+    }
+  else
+    begin1 = end1 = nullptr;
+
+  if (p._M_type() == _Type::_Multi)
+    {
+      begin2 = p._M_cmpts.begin();
+      end2 = p._M_cmpts.end();
+      // Find start of p.relative_path()
+      while (begin2 != end2 && begin2->_M_type() != _Type::_Filename)
+       ++begin2;
+    }
+  else
+    begin2 = end2 = nullptr;
+
+  if (_M_type() == _Type::_Filename)
+    {
+      if (p._M_type() == _Type::_Filename)
+       return native().compare(p.native());
+      else if (begin2 != end2)
+       {
+         if (int ret = native().compare(begin2->native()))
+           return ret;
+         else
+           return ++begin2 == end2 ? 0 : -1;
+       }
+      else
+       return +1;
+    }
+  else if (p._M_type() == _Type::_Filename)
+    {
+      if (begin1 != end1)
+       {
+         if (int ret = begin1->native().compare(p.native()))
+           return ret;
+         else
+           return ++begin1 == end1 ? 0 : +1;
+       }
+      else
+       return -1;
+    }
+
+  int count = 1;
+  while (begin1 != end1 && begin2 != end2)
+    {
+      if (int i = begin1->native().compare(begin2->native()))
+       return i;
+      ++begin1;
+      ++begin2;
+      ++count;
+    }
+  if (begin1 == end1)
+    {
+      if (begin2 == end2)
+       return 0;
+      return -count;
+    }
+  return count;
+}
+
+int
+path::compare(basic_string_view<value_type> s) const noexcept
+{
+  if (_M_pathname == s)
+    return 0;
+
+  _Parser parser(s);
+
+  basic_string_view<value_type> lroot, rroot;
+  if (_M_type() == _Type::_Root_name)
+    lroot = _M_pathname;
+  else if (_M_type() == _Type::_Multi
+      && _M_cmpts.front()._M_type() == _Type::_Root_name)
+    lroot = _M_cmpts.front()._M_pathname;
+  auto root_path = parser.root_path();
+  if (root_path.first.type == _Type::_Root_name)
+    rroot = root_path.first.str;
+  if (int rootNameComparison = lroot.compare(rroot))
+    return rootNameComparison;
+
+  const bool has_root_dir = root_path.first.type == _Type::_Root_dir
+    || root_path.second.type == _Type::_Root_dir;
+  if (!this->has_root_directory() && has_root_dir)
+    return -1;
+  else if (this->has_root_directory() && !has_root_dir)
+    return +1;
+
+  using Iterator = const _Cmpt*;
+  Iterator begin1, end1;
+  if (_M_type() == _Type::_Filename)
+    {
+      auto cmpt = parser.next();
+      if (cmpt.valid())
+       {
+         if (int ret = this->native().compare(cmpt.str))
+           return ret;
+         return parser.next().valid() ? -1 : 0;
+       }
+      else
+       return +1;
+    }
+  else if (_M_type() == _Type::_Multi)
+    {
+      begin1 = _M_cmpts.begin();
+      end1 = _M_cmpts.end();
+      while (begin1 != end1 && begin1->_M_type() != _Type::_Filename)
+       ++begin1;
+    }
+  else
+    begin1 = end1 = nullptr;
+
+  int count = 1;
+  auto cmpt = parser.next();
+  while (begin1 != end1 && cmpt.valid())
+    {
+      if (int i = begin1->native().compare(cmpt.str))
+       return i;
+      ++begin1;
+      cmpt = parser.next();
+      ++count;
+    }
+  if (begin1 == end1)
+    {
+      if (!cmpt.valid())
+       return 0;
+      return -count;
+    }
+  return +count;
+}
+
+path
+path::root_name() const
+{
+  path __ret;
+  if (_M_type() == _Type::_Root_name)
+    __ret = *this;
+  else if (_M_cmpts.size() && _M_cmpts.begin()->_M_type() == _Type::_Root_name)
+    __ret = *_M_cmpts.begin();
+  return __ret;
+}
+
+path
+path::root_directory() const
+{
+  path __ret;
+  if (_M_type() == _Type::_Root_dir)
+    {
+      __ret._M_cmpts.type(_Type::_Root_dir);
+      __ret._M_pathname.assign(1, preferred_separator);
+    }
+  else if (!_M_cmpts.empty())
+    {
+      auto __it = _M_cmpts.begin();
+      if (__it->_M_type() == _Type::_Root_name)
+        ++__it;
+      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
+        __ret = *__it;
+    }
+  return __ret;
+}
+
+path
+path::root_path() const
+{
+  path __ret;
+  if (_M_type() == _Type::_Root_name)
+    __ret = *this;
+  else if (_M_type() == _Type::_Root_dir)
+    {
+      __ret._M_pathname.assign(1, preferred_separator);
+      __ret._M_cmpts.type(_Type::_Root_dir);
+    }
+  else if (!_M_cmpts.empty())
+    {
+      auto __it = _M_cmpts.begin();
+      if (__it->_M_type() == _Type::_Root_name)
+        {
+          __ret = *__it++;
+          if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
+           __ret /= *__it;
+        }
+      else if (__it->_M_type() == _Type::_Root_dir)
+        __ret = *__it;
+    }
+  return __ret;
+}
+
+path
+path::relative_path() const
+{
+  path __ret;
+  if (_M_type() == _Type::_Filename)
+    __ret = *this;
+  else if (!_M_cmpts.empty())
+    {
+      auto __it = _M_cmpts.begin();
+      if (__it->_M_type() == _Type::_Root_name)
+        ++__it;
+      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
+        ++__it;
+      if (__it != _M_cmpts.end())
+        __ret.assign(_M_pathname.substr(__it->_M_pos));
+    }
+  return __ret;
+}
+
+path
+path::parent_path() const
+{
+  path __ret;
+  if (!has_relative_path())
+    __ret = *this;
+  else if (_M_cmpts.size() >= 2)
+    {
+      for (auto __it = _M_cmpts.begin(), __end = std::prev(_M_cmpts.end());
+          __it != __end; ++__it)
+       {
+         __ret /= *__it;
+       }
+    }
+  return __ret;
+}
+
+bool
+path::has_root_name() const
+{
+  if (_M_type() == _Type::_Root_name)
+    return true;
+  if (!_M_cmpts.empty() && _M_cmpts.begin()->_M_type() == _Type::_Root_name)
+    return true;
+  return false;
+}
+
+bool
+path::has_root_directory() const
+{
+  if (_M_type() == _Type::_Root_dir)
+    return true;
+  if (!_M_cmpts.empty())
+    {
+      auto __it = _M_cmpts.begin();
+      if (__it->_M_type() == _Type::_Root_name)
+        ++__it;
+      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
+        return true;
+    }
+  return false;
+}
+
+bool
+path::has_root_path() const
+{
+  if (_M_type() == _Type::_Root_name || _M_type() == _Type::_Root_dir)
+    return true;
+  if (!_M_cmpts.empty())
+    {
+      auto __type = _M_cmpts.front()._M_type();
+      if (__type == _Type::_Root_name || __type == _Type::_Root_dir)
+        return true;
+    }
+  return false;
+}
+
+bool
+path::has_relative_path() const
+{
+  if (_M_type() == _Type::_Filename && !_M_pathname.empty())
+    return true;
+  if (!_M_cmpts.empty())
+    {
+      auto __it = _M_cmpts.begin();
+      if (__it->_M_type() == _Type::_Root_name)
+        ++__it;
+      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
+        ++__it;
+      if (__it != _M_cmpts.end() && !__it->_M_pathname.empty())
+        return true;
+    }
+  return false;
+}
+
+
+bool
+path::has_parent_path() const
+{
+  if (!has_relative_path())
+    return !empty();
+  return _M_cmpts.size() >= 2;
+}
+
+bool
+path::has_filename() const
+{
+  if (empty())
+    return false;
+  if (_M_type() == _Type::_Filename)
+    return !_M_pathname.empty();
+  if (_M_type() == _Type::_Multi)
+    {
+      if (_M_pathname.back() == preferred_separator)
+       return false;
+      return _M_cmpts.back().has_filename();
+    }
+  return false;
+}
+
+namespace
+{
+  inline bool is_dot(fs::path::value_type c) { return c == dot; }
+
+  inline bool is_dot(const fs::path& path)
+  {
+    const auto& filename = path.native();
+    return filename.size() == 1 && is_dot(filename[0]);
+  }
+
+  inline bool is_dotdot(const fs::path& path)
+  {
+    const auto& filename = path.native();
+    return filename.size() == 2 && is_dot(filename[0]) && is_dot(filename[1]);
+  }
+} // namespace
+
+path
+path::lexically_normal() const
+{
+  /*
+  C++17 [fs.path.generic] p6
+  - If the path is empty, stop.
+  - Replace each slash character in the root-name with a preferred-separator.
+  - Replace each directory-separator with a preferred-separator.
+  - Remove each dot filename and any immediately following directory-separator.
+  - As long as any appear, remove a non-dot-dot filename immediately followed
+    by a directory-separator and a dot-dot filename, along with any immediately
+    following directory-separator.
+  - If there is a root-directory, remove all dot-dot filenames and any
+    directory-separators immediately following them.
+  - If the last filename is dot-dot, remove any trailing directory-separator.
+  - If the path is empty, add a dot.
+  */
+  path ret;
+  // If the path is empty, stop.
+  if (empty())
+    return ret;
+  for (auto& p : *this)
+    {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+      // Replace each slash character in the root-name
+      if (p._M_type() == _Type::_Root_name || p._M_type() == _Type::_Root_dir)
+       {
+         string_type s = p.native();
+         std::replace(s.begin(), s.end(), L'/', L'\\');
+         ret /= s;
+         continue;
+       }
+#endif
+      if (is_dotdot(p))
+       {
+         if (ret.has_filename())
+           {
+             // remove a non-dot-dot filename immediately followed by /..
+             if (!is_dotdot(ret.filename()))
+               ret.remove_filename();
+             else
+               ret /= p;
+           }
+         else if (!ret.has_relative_path())
+           {
+             // remove a dot-dot filename immediately after root-directory
+             if (!ret.has_root_directory())
+               ret /= p;
+           }
+         else
+           {
+             // Got a path with a relative path (i.e. at least one non-root
+             // element) and no filename at the end (i.e. empty last element),
+             // so must have a trailing slash. See what is before it.
+             auto elem = ret._M_cmpts.end() - 2;
+             if (elem->has_filename() && !is_dotdot(*elem))
+               {
+                 // Remove the filename before the trailing slash
+                 // (equiv. to ret = ret.parent_path().remove_filename())
+
+                 if (elem == ret._M_cmpts.begin())
+                   ret.clear();
+                 else
+                   {
+                     ret._M_pathname.erase(elem->_M_pos);
+                     // Remove empty filename at the end:
+                     ret._M_cmpts.pop_back();
+                     // If we still have a trailing non-root dir separator
+                     // then leave an empty filename at the end:
+                     if (std::prev(elem)->_M_type() == _Type::_Filename)
+                       elem->clear();
+                     else // remove the component completely:
+                       ret._M_cmpts.pop_back();
+                   }
+               }
+             else
+               // Append the ".." to something ending in "../" which happens
+               // when normalising paths like ".././.." and "../a/../.."
+               ret /= p;
+           }
+       }
+      else if (is_dot(p))
+       ret /= path();
+#if SLASHSLASH_IS_ROOTNAME
+      else if (p._M_type() == _Type::_Root_dir)
+       ret += '/'; // using operator/=('/') would replace whole of ret
+#endif
+      else
+       ret /= p;
+    }
+
+  if (ret._M_cmpts.size() >= 2)
+    {
+      auto back = std::prev(ret.end());
+      // If the last filename is dot-dot, ...
+      if (back->empty() && is_dotdot(*std::prev(back)))
+       // ... remove any trailing directory-separator.
+       ret = ret.parent_path();
+    }
+  // If the path is empty, add a dot.
+  else if (ret.empty())
+    ret = ".";
+
+  return ret;
+}
+
+path
+path::lexically_relative(const path& base) const
+{
+  path ret;
+  if (root_name() != base.root_name())
+    return ret;
+  if (is_absolute() != base.is_absolute())
+    return ret;
+  if (!has_root_directory() && base.has_root_directory())
+    return ret;
+  auto [a, b] = std::mismatch(begin(), end(), base.begin(), base.end());
+  if (a == end() && b == base.end())
+    ret = ".";
+  else
+  {
+    int n = 0;
+    for (; b != base.end(); ++b)
+    {
+      const path& p = *b;
+      if (is_dotdot(p))
+       --n;
+      else if (!p.empty() && !is_dot(p))
+       ++n;
+    }
+    if (n == 0 && (a == end() || a->empty()))
+      ret = ".";
+    else if (n >= 0)
+    {
+      const path dotdot("..");
+      while (n--)
+       ret /= dotdot;
+      for (; a != end(); ++a)
+       ret /= *a;
+    }
+  }
+  return ret;
+}
+
+path
+path::lexically_proximate(const path& base) const
+{
+  path rel = lexically_relative(base);
+  if (rel.empty())
+    rel = *this;
+  return rel;
+}
+
+std::pair<const path::string_type*, std::size_t>
+path::_M_find_extension() const
+{
+  const string_type* s = nullptr;
+
+  if (_M_type() == _Type::_Filename)
+    s = &_M_pathname;
+  else if (_M_type() == _Type::_Multi && !_M_cmpts.empty())
+    {
+      const auto& c = _M_cmpts.back();
+      if (c._M_type() == _Type::_Filename)
+       s = &c._M_pathname;
+    }
+
+  if (s)
+    {
+      if (auto sz = s->size())
+       {
+         if (sz <= 2 && (*s)[0] == dot)
+           return { s, string_type::npos };
+         const auto pos = s->rfind(dot);
+         return { s, pos ? pos : string_type::npos };
+       }
+    }
+  return {};
+}
+
+void
+path::_M_split_cmpts()
+{
+  _M_cmpts.clear();
+
+  if (_M_pathname.empty())
+    {
+      _M_cmpts.type(_Type::_Filename);
+      return;
+    }
+  if (_M_pathname.length() == 1 && _M_pathname[0] == preferred_separator)
+    {
+      _M_cmpts.type(_Type::_Root_dir);
+      return;
+    }
+
+  _Parser parser(_M_pathname);
+
+  std::array<_Parser::cmpt, 64> buf;
+  auto next = buf.begin();
+
+  // look for root name or root directory
+  auto root_path = parser.root_path();
+  if (root_path.first.valid())
+    {
+      *next++ = root_path.first;
+      if (root_path.second.valid())
+       *next++ = root_path.second;
+    }
+
+  auto cmpt = parser.next();
+  while (cmpt.valid())
+    {
+      do
+       {
+         *next++ = cmpt;
+         cmpt = parser.next();
+       }
+      while (cmpt.valid() && next != buf.end());
+
+      if (next == buf.end())
+       {
+         _M_cmpts.type(_Type::_Multi);
+         _M_cmpts.reserve(_M_cmpts.size() + buf.size());
+         auto output = _M_cmpts._M_impl->end();
+         for (auto& c : buf)
+           {
+             auto pos = c.str.data() - _M_pathname.data();
+             ::new(output++) _Cmpt(c.str, c.type, pos);
+             ++_M_cmpts._M_impl->_M_size;
+           }
+         next = buf.begin();
+       }
+    }
+
+  if (auto n = next - buf.begin())
+    {
+      if (n == 1 && _M_cmpts.empty())
+       {
+         _M_cmpts.type(buf.front().type);
+         return;
+       }
+
+      _M_cmpts.type(_Type::_Multi);
+      _M_cmpts.reserve(_M_cmpts.size() + n, true);
+      auto output = _M_cmpts._M_impl->end();
+      for (int i = 0; i < n; ++i)
+       {
+         auto c = buf[i];
+         auto pos = c.str.data() - _M_pathname.data();
+         ::new(output++) _Cmpt(c.str, c.type, pos);
+         ++_M_cmpts._M_impl->_M_size;
+       }
+    }
+}
+
+path::string_type
+path::_S_convert_loc(const char* __first, const char* __last,
+                    const std::locale& __loc)
+{
+#if _GLIBCXX_USE_WCHAR_T
+  auto& __cvt = std::use_facet<codecvt<wchar_t, char, mbstate_t>>(__loc);
+  basic_string<wchar_t> __ws;
+  if (!__str_codecvt_in(__first, __last, __ws, __cvt))
+    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+         "Cannot convert character sequence",
+         std::make_error_code(errc::illegal_byte_sequence)));
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  return __ws;
+#else
+  return _Cvt<wchar_t>::_S_convert(__ws.data(), __ws.data() + __ws.size());
+#endif
+#else
+  return {__first, __last};
+#endif
+}
+
+std::size_t
+fs::hash_value(const path& p) noexcept
+{
+  // [path.non-member]
+  // "If for two paths, p1 == p2 then hash_value(p1) == hash_value(p2)."
+  // Equality works as if by traversing the range [begin(), end()), meaning
+  // e.g. path("a//b") == path("a/b"), so we cannot simply hash _M_pathname
+  // but need to iterate over individual elements. Use the hash_combine from
+  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3876.pdf
+  size_t seed = 0;
+  for (const auto& x : p)
+    {
+      seed ^= std::hash<path::string_type>()(x.native()) + 0x9e3779b9
+       + (seed<<6) + (seed>>2);
+    }
+  return seed;
+}
+
+struct fs::filesystem_error::_Impl
+{
+  _Impl(const string& what_arg, const path& p1, const path& p2)
+  : path1(p1), path2(p2), what(make_what(what_arg, &p1, &p2))
+  { }
+
+  _Impl(const string& what_arg, const path& p1)
+  : path1(p1), path2(), what(make_what(what_arg, &p1, nullptr))
+  { }
+
+  _Impl(const string& what_arg)
+  : what(make_what(what_arg, nullptr, nullptr))
+  { }
+
+  static std::string
+  make_what(const std::string& s, const path* p1, const path* p2)
+  {
+    const std::string pstr1 = p1 ? p1->u8string() : std::string{};
+    const std::string pstr2 = p2 ? p2->u8string() : std::string{};
+    const size_t len = 18 + s.length()
+      + (pstr1.length() ? pstr1.length() + 3 : 0)
+      + (pstr2.length() ? pstr2.length() + 3 : 0);
+    std::string w;
+    w.reserve(len);
+    w = "filesystem error: ";
+    w += s;
+    if (p1)
+      {
+       w += " [";
+       w += pstr1;
+       w += ']';
+       if (p2)
+         {
+           w += " [";
+           w += pstr2;
+           w += ']';
+         }
+      }
+    return w;
+  }
+
+  path path1;
+  path path2;
+  std::string what;
+};
+
+template class std::__shared_ptr<const fs::filesystem_error::_Impl>;
+
+fs::filesystem_error::
+filesystem_error(const string& what_arg, error_code ec)
+: system_error(ec, what_arg),
+  _M_impl(std::__make_shared<_Impl>(what_arg))
+{ }
+
+fs::filesystem_error::
+filesystem_error(const string& what_arg, const path& p1, error_code ec)
+: system_error(ec, what_arg),
+  _M_impl(std::__make_shared<_Impl>(what_arg, p1))
+{ }
+
+fs::filesystem_error::
+filesystem_error(const string& what_arg, const path& p1, const path& p2,
+                error_code ec)
+: system_error(ec, what_arg),
+  _M_impl(std::__make_shared<_Impl>(what_arg, p1, p2))
+{ }
+
+fs::filesystem_error::~filesystem_error() = default;
+
+const fs::path&
+fs::filesystem_error::path1() const noexcept
+{ return _M_impl->path1; }
+
+const fs::path&
+fs::filesystem_error::path2() const noexcept
+{ return _M_impl->path2; }
+
+const char*
+fs::filesystem_error::what() const noexcept
+{ return _M_impl->what.c_str(); }
index 12367c7c02c8569d99a43f8d7ac1144d9b262619..6f2a9f63b8aeb74834da5c09d5c8f2e10698f285 100644 (file)
@@ -32,8 +32,7 @@ cxx11_abi_sources = \
        cow-ops.cc \
        cow-path.cc \
        cow-std-dir.cc \
-       cow-std-ops.cc \
-       cow-std-path.cc
+       cow-std-ops.cc
 else
 cxx11_abi_sources =
 endif
@@ -44,7 +43,6 @@ sources = \
        path.cc \
        std-dir.cc \
        std-ops.cc \
-       std-path.cc \
        ${cxx11_abi_sources}
 
 # vpath % $(top_srcdir)/src/filesystem
index f23451180335917190ef57b7812008d0e89df0e5..12524ff1cc694bd6b9fccf76ca0cf5c8d0996c6a 100644 (file)
@@ -151,9 +151,9 @@ LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
 libstdc__fs_la_LIBADD =
 @ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-dir.lo cow-ops.lo \
 @ENABLE_DUAL_ABI_TRUE@ cow-path.lo cow-std-dir.lo \
-@ENABLE_DUAL_ABI_TRUE@ cow-std-ops.lo cow-std-path.lo
+@ENABLE_DUAL_ABI_TRUE@ cow-std-ops.lo
 am__objects_2 = dir.lo ops.lo path.lo std-dir.lo std-ops.lo \
-       std-path.lo $(am__objects_1)
+       $(am__objects_1)
 am_libstdc__fs_la_OBJECTS = $(am__objects_2)
 libstdc__fs_la_OBJECTS = $(am_libstdc__fs_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -444,8 +444,7 @@ headers =
 @ENABLE_DUAL_ABI_TRUE@ cow-ops.cc \
 @ENABLE_DUAL_ABI_TRUE@ cow-path.cc \
 @ENABLE_DUAL_ABI_TRUE@ cow-std-dir.cc \
-@ENABLE_DUAL_ABI_TRUE@ cow-std-ops.cc \
-@ENABLE_DUAL_ABI_TRUE@ cow-std-path.cc
+@ENABLE_DUAL_ABI_TRUE@ cow-std-ops.cc
 
 sources = \
        dir.cc \
@@ -453,7 +452,6 @@ sources = \
        path.cc \
        std-dir.cc \
        std-ops.cc \
-       std-path.cc \
        ${cxx11_abi_sources}
 
 
diff --git a/libstdc++-v3/src/filesystem/cow-std-path.cc b/libstdc++-v3/src/filesystem/cow-std-path.cc
deleted file mode 100644 (file)
index f0717ae..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Class filesystem::path -*- C++ -*-
-
-// Copyright (C) 2015-2019 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-#define _GLIBCXX_USE_CXX11_ABI 0
-#include "std-path.cc"
diff --git a/libstdc++-v3/src/filesystem/std-path.cc b/libstdc++-v3/src/filesystem/std-path.cc
deleted file mode 100644 (file)
index 34de52f..0000000
+++ /dev/null
@@ -1,2007 +0,0 @@
-// Class filesystem::path -*- C++ -*-
-
-// Copyright (C) 2014-2019 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef _GLIBCXX_USE_CXX11_ABI
-# define _GLIBCXX_USE_CXX11_ABI 1
-#endif
-
-#ifdef __CYGWIN__
-// Interpret "//x" as a root-name, not root-dir + filename
-# define SLASHSLASH_IS_ROOTNAME 1
-#endif
-
-#include <filesystem>
-#include <algorithm>
-#include <bits/stl_uninitialized.h>
-
-namespace fs = std::filesystem;
-using fs::path;
-
-static inline bool is_dir_sep(path::value_type ch)
-{
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-    return ch == L'/' || ch == path::preferred_separator;
-#else
-    return ch == '/';
-#endif
-}
-
-struct path::_Parser
-{
-  using string_view_type = std::basic_string_view<value_type>;
-
-  struct cmpt
-  {
-    string_view_type str;
-    _Type type = _Type::_Multi;
-
-    bool valid() const { return type != _Type::_Multi; }
-  };
-
-  string_view_type input;
-  string_view_type::size_type pos = 0;
-  size_t origin;
-  _Type last_type = _Type::_Multi;
-
-  _Parser(string_view_type s, size_t o = 0) : input(s), origin(o) { }
-
-  pair<cmpt, cmpt> root_path() noexcept
-  {
-    pos = 0;
-    pair<cmpt, cmpt> root;
-
-    const size_t len = input.size();
-
-    // look for root name or root directory
-    if (is_dir_sep(input[0]))
-      {
-#if SLASHSLASH_IS_ROOTNAME
-       // look for root name, such as "//foo"
-       if (len > 2 && input[1] == input[0])
-         {
-           if (!is_dir_sep(input[2]))
-             {
-               // got root name, find its end
-               pos = 3;
-               while (pos < len && !is_dir_sep(input[pos]))
-                 ++pos;
-               root.first.str = input.substr(0, pos);
-               root.first.type = _Type::_Root_name;
-
-               if (pos < len) // also got root directory
-                 {
-                   root.second.str = input.substr(pos, 1);
-                   root.second.type = _Type::_Root_dir;
-                   ++pos;
-                 }
-             }
-           else
-             {
-               // got something like "///foo" which is just a root directory
-               // composed of multiple redundant directory separators
-               root.first.str = input.substr(0, 1);
-               root.first.type = _Type::_Root_dir;
-               pos += 2;
-             }
-         }
-       else
-#endif
-         {
-           root.first.str = input.substr(0, 1);
-           root.first.type = _Type::_Root_dir;
-           ++pos;
-         }
-       // Find the start of the first filename
-       while (pos < len && is_dir_sep(input[pos]))
-         ++pos;
-      }
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-    else if (len > 1 && input[1] == L':')
-      {
-       // got disk designator
-       root.first.str = input.substr(0, 2);
-       root.first.type = _Type::_Root_name;
-       if (len > 2 && is_dir_sep(input[2]))
-         {
-           root.second.str = input.substr(2, 1);
-           root.second.type = _Type::_Root_dir;
-         }
-       pos = input.find_first_not_of(L"/\\", 2);
-      }
-#endif
-
-    if (root.second.valid())
-      last_type = root.second.type;
-    else
-      last_type = root.first.type;
-
-    return root;
-  }
-
-  cmpt next() noexcept
-  {
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-    string_view_type sep = L"/\\";
-#else
-    char sep = '/';
-#endif
-
-    const int last_pos = pos;
-
-    cmpt f;
-    if (pos != input.npos)
-      {
-       pos = input.find_first_not_of(sep, pos);
-       if (pos != input.npos)
-         {
-           const auto end = input.find_first_of(sep, pos);
-           f.str = input.substr(pos, end - pos);
-           f.type = _Type::_Filename;
-           pos = end;
-         }
-       else if (last_type == _Type::_Filename
-           || (last_pos == 0 && !input.empty()))
-         {
-           // [fs.path.itr]/4 An empty element, if trailing non-root
-           // directory-separator present.
-           __glibcxx_assert(is_dir_sep(input.back()));
-           f.str = input.substr(input.length(), 0);
-           f.type = _Type::_Filename;
-         }
-      }
-    last_type = f.type;
-    return f;
-  }
-
-  string_view_type::size_type
-  offset(const cmpt& c) const noexcept
-  { return origin + c.str.data() - input.data(); }
-};
-
-struct path::_List::_Impl
-{
-  using value_type = _Cmpt;
-
-  _Impl(int cap) : _M_size(0), _M_capacity(cap) { }
-
-  alignas(value_type) int _M_size;
-  int _M_capacity;
-
-  using iterator = value_type*;
-  using const_iterator = const value_type*;
-
-  iterator begin() { return reinterpret_cast<value_type*>(this + 1); }
-  iterator end() { return begin() + size(); }
-
-  const_iterator begin() const
-  { return reinterpret_cast<const value_type*>(this + 1); }
-  const_iterator end() const { return begin() + size(); }
-
-  const value_type& front() const { return *begin(); }
-  const value_type& back() const { return end()[-1]; }
-
-  int size() const { return _M_size; }
-  int capacity() const { return _M_capacity; }
-  bool empty() const { return _M_size == 0; }
-
-  void clear() { std::destroy_n(begin(), _M_size); _M_size = 0; }
-
-  void pop_back()
-  {
-    back().~_Cmpt();
-    --_M_size;
-  }
-
-  void _M_erase_from(const_iterator pos)
-  {
-    iterator first = begin() + (pos - begin());
-    iterator last = end();
-    std::destroy(first, last);
-    _M_size -= last - first;
-  }
-
-  unique_ptr<_Impl, _Impl_deleter> copy() const
-  {
-    const auto n = size();
-    void* p = ::operator new(sizeof(_Impl) + n * sizeof(value_type));
-    unique_ptr<_Impl, _Impl_deleter> newptr(::new (p) _Impl{n});
-    std::uninitialized_copy_n(begin(), n, newptr->begin());
-    newptr->_M_size = n;
-    return newptr;
-  }
-
-  // Clear the lowest two bits from the pointer (i.e. remove the _Type value)
-  static _Impl* notype(_Impl* p)
-  {
-    constexpr uintptr_t mask = ~(uintptr_t)0x3;
-    return reinterpret_cast<_Impl*>(reinterpret_cast<uintptr_t>(p) & mask);
-  }
-};
-
-void path::_List::_Impl_deleter::operator()(_Impl* p) const noexcept
-{
-  p = _Impl::notype(p);
-  if (p)
-    {
-      __glibcxx_assert(p->_M_size <= p->_M_capacity);
-      p->clear();
-      ::operator delete(p, sizeof(*p) + p->_M_capacity * sizeof(value_type));
-    }
-}
-
-path::_List::_List() : _M_impl(reinterpret_cast<_Impl*>(_Type::_Filename)) { }
-
-path::_List::_List(const _List& other)
-{
-  if (!other.empty())
-    _M_impl = other._M_impl->copy();
-  else
-    type(other.type());
-}
-
-path::_List&
-path::_List::operator=(const _List& other)
-{
-  if (!other.empty())
-    {
-      // copy in-place if there is capacity
-      const int newsize = other._M_impl->size();
-      auto impl = _Impl::notype(_M_impl.get());
-      if (impl && impl->capacity() >= newsize)
-       {
-         const int oldsize = impl->_M_size;
-         auto to = impl->begin();
-         auto from = other._M_impl->begin();
-         const int minsize = std::min(newsize, oldsize);
-         for (int i = 0; i < minsize; ++i)
-           to[i]._M_pathname.reserve(from[i]._M_pathname.length());
-         if (newsize > oldsize)
-           {
-             std::uninitialized_copy_n(to + oldsize, newsize - oldsize,
-                                       from + oldsize);
-             impl->_M_size = newsize;
-           }
-         else if (newsize < oldsize)
-           impl->_M_erase_from(impl->begin() + newsize);
-         std::copy_n(from, minsize, to);
-         type(_Type::_Multi);
-       }
-      else
-       _M_impl = other._M_impl->copy();
-    }
-  else
-    {
-      clear();
-      type(other.type());
-    }
-  return *this;
-}
-
-inline void
-path::_List::type(_Type t) noexcept
-{
-  auto val = reinterpret_cast<uintptr_t>(_Impl::notype(_M_impl.release()));
-  _M_impl.reset(reinterpret_cast<_Impl*>(val | (unsigned char)t));
-}
-
-inline int
-path::_List::size() const noexcept
-{
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->size();
-  return 0;
-}
-
-inline int
-path::_List::capacity() const noexcept
-{
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->capacity();
-  return 0;
-}
-
-inline bool
-path::_List::empty() const noexcept
-{
-  return size() == 0;
-}
-
-inline auto
-path::_List::begin() noexcept
--> iterator
-{
-  __glibcxx_assert(!empty());
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->begin();
-  return nullptr;
-}
-
-inline auto
-path::_List::end() noexcept
--> iterator
-{
-  __glibcxx_assert(!empty());
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->end();
-  return nullptr;
-}
-
-auto
-path::_List::begin() const noexcept
--> const_iterator
-{
-  __glibcxx_assert(!empty());
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->begin();
-  return nullptr;
-}
-
-auto
-path::_List::end() const noexcept
--> const_iterator
-{
-  __glibcxx_assert(!empty());
-  if (auto* ptr = _Impl::notype(_M_impl.get()))
-    return ptr->end();
-  return nullptr;
-}
-
-inline auto
-path::_List::front() noexcept
--> value_type&
-{
-  return *_M_impl->begin();
-}
-
-inline auto
-path::_List::back() noexcept
--> value_type&
-{
-  return _M_impl->begin()[_M_impl->size() - 1];
-}
-
-inline auto
-path::_List::front() const noexcept
--> const value_type&
-{
-  return *_M_impl->begin();
-}
-
-inline auto
-path::_List::back() const noexcept
--> const value_type&
-{
-  return _M_impl->begin()[_M_impl->size() - 1];
-}
-
-inline void
-path::_List::pop_back()
-{
-  __glibcxx_assert(size() > 0);
-  _M_impl->pop_back();
-}
-
-inline void
-path::_List::_M_erase_from(const_iterator pos)
-{
-  _M_impl->_M_erase_from(pos);
-}
-
-inline void
-path::_List::clear()
-{
-  if (auto ptr = _Impl::notype(_M_impl.get()))
-    ptr->clear();
-}
-
-void
-path::_List::reserve(int newcap, bool exact = false)
-{
-  // __glibcxx_assert(type() == _Type::_Multi);
-
-  _Impl* curptr = _Impl::notype(_M_impl.get());
-
-  int curcap = curptr ? curptr->capacity() : 0;
-
-  if (curcap < newcap)
-    {
-      if (!exact && newcap < int(1.5 * curcap))
-       newcap = 1.5 * curcap;
-
-      void* p = ::operator new(sizeof(_Impl) + newcap * sizeof(value_type));
-      std::unique_ptr<_Impl, _Impl_deleter> newptr(::new(p) _Impl{newcap});
-      const int cursize = curptr ? curptr->size() : 0;
-      if (cursize)
-       {
-         std::uninitialized_move_n(curptr->begin(), cursize, newptr->begin());
-         newptr->_M_size = cursize;
-       }
-      std::swap(newptr, _M_impl);
-    }
-}
-
-path&
-path::operator=(const path& p)
-{
-  _M_pathname.reserve(p._M_pathname.length());
-  _M_cmpts = p._M_cmpts;       // might throw
-  _M_pathname = p._M_pathname; // won't throw because we reserved enough space
-  return *this;
-}
-
-path&
-path::operator/=(const path& __p)
-{
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  if (__p.is_absolute()
-      || (__p.has_root_name() && __p.root_name() != root_name()))
-    return operator=(__p);
-
-  basic_string_view<value_type> __lhs = _M_pathname;
-  bool __add_sep = false;
-
-  if (__p.has_root_directory())
-    {
-      // Remove any root directory and relative path
-      if (_M_type() != _Type::_Root_name)
-       {
-         if (!_M_cmpts.empty()
-             && _M_cmpts.front()._M_type() == _Type::_Root_name)
-           __lhs = _M_cmpts.front()._M_pathname;
-         else
-           __lhs = {};
-       }
-    }
-  else if (has_filename() || (!has_root_directory() && is_absolute()))
-    __add_sep = true;
-
-  basic_string_view<value_type> __rhs = __p._M_pathname;
-  // Omit any root-name from the generic format pathname:
-  if (__p._M_type() == _Type::_Root_name)
-    __rhs = {};
-  else if (!__p._M_cmpts.empty()
-      && __p._M_cmpts.front()._M_type() == _Type::_Root_name)
-    __rhs.remove_prefix(__p._M_cmpts.front()._M_pathname.size());
-
-  const size_t __len = __lhs.size() + (int)__add_sep + __rhs.size();
-  const int __maxcmpts = _M_cmpts.size() + __p._M_cmpts.size();
-  if (_M_pathname.capacity() < __len || _M_cmpts.capacity() < __maxcmpts)
-    {
-      // Construct new path and swap (strong exception-safety guarantee).
-      string_type __tmp;
-      __tmp.reserve(__len);
-      __tmp = __lhs;
-      if (__add_sep)
-       __tmp += preferred_separator;
-      __tmp += __rhs;
-      path __newp = std::move(__tmp);
-      swap(__newp);
-    }
-  else
-    {
-      _M_pathname = __lhs;
-      if (__add_sep)
-       _M_pathname += preferred_separator;
-      _M_pathname += __rhs;
-      __try
-       {
-         _M_split_cmpts();
-       }
-      __catch (...)
-       {
-         __try
-           {
-             // try to restore original state
-             _M_pathname.resize(__lhs.length());
-             _M_split_cmpts();
-           }
-         __catch (...)
-           {
-             // give up, basic exception safety guarantee only:
-             clear();
-             __throw_exception_again;
-           }
-       }
-    }
-#else
-  // POSIX version is simpler than the specification in the standard,
-  // as any path with root-name or root-dir is absolute.
-
-  if (__p.is_absolute() || this->empty())
-    {
-      return operator=(__p);
-    }
-
-  using string_view_type = basic_string_view<value_type>;
-
-  string_view_type sep;
-  if (has_filename())
-    sep = { &preferred_separator, 1 };  // need to add a separator
-#if SLASHSLASH_IS_ROOTNAME
-  else if (_M_type() == _Type::_Root_name) // root-name with no root-dir
-    sep = { &preferred_separator, 1 };  // need to add a separator
-#endif
-  else if (__p.empty())
-    return *this;                          // nothing to do
-
-  const auto orig_pathlen = _M_pathname.length();
-  const auto orig_size = _M_cmpts.size();
-  const auto orig_type = _M_type();
-
-  int capacity = 0;
-  if (_M_type() == _Type::_Multi)
-    capacity += _M_cmpts.size();
-  else if (!empty())
-    capacity += 1;
-  if (__p._M_type() == _Type::_Multi)
-    capacity += __p._M_cmpts.size();
-  else if (!__p.empty() || !sep.empty())
-    capacity += 1;
-#if SLASHSLASH_IS_ROOTNAME
-  if (orig_type == _Type::_Root_name)
-    ++capacity; // Need to insert root-directory after root-name
-#endif
-
-  if (orig_type == _Type::_Multi)
-    {
-      const int curcap = _M_cmpts._M_impl->capacity();
-      if (capacity > curcap)
-       capacity = std::max(capacity, (int) (curcap * 1.5));
-    }
-
-  _M_pathname.reserve(_M_pathname.length() + sep.length()
-                     + __p._M_pathname.length());
-
-  __try
-    {
-      _M_pathname += sep;
-      const auto basepos = _M_pathname.length();
-      _M_pathname += __p.native();
-
-      _M_cmpts.type(_Type::_Multi);
-      _M_cmpts.reserve(capacity);
-      _Cmpt* output = _M_cmpts._M_impl->end();
-
-      if (orig_type == _Type::_Multi)
-       {
-         // Remove empty final component
-         if (_M_cmpts._M_impl->back().empty())
-           {
-             _M_cmpts.pop_back();
-             --output;
-           }
-       }
-      else if (orig_pathlen != 0)
-       {
-         // Create single component from original path
-         string_view_type s(_M_pathname.data(), orig_pathlen);
-         ::new(output++) _Cmpt(s, orig_type, 0);
-         ++_M_cmpts._M_impl->_M_size;
-#if SLASHSLASH_IS_ROOTNAME
-         if (orig_type == _Type::_Root_name)
-           {
-             ::new(output++) _Cmpt(sep, _Type::_Root_dir,
-                                   orig_pathlen + sep.length());
-             ++_M_cmpts._M_impl->_M_size;
-           }
-#endif
-       }
-
-      if (__p._M_type() == _Type::_Multi)
-       {
-         for (auto& c : *__p._M_cmpts._M_impl)
-           {
-             ::new(output++) _Cmpt(c._M_pathname, _Type::_Filename,
-                                   c._M_pos + basepos);
-             ++_M_cmpts._M_impl->_M_size;
-           }
-       }
-      else if (!__p.empty() || !sep.empty())
-       {
-         __glibcxx_assert(__p._M_type() == _Type::_Filename);
-         ::new(output) _Cmpt(__p._M_pathname, __p._M_type(), basepos);
-         ++_M_cmpts._M_impl->_M_size;
-       }
-    }
-  __catch (...)
-    {
-      _M_pathname.resize(orig_pathlen);
-      if (orig_type == _Type::_Multi)
-       _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
-      else
-       _M_cmpts.clear();
-      _M_cmpts.type(orig_type);
-      __throw_exception_again;
-    }
-#endif
-  return *this;
-}
-
-// [fs.path.append]
-void
-path::_M_append(basic_string_view<value_type> s)
-{
-  _Parser parser(s);
-  auto root_path = parser.root_path();
-
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  bool is_absolute = root_path.second.type == _Type::_Root_dir;
-  bool has_root_name = root_path.first.type == _Type::_Root_name;
-  if (is_absolute || (has_root_name && root_path.first.str != root_name()))
-    {
-      operator=(s);
-      return;
-    }
-
-  basic_string_view<value_type> lhs = _M_pathname;
-  bool add_sep = false;
-
-  bool has_root_directory = root_path.first.type == _Type::_Root_dir
-    || root_path.second.type == _Type::_Root_dir;
-
-  if (has_root_directory)
-    {
-      // Remove any root directory and relative path
-      if (_M_type() != _Type::_Root_name)
-       {
-         if (!_M_cmpts.empty()
-             && _M_cmpts.front()._M_type() == _Type::_Root_name)
-           lhs = _M_cmpts.front()._M_pathname;
-         else
-           lhs = {};
-       }
-    }
-  else if (has_filename() || (!has_root_directory && is_absolute))
-    add_sep = true;
-
-  basic_string_view<value_type> rhs = s;
-  // Omit any root-name from the generic format pathname:
-  if (has_root_name)
-    rhs.remove_prefix(root_path.first.str.length());
-
-  // Construct new path and swap (strong exception-safety guarantee).
-  string_type tmp;
-  tmp.reserve(lhs.size() + (int)add_sep + rhs.size());
-  tmp = lhs;
-  if (add_sep)
-    tmp += preferred_separator;
-  tmp += rhs;
-  path newp = std::move(tmp);
-  swap(newp);
-#else
-
-  bool is_absolute = root_path.first.type == _Type::_Root_dir
-    || root_path.second.type == _Type::_Root_dir;
-  if (is_absolute || this->empty())
-    {
-      operator=(s);
-      return;
-    }
-
-  const auto orig_pathlen = _M_pathname.length();
-  const auto orig_size = _M_cmpts.size();
-  const auto orig_type = _M_type();
-
-  basic_string_view<value_type> sep;
-  if (has_filename())
-    sep = { &preferred_separator, 1 };  // need to add a separator
-#if SLASHSLASH_IS_ROOTNAME
-  else if (_M_type() == _Type::_Root_name) // root-name with no root-dir
-    sep = { &preferred_separator, 1 };  // need to add a separator
-#endif
-  else if (s.empty())
-    return;                        // nothing to do
-
-  // Copy the input into _M_pathname:
-  _M_pathname += s;
-  _M_pathname.insert(orig_pathlen, sep);
-  // Update s to refer to the new copy (this ensures s is not a dangling
-  // reference to deallocated characters, in the case where it was referring
-  // into _M_pathname or a member of _M_cmpts).
-  s = _M_pathname;
-  const auto orig_pathname = s.substr(0, orig_pathlen);
-  s.remove_prefix(orig_pathlen + sep.length());
-
-  parser.input = s; // reset parser to use updated string view
-  const auto basepos = orig_pathname.length() + sep.length();
-  parser.origin = basepos;
-
-  std::array<_Parser::cmpt, 64> buf;
-  auto next = buf.begin();
-
-  int capacity = 0;
-  if (_M_type() == _Type::_Multi)
-    capacity += _M_cmpts.size();
-  else if (!empty())
-    capacity += 1;
-
-  auto cmpt = parser.next();
-  if (cmpt.valid())
-    {
-      do
-       {
-         *next++ = cmpt;
-         cmpt = parser.next();
-       }
-      while (cmpt.valid() && next != buf.end());
-
-      capacity += next - buf.begin();
-      if (cmpt.valid()) // filled buffer before parsing whole input
-       {
-         ++capacity;
-         _Parser parser2(parser);
-         while (parser2.next().valid())
-           ++capacity;
-       }
-    }
-  else if (!sep.empty())
-    ++capacity;
-
-#if SLASHSLASH_IS_ROOTNAME
-  if (orig_type == _Type::_Root_name)
-    ++capacity; // Need to insert root-directory after root-name
-#endif
-
-  __try
-    {
-      _M_cmpts.type(_Type::_Multi);
-      _M_cmpts.reserve(capacity);
-      _Cmpt* output = _M_cmpts._M_impl->end();
-
-      if (orig_type == _Type::_Multi)
-       {
-         // Remove empty final component
-         if (_M_cmpts._M_impl->back().empty())
-           {
-             _M_cmpts.pop_back();
-             --output;
-           }
-       }
-      else if (orig_pathlen != 0)
-       {
-         // Create single component from original path
-         ::new(output++) _Cmpt(orig_pathname, orig_type, 0);
-         ++_M_cmpts._M_impl->_M_size;
-
-#if SLASHSLASH_IS_ROOTNAME
-         if (!sep.empty() && orig_type == _Type::_Root_name)
-           {
-             ::new(output++) _Cmpt(sep, _Type::_Root_dir,
-                                   orig_pathlen + sep.length());
-             ++_M_cmpts._M_impl->_M_size;
-           }
-#endif
-       }
-
-      if (next != buf.begin())
-       {
-         for (auto it = buf.begin(); it != next; ++it)
-           {
-             auto c = *it;
-             ::new(output++) _Cmpt(c.str, c.type, parser.offset(c));
-             ++_M_cmpts._M_impl->_M_size;
-           }
-         while (cmpt.valid())
-           {
-             ::new(output++) _Cmpt(cmpt.str, cmpt.type, parser.offset(cmpt));
-             ++_M_cmpts._M_impl->_M_size;
-             cmpt = parser.next();
-           }
-       }
-      else if (!sep.empty())
-       {
-         // Empty filename at the end:
-         ::new(output) _Cmpt({}, _Type::_Filename, basepos);
-         ++_M_cmpts._M_impl->_M_size;
-       }
-    }
-  __catch (...)
-    {
-      _M_pathname.resize(orig_pathlen);
-      if (orig_type == _Type::_Multi)
-       _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
-      else
-       _M_cmpts.clear();
-      _M_cmpts.type(orig_type);
-      __throw_exception_again;
-    }
-#endif
-}
-
-// [fs.path.concat]
-path&
-path::operator+=(const path& p)
-{
-  if (p.empty())
-    return *this;
-
-  if (this->empty())
-    {
-      operator=(p);
-      return *this;
-    }
-
-  const auto orig_pathlen = _M_pathname.length();
-  const auto orig_type = _M_type();
-  const auto orig_size = _M_cmpts.size();
-  int orig_filenamelen = -1;
-  basic_string_view<value_type> extra;
-
-  // Ensure that '_M_pathname += p._M_pathname' won't throw:
-  _M_pathname.reserve(orig_pathlen + p._M_pathname.length());
-
-  _Cmpt c;
-  _Cmpt* it = nullptr;
-  _Cmpt* last = nullptr;
-  if (p._M_type() == _Type::_Multi)
-    {
-      it = p._M_cmpts._M_impl->begin();
-      last = p._M_cmpts._M_impl->end();
-    }
-  else
-    {
-      c = _Cmpt(p._M_pathname, p._M_type(), 0);
-      it = &c;
-      last = it + 1;
-    }
-
-  if (it->_M_type() == _Type::_Filename)
-    {
-      // See if there's a filename or root-name at the end of the original path
-      // that we can add to.
-      if (_M_type() == _Type::_Filename
-#if SLASHSLASH_IS_ROOTNAME
-         || _M_type() == _Type::_Root_name
-#endif
-         )
-       {
-         if (p._M_type() == _Type::_Filename)
-           {
-             // Simplest case where we just add the whole of p to the
-             // original path.
-             _M_pathname += p._M_pathname;
-             return *this;
-           }
-         // Only the first component of s should be appended, do so below:
-         extra = it->_M_pathname;
-         ++it;
-       }
-      else if (_M_type() == _Type::_Multi
-         && _M_cmpts.back()._M_type() == _Type::_Filename)
-       {
-         auto& back = _M_cmpts.back();
-         if (p._M_type() == _Type::_Filename)
-           {
-             basic_string_view<value_type> s = p._M_pathname;
-             back._M_pathname += s;
-             _M_pathname += s;
-             return *this;
-           }
-
-         orig_filenamelen = back._M_pathname.length();
-         back._M_pathname += it->_M_pathname;
-         extra = it->_M_pathname;
-         ++it;
-       }
-    }
-  else if (is_dir_sep(_M_pathname.back()) && _M_type() == _Type::_Multi
-      && _M_cmpts.back()._M_type() == _Type::_Filename)
-    orig_filenamelen = 0; // current path has empty filename at end
-
-  int capacity = 0;
-  if (_M_type() == _Type::_Multi)
-    capacity += _M_cmpts.size();
-  else
-    capacity += 1;
-  if (p._M_type() == _Type::_Multi)
-    capacity += p._M_cmpts.size();
-  else
-    capacity += 1;
-
-  __try
-    {
-      _M_cmpts.type(_Type::_Multi);
-      _M_cmpts.reserve(capacity);
-      _Cmpt* output = _M_cmpts._M_impl->end();
-
-      if (orig_type != _Type::_Multi)
-       {
-         // Create single component from original path
-         auto ptr = ::new(output++) _Cmpt({}, orig_type, 0);
-         ++_M_cmpts._M_impl->_M_size;
-         ptr->_M_pathname.reserve(_M_pathname.length() + extra.length());
-         ptr->_M_pathname = _M_pathname;
-         ptr->_M_pathname += extra;
-
-#if SLASHSLASH_IS_ROOTNAME
-         if (orig_type == _Type::_Root_name)
-           {
-             basic_string_view<value_type> s(p._M_pathname);
-             ::new(output++) _Cmpt(s.substr(extra.length(), 1),
-                 _Type::_Root_dir, orig_pathlen + extra.length());
-             ++_M_cmpts._M_impl->_M_size;
-           }
-#endif
-       }
-      else if (orig_filenamelen == 0 && it != last)
-       {
-         // Remove empty filename at end of original path.
-         _M_cmpts.pop_back();
-         --output;
-       }
-
-      if (it != last && it->_M_type() == _Type::_Root_name)
-       {
-         basic_string_view<value_type> s = it->_M_pathname;
-         auto pos = orig_pathlen;
-#if SLASHSLASH_IS_ROOTNAME
-         s.remove_prefix(2);
-         pos += 2;
-#endif
-         ::new(output++) _Cmpt(s, _Type::_Filename, pos);
-         ++_M_cmpts._M_impl->_M_size;
-         ++it;
-       }
-
-      if (it != last && it->_M_type() == _Type::_Root_dir)
-       {
-         ++it;
-         if (it == last)
-           {
-             // This root-dir becomes a trailing slash
-             auto pos = _M_pathname.length() + p._M_pathname.length();
-             ::new(output++) _Cmpt({}, _Type::_Filename, pos);
-             ++_M_cmpts._M_impl->_M_size;
-           }
-       }
-
-      while (it != last)
-       {
-         auto pos = it->_M_pos + orig_pathlen;
-         ::new(output++) _Cmpt(it->_M_pathname, _Type::_Filename, pos);
-         ++_M_cmpts._M_impl->_M_size;
-         ++it;
-       }
-
-      _M_pathname += p._M_pathname;
-
-      if (is_dir_sep(_M_pathname.back()))
-       {
-         ::new(output++) _Cmpt({}, _Type::_Filename, _M_pathname.length());
-         ++_M_cmpts._M_impl->_M_size;
-       }
-      }
-  __catch (...)
-    {
-      _M_pathname.resize(orig_pathlen);
-      if (orig_type == _Type::_Multi)
-       {
-         if (_M_cmpts.size() > orig_size)
-           _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
-         if (orig_filenamelen != -1)
-           {
-             if (_M_cmpts.size() == orig_size)
-               {
-                 auto& back = _M_cmpts.back();
-                 back._M_pathname.resize(orig_filenamelen);
-                 if (orig_filenamelen == 0)
-                   back._M_pos = orig_pathlen;
-               }
-             else
-               {
-                 auto output = _M_cmpts._M_impl->end();
-                 ::new(output) _Cmpt({}, _Type::_Filename, orig_pathlen);
-                 ++_M_cmpts._M_impl->_M_size;
-               }
-           }
-       }
-      else
-       _M_cmpts.clear();
-      _M_cmpts.type(orig_type);
-      __throw_exception_again;
-    }
-  return *this;
-}
-
-// [fs.path.concat]
-void
-path::_M_concat(basic_string_view<value_type> s)
-{
-  if (s.empty())
-    return;
-
-  if (this->empty())
-    {
-      operator=(s);
-      return;
-    }
-
-  const auto orig_pathlen = _M_pathname.length();
-  const auto orig_type = _M_type();
-  const auto orig_size = _M_cmpts.size();
-  int orig_filenamelen = -1;
-  basic_string_view<value_type> extra;
-
-  // Copy the input into _M_pathname:
-  _M_pathname += s;
-  // Update s to refer to the new copy (this ensures s is not a dangling
-  // reference to deallocated characters, in the case where it was referring
-  // into _M_pathname or a member of _M_cmpts).
-  s = _M_pathname;
-  const auto orig_pathname = s.substr(0, orig_pathlen);
-  s.remove_prefix(orig_pathlen);
-
-  _Parser parser(s, orig_pathlen);
-  auto cmpt = parser.next();
-
-  if (cmpt.str.data() == s.data())
-    {
-      // See if there's a filename or root-name at the end of the original path
-      // that we can add to.
-      if (_M_type() == _Type::_Filename
-#if SLASHSLASH_IS_ROOTNAME
-         || _M_type() == _Type::_Root_name
-#endif
-         )
-       {
-         if (cmpt.str.length() == s.length())
-           {
-             // Simplest case where we just need to add the whole of s
-             // to the original path, which was already done above.
-             return;
-           }
-         // Only the first component of s should be appended, do so below:
-         extra = cmpt.str;
-         cmpt = {}; // so we don't process it again
-       }
-      else if (_M_type() == _Type::_Multi
-         && _M_cmpts.back()._M_type() == _Type::_Filename)
-       {
-         auto& back = _M_cmpts.back();
-         if (cmpt.str.length() == s.length())
-           {
-             back._M_pathname += s;
-             return;
-           }
-
-         orig_filenamelen = back._M_pathname.length();
-         back._M_pathname += cmpt.str;
-         extra = cmpt.str;
-         cmpt = {};
-       }
-    }
-  else if (is_dir_sep(orig_pathname.back()) && _M_type() == _Type::_Multi
-      && _M_cmpts.back()._M_type() == _Type::_Filename)
-    orig_filenamelen = 0; // original path had empty filename at end
-
-  std::array<_Parser::cmpt, 64> buf;
-  auto next = buf.begin();
-
-  if (cmpt.valid())
-    *next++ = cmpt;
-
-  cmpt = parser.next();
-  while (cmpt.valid() && next != buf.end())
-    {
-      *next++ = cmpt;
-      cmpt = parser.next();
-    }
-
-  int capacity = 0;
-  if (_M_type() == _Type::_Multi)
-    capacity += _M_cmpts.size();
-  else
-    capacity += 1;
-
-  capacity += next - buf.begin();
-
-  if (cmpt.valid()) // filled buffer before parsing whole input
-    {
-      ++capacity;
-      _Parser parser2(parser);
-      while (parser2.next().valid())
-       ++capacity;
-    }
-
-#if SLASHSLASH_IS_ROOTNAME
-  if (orig_type == _Type::_Root_name)
-    ++capacity; // Need to insert root-directory after root-name
-#endif
-
-  __try
-    {
-      _M_cmpts.type(_Type::_Multi);
-      _M_cmpts.reserve(capacity);
-      _Cmpt* output = _M_cmpts._M_impl->end();
-      auto it = buf.begin();
-
-      if (orig_type != _Type::_Multi)
-       {
-         // Create single component from original path
-         auto p = ::new(output++) _Cmpt({}, orig_type, 0);
-         ++_M_cmpts._M_impl->_M_size;
-         p->_M_pathname.reserve(orig_pathname.length() + extra.length());
-         p->_M_pathname = orig_pathname;
-         p->_M_pathname += extra;
-
-#if SLASHSLASH_IS_ROOTNAME
-         if (orig_type == _Type::_Root_name)
-           {
-             ::new(output++) _Cmpt(s.substr(extra.length(), 1),
-                 _Type::_Root_dir, orig_pathlen + extra.length());
-             ++_M_cmpts._M_impl->_M_size;
-           }
-#endif
-       }
-      else if (orig_filenamelen == 0 && extra.empty())
-       {
-         // Replace empty filename at end of original path.
-         std::prev(output)->_M_pathname = it->str;
-         std::prev(output)->_M_pos = parser.offset(*it);
-         ++it;
-       }
-
-      while (it != next)
-       {
-         ::new(output++) _Cmpt(it->str, _Type::_Filename, parser.offset(*it));
-         ++_M_cmpts._M_impl->_M_size;
-         ++it;
-       }
-
-      if (next == buf.end())
-       {
-         while (cmpt.valid())
-           {
-             auto pos = parser.offset(cmpt);
-             ::new(output++) _Cmpt(cmpt.str, _Type::_Filename, pos);
-             ++_M_cmpts._M_impl->_M_size;
-             cmpt = parser.next();
-           }
-       }
-    }
-  __catch (...)
-    {
-      _M_pathname.resize(orig_pathlen);
-      if (orig_type == _Type::_Multi)
-       {
-         _M_cmpts._M_erase_from(_M_cmpts.begin() + orig_size);
-         if (orig_filenamelen != -1)
-           {
-             auto& back = _M_cmpts.back();
-             back._M_pathname.resize(orig_filenamelen);
-             if (orig_filenamelen == 0)
-               back._M_pos = orig_pathlen;
-           }
-       }
-      else
-       _M_cmpts.clear();
-      _M_cmpts.type(orig_type);
-      __throw_exception_again;
-    }
-}
-
-path&
-path::remove_filename()
-{
-  if (_M_type() == _Type::_Multi)
-    {
-      if (!_M_cmpts.empty())
-       {
-         auto cmpt = std::prev(_M_cmpts.end());
-         if (cmpt->_M_type() == _Type::_Filename && !cmpt->empty())
-           {
-             _M_pathname.erase(cmpt->_M_pos);
-             auto prev = std::prev(cmpt);
-             if (prev->_M_type() == _Type::_Root_dir
-                 || prev->_M_type() == _Type::_Root_name)
-               {
-                 _M_cmpts.pop_back();
-                 if (_M_cmpts.size() == 1)
-                   {
-                     _M_cmpts.type(_M_cmpts.front()._M_type());
-                     _M_cmpts.clear();
-                   }
-               }
-             else
-               cmpt->clear();
-           }
-       }
-    }
-  else if (_M_type() == _Type::_Filename)
-    clear();
-  return *this;
-}
-
-path&
-path::replace_filename(const path& replacement)
-{
-  remove_filename();
-  operator/=(replacement);
-  return *this;
-}
-
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-const fs::path::value_type dot = L'.';
-#else
-const fs::path::value_type dot = '.';
-#endif
-
-path&
-path::replace_extension(const path& replacement)
-{
-  auto ext = _M_find_extension();
-  // Any existing extension() is removed
-  if (ext.first && ext.second != string_type::npos)
-    {
-      if (ext.first == &_M_pathname)
-       _M_pathname.erase(ext.second);
-      else
-       {
-         const auto& back = _M_cmpts.back();
-         if (ext.first != &back._M_pathname)
-           _GLIBCXX_THROW_OR_ABORT(
-               std::logic_error("path::replace_extension failed"));
-         _M_pathname.erase(back._M_pos + ext.second);
-       }
-    }
-   // If replacement is not empty and does not begin with a dot character,
-   // a dot character is appended
-  if (!replacement.empty() && replacement.native()[0] != dot)
-    _M_pathname += dot;
-  operator+=(replacement);
-  return *this;
-}
-
-int
-path::compare(const path& p) const noexcept
-{
-  if (_M_pathname == p._M_pathname)
-    return 0;
-
-  basic_string_view<value_type> lroot, rroot;
-  if (_M_type() == _Type::_Root_name)
-    lroot = _M_pathname;
-  else if (_M_type() == _Type::_Multi
-      && _M_cmpts.front()._M_type() == _Type::_Root_name)
-    lroot = _M_cmpts.front()._M_pathname;
-  if (p._M_type() == _Type::_Root_name)
-    rroot = p._M_pathname;
-  else if (p._M_type() == _Type::_Multi
-      && p._M_cmpts.front()._M_type() == _Type::_Root_name)
-    rroot = p._M_cmpts.front()._M_pathname;
-  if (int rootNameComparison = lroot.compare(rroot))
-    return rootNameComparison;
-
-  if (!this->has_root_directory() && p.has_root_directory())
-    return -1;
-  else if (this->has_root_directory() && !p.has_root_directory())
-    return +1;
-
-  using Iterator = const _Cmpt*;
-  Iterator begin1, end1, begin2, end2;
-  if (_M_type() == _Type::_Multi)
-    {
-      begin1 = _M_cmpts.begin();
-      end1 = _M_cmpts.end();
-      // Find start of this->relative_path()
-      while (begin1 != end1 && begin1->_M_type() != _Type::_Filename)
-       ++begin1;
-    }
-  else
-    begin1 = end1 = nullptr;
-
-  if (p._M_type() == _Type::_Multi)
-    {
-      begin2 = p._M_cmpts.begin();
-      end2 = p._M_cmpts.end();
-      // Find start of p.relative_path()
-      while (begin2 != end2 && begin2->_M_type() != _Type::_Filename)
-       ++begin2;
-    }
-  else
-    begin2 = end2 = nullptr;
-
-  if (_M_type() == _Type::_Filename)
-    {
-      if (p._M_type() == _Type::_Filename)
-       return native().compare(p.native());
-      else if (begin2 != end2)
-       {
-         if (int ret = native().compare(begin2->native()))
-           return ret;
-         else
-           return ++begin2 == end2 ? 0 : -1;
-       }
-      else
-       return +1;
-    }
-  else if (p._M_type() == _Type::_Filename)
-    {
-      if (begin1 != end1)
-       {
-         if (int ret = begin1->native().compare(p.native()))
-           return ret;
-         else
-           return ++begin1 == end1 ? 0 : +1;
-       }
-      else
-       return -1;
-    }
-
-  int count = 1;
-  while (begin1 != end1 && begin2 != end2)
-    {
-      if (int i = begin1->native().compare(begin2->native()))
-       return i;
-      ++begin1;
-      ++begin2;
-      ++count;
-    }
-  if (begin1 == end1)
-    {
-      if (begin2 == end2)
-       return 0;
-      return -count;
-    }
-  return count;
-}
-
-int
-path::compare(basic_string_view<value_type> s) const noexcept
-{
-  if (_M_pathname == s)
-    return 0;
-
-  _Parser parser(s);
-
-  basic_string_view<value_type> lroot, rroot;
-  if (_M_type() == _Type::_Root_name)
-    lroot = _M_pathname;
-  else if (_M_type() == _Type::_Multi
-      && _M_cmpts.front()._M_type() == _Type::_Root_name)
-    lroot = _M_cmpts.front()._M_pathname;
-  auto root_path = parser.root_path();
-  if (root_path.first.type == _Type::_Root_name)
-    rroot = root_path.first.str;
-  if (int rootNameComparison = lroot.compare(rroot))
-    return rootNameComparison;
-
-  const bool has_root_dir = root_path.first.type == _Type::_Root_dir
-    || root_path.second.type == _Type::_Root_dir;
-  if (!this->has_root_directory() && has_root_dir)
-    return -1;
-  else if (this->has_root_directory() && !has_root_dir)
-    return +1;
-
-  using Iterator = const _Cmpt*;
-  Iterator begin1, end1;
-  if (_M_type() == _Type::_Filename)
-    {
-      auto cmpt = parser.next();
-      if (cmpt.valid())
-       {
-         if (int ret = this->native().compare(cmpt.str))
-           return ret;
-         return parser.next().valid() ? -1 : 0;
-       }
-      else
-       return +1;
-    }
-  else if (_M_type() == _Type::_Multi)
-    {
-      begin1 = _M_cmpts.begin();
-      end1 = _M_cmpts.end();
-      while (begin1 != end1 && begin1->_M_type() != _Type::_Filename)
-       ++begin1;
-    }
-  else
-    begin1 = end1 = nullptr;
-
-  int count = 1;
-  auto cmpt = parser.next();
-  while (begin1 != end1 && cmpt.valid())
-    {
-      if (int i = begin1->native().compare(cmpt.str))
-       return i;
-      ++begin1;
-      cmpt = parser.next();
-      ++count;
-    }
-  if (begin1 == end1)
-    {
-      if (!cmpt.valid())
-       return 0;
-      return -count;
-    }
-  return +count;
-}
-
-path
-path::root_name() const
-{
-  path __ret;
-  if (_M_type() == _Type::_Root_name)
-    __ret = *this;
-  else if (_M_cmpts.size() && _M_cmpts.begin()->_M_type() == _Type::_Root_name)
-    __ret = *_M_cmpts.begin();
-  return __ret;
-}
-
-path
-path::root_directory() const
-{
-  path __ret;
-  if (_M_type() == _Type::_Root_dir)
-    {
-      __ret._M_cmpts.type(_Type::_Root_dir);
-      __ret._M_pathname.assign(1, preferred_separator);
-    }
-  else if (!_M_cmpts.empty())
-    {
-      auto __it = _M_cmpts.begin();
-      if (__it->_M_type() == _Type::_Root_name)
-        ++__it;
-      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
-        __ret = *__it;
-    }
-  return __ret;
-}
-
-path
-path::root_path() const
-{
-  path __ret;
-  if (_M_type() == _Type::_Root_name)
-    __ret = *this;
-  else if (_M_type() == _Type::_Root_dir)
-    {
-      __ret._M_pathname.assign(1, preferred_separator);
-      __ret._M_cmpts.type(_Type::_Root_dir);
-    }
-  else if (!_M_cmpts.empty())
-    {
-      auto __it = _M_cmpts.begin();
-      if (__it->_M_type() == _Type::_Root_name)
-        {
-          __ret = *__it++;
-          if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
-           __ret /= *__it;
-        }
-      else if (__it->_M_type() == _Type::_Root_dir)
-        __ret = *__it;
-    }
-  return __ret;
-}
-
-path
-path::relative_path() const
-{
-  path __ret;
-  if (_M_type() == _Type::_Filename)
-    __ret = *this;
-  else if (!_M_cmpts.empty())
-    {
-      auto __it = _M_cmpts.begin();
-      if (__it->_M_type() == _Type::_Root_name)
-        ++__it;
-      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
-        ++__it;
-      if (__it != _M_cmpts.end())
-        __ret.assign(_M_pathname.substr(__it->_M_pos));
-    }
-  return __ret;
-}
-
-path
-path::parent_path() const
-{
-  path __ret;
-  if (!has_relative_path())
-    __ret = *this;
-  else if (_M_cmpts.size() >= 2)
-    {
-      for (auto __it = _M_cmpts.begin(), __end = std::prev(_M_cmpts.end());
-          __it != __end; ++__it)
-       {
-         __ret /= *__it;
-       }
-    }
-  return __ret;
-}
-
-bool
-path::has_root_name() const
-{
-  if (_M_type() == _Type::_Root_name)
-    return true;
-  if (!_M_cmpts.empty() && _M_cmpts.begin()->_M_type() == _Type::_Root_name)
-    return true;
-  return false;
-}
-
-bool
-path::has_root_directory() const
-{
-  if (_M_type() == _Type::_Root_dir)
-    return true;
-  if (!_M_cmpts.empty())
-    {
-      auto __it = _M_cmpts.begin();
-      if (__it->_M_type() == _Type::_Root_name)
-        ++__it;
-      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
-        return true;
-    }
-  return false;
-}
-
-bool
-path::has_root_path() const
-{
-  if (_M_type() == _Type::_Root_name || _M_type() == _Type::_Root_dir)
-    return true;
-  if (!_M_cmpts.empty())
-    {
-      auto __type = _M_cmpts.front()._M_type();
-      if (__type == _Type::_Root_name || __type == _Type::_Root_dir)
-        return true;
-    }
-  return false;
-}
-
-bool
-path::has_relative_path() const
-{
-  if (_M_type() == _Type::_Filename && !_M_pathname.empty())
-    return true;
-  if (!_M_cmpts.empty())
-    {
-      auto __it = _M_cmpts.begin();
-      if (__it->_M_type() == _Type::_Root_name)
-        ++__it;
-      if (__it != _M_cmpts.end() && __it->_M_type() == _Type::_Root_dir)
-        ++__it;
-      if (__it != _M_cmpts.end() && !__it->_M_pathname.empty())
-        return true;
-    }
-  return false;
-}
-
-
-bool
-path::has_parent_path() const
-{
-  if (!has_relative_path())
-    return !empty();
-  return _M_cmpts.size() >= 2;
-}
-
-bool
-path::has_filename() const
-{
-  if (empty())
-    return false;
-  if (_M_type() == _Type::_Filename)
-    return !_M_pathname.empty();
-  if (_M_type() == _Type::_Multi)
-    {
-      if (_M_pathname.back() == preferred_separator)
-       return false;
-      return _M_cmpts.back().has_filename();
-    }
-  return false;
-}
-
-namespace
-{
-  inline bool is_dot(fs::path::value_type c) { return c == dot; }
-
-  inline bool is_dot(const fs::path& path)
-  {
-    const auto& filename = path.native();
-    return filename.size() == 1 && is_dot(filename[0]);
-  }
-
-  inline bool is_dotdot(const fs::path& path)
-  {
-    const auto& filename = path.native();
-    return filename.size() == 2 && is_dot(filename[0]) && is_dot(filename[1]);
-  }
-} // namespace
-
-path
-path::lexically_normal() const
-{
-  /*
-  C++17 [fs.path.generic] p6
-  - If the path is empty, stop.
-  - Replace each slash character in the root-name with a preferred-separator.
-  - Replace each directory-separator with a preferred-separator.
-  - Remove each dot filename and any immediately following directory-separator.
-  - As long as any appear, remove a non-dot-dot filename immediately followed
-    by a directory-separator and a dot-dot filename, along with any immediately
-    following directory-separator.
-  - If there is a root-directory, remove all dot-dot filenames and any
-    directory-separators immediately following them.
-  - If the last filename is dot-dot, remove any trailing directory-separator.
-  - If the path is empty, add a dot.
-  */
-  path ret;
-  // If the path is empty, stop.
-  if (empty())
-    return ret;
-  for (auto& p : *this)
-    {
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-      // Replace each slash character in the root-name
-      if (p._M_type() == _Type::_Root_name || p._M_type() == _Type::_Root_dir)
-       {
-         string_type s = p.native();
-         std::replace(s.begin(), s.end(), L'/', L'\\');
-         ret /= s;
-         continue;
-       }
-#endif
-      if (is_dotdot(p))
-       {
-         if (ret.has_filename())
-           {
-             // remove a non-dot-dot filename immediately followed by /..
-             if (!is_dotdot(ret.filename()))
-               ret.remove_filename();
-             else
-               ret /= p;
-           }
-         else if (!ret.has_relative_path())
-           {
-             // remove a dot-dot filename immediately after root-directory
-             if (!ret.has_root_directory())
-               ret /= p;
-           }
-         else
-           {
-             // Got a path with a relative path (i.e. at least one non-root
-             // element) and no filename at the end (i.e. empty last element),
-             // so must have a trailing slash. See what is before it.
-             auto elem = ret._M_cmpts.end() - 2;
-             if (elem->has_filename() && !is_dotdot(*elem))
-               {
-                 // Remove the filename before the trailing slash
-                 // (equiv. to ret = ret.parent_path().remove_filename())
-
-                 if (elem == ret._M_cmpts.begin())
-                   ret.clear();
-                 else
-                   {
-                     ret._M_pathname.erase(elem->_M_pos);
-                     // Remove empty filename at the end:
-                     ret._M_cmpts.pop_back();
-                     // If we still have a trailing non-root dir separator
-                     // then leave an empty filename at the end:
-                     if (std::prev(elem)->_M_type() == _Type::_Filename)
-                       elem->clear();
-                     else // remove the component completely:
-                       ret._M_cmpts.pop_back();
-                   }
-               }
-             else
-               // Append the ".." to something ending in "../" which happens
-               // when normalising paths like ".././.." and "../a/../.."
-               ret /= p;
-           }
-       }
-      else if (is_dot(p))
-       ret /= path();
-#if SLASHSLASH_IS_ROOTNAME
-      else if (p._M_type() == _Type::_Root_dir)
-       ret += '/'; // using operator/=('/') would replace whole of ret
-#endif
-      else
-       ret /= p;
-    }
-
-  if (ret._M_cmpts.size() >= 2)
-    {
-      auto back = std::prev(ret.end());
-      // If the last filename is dot-dot, ...
-      if (back->empty() && is_dotdot(*std::prev(back)))
-       // ... remove any trailing directory-separator.
-       ret = ret.parent_path();
-    }
-  // If the path is empty, add a dot.
-  else if (ret.empty())
-    ret = ".";
-
-  return ret;
-}
-
-path
-path::lexically_relative(const path& base) const
-{
-  path ret;
-  if (root_name() != base.root_name())
-    return ret;
-  if (is_absolute() != base.is_absolute())
-    return ret;
-  if (!has_root_directory() && base.has_root_directory())
-    return ret;
-  auto [a, b] = std::mismatch(begin(), end(), base.begin(), base.end());
-  if (a == end() && b == base.end())
-    ret = ".";
-  else
-  {
-    int n = 0;
-    for (; b != base.end(); ++b)
-    {
-      const path& p = *b;
-      if (is_dotdot(p))
-       --n;
-      else if (!p.empty() && !is_dot(p))
-       ++n;
-    }
-    if (n == 0 && (a == end() || a->empty()))
-      ret = ".";
-    else if (n >= 0)
-    {
-      const path dotdot("..");
-      while (n--)
-       ret /= dotdot;
-      for (; a != end(); ++a)
-       ret /= *a;
-    }
-  }
-  return ret;
-}
-
-path
-path::lexically_proximate(const path& base) const
-{
-  path rel = lexically_relative(base);
-  if (rel.empty())
-    rel = *this;
-  return rel;
-}
-
-std::pair<const path::string_type*, std::size_t>
-path::_M_find_extension() const
-{
-  const string_type* s = nullptr;
-
-  if (_M_type() == _Type::_Filename)
-    s = &_M_pathname;
-  else if (_M_type() == _Type::_Multi && !_M_cmpts.empty())
-    {
-      const auto& c = _M_cmpts.back();
-      if (c._M_type() == _Type::_Filename)
-       s = &c._M_pathname;
-    }
-
-  if (s)
-    {
-      if (auto sz = s->size())
-       {
-         if (sz <= 2 && (*s)[0] == dot)
-           return { s, string_type::npos };
-         const auto pos = s->rfind(dot);
-         return { s, pos ? pos : string_type::npos };
-       }
-    }
-  return {};
-}
-
-void
-path::_M_split_cmpts()
-{
-  _M_cmpts.clear();
-
-  if (_M_pathname.empty())
-    {
-      _M_cmpts.type(_Type::_Filename);
-      return;
-    }
-  if (_M_pathname.length() == 1 && _M_pathname[0] == preferred_separator)
-    {
-      _M_cmpts.type(_Type::_Root_dir);
-      return;
-    }
-
-  _Parser parser(_M_pathname);
-
-  std::array<_Parser::cmpt, 64> buf;
-  auto next = buf.begin();
-
-  // look for root name or root directory
-  auto root_path = parser.root_path();
-  if (root_path.first.valid())
-    {
-      *next++ = root_path.first;
-      if (root_path.second.valid())
-       *next++ = root_path.second;
-    }
-
-  auto cmpt = parser.next();
-  while (cmpt.valid())
-    {
-      do
-       {
-         *next++ = cmpt;
-         cmpt = parser.next();
-       }
-      while (cmpt.valid() && next != buf.end());
-
-      if (next == buf.end())
-       {
-         _M_cmpts.type(_Type::_Multi);
-         _M_cmpts.reserve(_M_cmpts.size() + buf.size());
-         auto output = _M_cmpts._M_impl->end();
-         for (auto& c : buf)
-           {
-             auto pos = c.str.data() - _M_pathname.data();
-             ::new(output++) _Cmpt(c.str, c.type, pos);
-             ++_M_cmpts._M_impl->_M_size;
-           }
-         next = buf.begin();
-       }
-    }
-
-  if (auto n = next - buf.begin())
-    {
-      if (n == 1 && _M_cmpts.empty())
-       {
-         _M_cmpts.type(buf.front().type);
-         return;
-       }
-
-      _M_cmpts.type(_Type::_Multi);
-      _M_cmpts.reserve(_M_cmpts.size() + n, true);
-      auto output = _M_cmpts._M_impl->end();
-      for (int i = 0; i < n; ++i)
-       {
-         auto c = buf[i];
-         auto pos = c.str.data() - _M_pathname.data();
-         ::new(output++) _Cmpt(c.str, c.type, pos);
-         ++_M_cmpts._M_impl->_M_size;
-       }
-    }
-}
-
-path::string_type
-path::_S_convert_loc(const char* __first, const char* __last,
-                    const std::locale& __loc)
-{
-#if _GLIBCXX_USE_WCHAR_T
-  auto& __cvt = std::use_facet<codecvt<wchar_t, char, mbstate_t>>(__loc);
-  basic_string<wchar_t> __ws;
-  if (!__str_codecvt_in(__first, __last, __ws, __cvt))
-    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-         "Cannot convert character sequence",
-         std::make_error_code(errc::illegal_byte_sequence)));
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  return __ws;
-#else
-  return _Cvt<wchar_t>::_S_convert(__ws.data(), __ws.data() + __ws.size());
-#endif
-#else
-  return {__first, __last};
-#endif
-}
-
-std::size_t
-fs::hash_value(const path& p) noexcept
-{
-  // [path.non-member]
-  // "If for two paths, p1 == p2 then hash_value(p1) == hash_value(p2)."
-  // Equality works as if by traversing the range [begin(), end()), meaning
-  // e.g. path("a//b") == path("a/b"), so we cannot simply hash _M_pathname
-  // but need to iterate over individual elements. Use the hash_combine from
-  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3876.pdf
-  size_t seed = 0;
-  for (const auto& x : p)
-    {
-      seed ^= std::hash<path::string_type>()(x.native()) + 0x9e3779b9
-       + (seed<<6) + (seed>>2);
-    }
-  return seed;
-}
-
-struct fs::filesystem_error::_Impl
-{
-  _Impl(const string& what_arg, const path& p1, const path& p2)
-  : path1(p1), path2(p2), what(make_what(what_arg, &p1, &p2))
-  { }
-
-  _Impl(const string& what_arg, const path& p1)
-  : path1(p1), path2(), what(make_what(what_arg, &p1, nullptr))
-  { }
-
-  _Impl(const string& what_arg)
-  : what(make_what(what_arg, nullptr, nullptr))
-  { }
-
-  static std::string
-  make_what(const std::string& s, const path* p1, const path* p2)
-  {
-    const std::string pstr1 = p1 ? p1->u8string() : std::string{};
-    const std::string pstr2 = p2 ? p2->u8string() : std::string{};
-    const size_t len = 18 + s.length()
-      + (pstr1.length() ? pstr1.length() + 3 : 0)
-      + (pstr2.length() ? pstr2.length() + 3 : 0);
-    std::string w;
-    w.reserve(len);
-    w = "filesystem error: ";
-    w += s;
-    if (p1)
-      {
-       w += " [";
-       w += pstr1;
-       w += ']';
-       if (p2)
-         {
-           w += " [";
-           w += pstr2;
-           w += ']';
-         }
-      }
-    return w;
-  }
-
-  path path1;
-  path path2;
-  std::string what;
-};
-
-template class std::__shared_ptr<const fs::filesystem_error::_Impl>;
-
-fs::filesystem_error::
-filesystem_error(const string& what_arg, error_code ec)
-: system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg))
-{ }
-
-fs::filesystem_error::
-filesystem_error(const string& what_arg, const path& p1, error_code ec)
-: system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg, p1))
-{ }
-
-fs::filesystem_error::
-filesystem_error(const string& what_arg, const path& p1, const path& p2,
-                error_code ec)
-: system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg, p1, p2))
-{ }
-
-fs::filesystem_error::~filesystem_error() = default;
-
-const fs::path&
-fs::filesystem_error::path1() const noexcept
-{ return _M_impl->path1; }
-
-const fs::path&
-fs::filesystem_error::path2() const noexcept
-{ return _M_impl->path2; }
-
-const char*
-fs::filesystem_error::what() const noexcept
-{ return _M_impl->what.c_str(); }
index 3375b06518141e9c2cfc9a91162b46ed3b27534c..93c0f15f5ea148e2cdf834dd4ebbc014948fffaa 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index a73766ce307ff1dfeab0978e07d7c602de9b0390..db80087ba6c768892118110c675b34fd3e5f48fa 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2018-2019 Free Software Foundation, Inc.
 //
index b93543c41dfe517669fc5f5db91ebc1620f65af3..13828fe9550264c9f24f9898206735c67180a5a5 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index e182d1ae21ad0deaed62c6a45df583914db6ff00..6c24e3ae7b9425c0876cd077359ccc87a1396687 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index b24527312e00fb0b2ae3f02fc0c88acf1ff2f017..7ce16f4d1909d1f7640580ad1481bbb4af4e455f 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index e45f9366c8eb1bd51bc1c2b78f43141a0a995b0c..bcb99cc6ddc00801ae46487a991c95753592ac6b 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index b46ff703bcb703a3a0cee4c53c1f6689eed27f9c..4de5a789994a6cc1ad9bbe261f28047245d7f718 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index f12b68fb0191e6da5912721c5db2b28e30ce6ff7..3f0aa4bde0693459d8a95897e0ceead74d405693 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index e2a14bd8fccd669df6681952ef7e7087f585f34c..9f534e64cb7ccde35eee2c753e1f22ca8217a3a9 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 21e2ecdfcafbc0044e055c5a14b094ef2e569a26..80ce25ef119a26cf03530b0bee438d83d556803d 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 5bf8298a818365830e68ea144f52fea8b739a9e8..71cdaa9d969236156a237f237742f3d0caeacba8 100644 (file)
@@ -17,7 +17,6 @@
 
 // { dg-options "-std=gnu++17" }
 // { dg-do compile { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 
index 5bab635eb1a061649592ef2124a8ada1a8f316a4..b29ab34332e18a6d98e11076f45cbbb36925a855 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 2280e7de64aad51c5bce673a0f3bd3c711cc703f..1e49c681a34641d321aca05e563dbb13c117f7ac 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index b97305b2aa6551a4bfe1dba336c9352da4de473d..f80d986049603d960f933bee81d35c2f57b6c9f5 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <string.h>
index 12b437c37b08cf154eaf2cd691fb98cabdf64025..bfb8aa136ea13cf92129be83e2c4c151cc671867 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 6b447980129c84bafabfe6b1a6fe5af78e55c4c6..f7a40364b8ab62c2099f58b045c944f6b2814283 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 42340e6eb756777016dad466afb502dc8a360fa9..343928edde6fa60c6e32c870b6bbec8bbbd81e60 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-lstdc++fs -std=gnu++17" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2016-2019 Free Software Foundation, Inc.
 //
index d3f8d7e3c54f4860486df36b1ffcbe4548507eab..a4d48c96edaa3e18cfc86fa86c2263cca2d2bdcc 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 51c4773a8db49de2965f883028cd6d3c337d2f4e..1bda26f088ac552228d52368fa637865be54445b 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 33f645fd6490859ec0b36185d8ca32195f5fdbc8..a49419f19dcd8033258153443632fd5151f4ed6d 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 58a5c915e529417bc2d6f7a7578f33b908418c7d..b1e9b1d7a9f94c4045b6122deb768c3d606d5232 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index f799faede21fec4ad5e016ee581cf529976b3b22..f171425f8a61f09b34aed8c5bd66fe78ea09c2c8 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index ce0d1335ca95305849cb16c596254dca7c31ad59..eb8e416eddb39a2cb958bf774508454935d4c01b 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 917f1a3842cf5a5f299818719081b0ec40bbf7a8..4f4c531819feaceb73aeb2cfe4650f597afc8445 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 705fff89b8bce721e9d5616bca778f15b109dddf..3320e7aca3eb59ff9439a0598402209d16c3528d 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 844168352c895ae31b22e40be4fe8aa8a51fe861..c93a1245b70e5a145c3e416ad09ab7dd1d55cfcc 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <testsuite_fs.h>
index f78f5dd8a9f6d7fdc86349707472c6ed37e35396..8c5bb954e81d42794bcf934c3f70c6f220631a29 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #undef _GLIBCXX_USE_CXX11_ABI
 #define _GLIBCXX_USE_CXX11_ABI 0
index 01b548bf5ef6b67b0eadd987a23c3f8726f936b8..1d6667910017740aed61fd617e0a6ad546e46d87 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <testsuite_hooks.h>
index 0bf8d34dbe0549a54403422ffaa7732ad88712ce..dde08d46f2cbb8940b53a54191ef0101dc84e06b 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <testsuite_hooks.h>
index 60e53fec2aa226e0fb68af501419fde4d7a2a364..5a0c24c25c359e8262dae6a50578422aab6e7bd6 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2017-2019 Free Software Foundation, Inc.
 //
index 70eba60b34e8ed75b5c60b095545d741eeee16d3..51583dd55b597d9931dcc1495a1748df70a56e9c 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <iterator>
index 16147ca8c28a1934435aaae42800f655d0a25d83..8513021e729327775e535d0f128148e749b37a43 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 65c2c4c049b6c099ff4e11c63a91d8c6f6a77ce7..3fa89938d7d0caad80039dcb25f30bb1f02e6141 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 2c514b4caffb2ce43d0b20627cd43b148a1759a2..e49c08e80328d51505a7fe07f6b910e3a1387bcc 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 53423155a753f5a061e8c3f1dae96c994edea32f..3b2ef062b6f3864c807aef88dae901221c4af1f0 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index b0f6ff70eabbd562abc1f220e628425e04f6c513..df4b77aa116a4042431cf2b6f7c4723cea5cefa4 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 52e438096b8960ce19ef992f057fc425d2324a83..6503454e303e2c7e7749cbe17c00dd2f8be261dc 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 34ae9262a8bd35ea2802ba05fc075c848983cb01..7414b8078b46c392ccfb12136c1906750d17a8f4 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 853eb70d0d2095cdee1e6376504df40c67432aa9..5417ab4c011f8ee9aa38bd5d394299a079d43082 100644 (file)
@@ -15,9 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 #include <filesystem>
 #include <string>
index 8c16f60bdadffa3f3ede52abac176f72fcc78a91..d4e1d6fb5f612a12895fbdd416b113cc1d7ab43b 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2018-2019 Free Software Foundation, Inc.
 //
index f8614d856565f3274fdd80e2c35331cbf2e554a0..13a0767a9eb6367f585df53dd3b1c39dca686a05 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index f176ef61848fb85ad8692bf9dc9185506eb7b9e2..7d0dc9bf8ccd5574ce6f8683a3b0b93dcc898998 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index a18fee6808fba0b3ca568ba9a262fc1a0fdb1f29..870d585a173ad3d0ec364ee8e8406f3b9510ce70 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index d58cc2760fd92874edc016b443ac3ed358812c47..7e6981130eab0cbdb88470e33c9c97e00ed50287 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 2d0b52ac315326bb92fdc30fdfa8efb1f3274e9f..17bbaba6310365f0fc16caa0fd6e3dfe525c0245 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 3af632badf10d8a93cd8372a06a0adb6c8470c07..42b1758d18a041d320dbc01ce38433a7b3649419 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index 4df0054f51809324e77bb68ea9ef367cfd13208a..d7f09b3f4b3b2725a3041521245db24a98b3d7eb 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index bda2c1c938a68ab1ed2c634d8d71ab26ac137fe3..15ab315bc93ae9617534010f2c6cad81cc185771 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index f5daabc9d2a5d3ccc15fa3ac5358db247a19695c..a5742ca4d77a02caab481d48ce3ba12aed5c463c 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index e3366763e9bd8039327c501a15cefb833646c4bf..097149941850193ed6affcbf603b9a7da7fce1e7 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //
index a48d3206eeb6919c7e673af28cad34dcffb2852b..ac97eee51155b84b922e51550cc8a44d6438fa1a 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2018-2019 Free Software Foundation, Inc.
 //
index 3f7317286e1f3b4c9df94759cb752dce52ac5589..61bbd57edece9d490cfef84a9cac6f1ddadd3bce 100644 (file)
@@ -1,6 +1,5 @@
-// { dg-options "-std=gnu++17 -lstdc++fs" }
+// { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
-// { dg-require-filesystem-ts "" }
 
 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
 //