]>
Commit | Line | Data |
---|---|---|
2b522535 | 1 | // { dg-options "-std=gnu++17" } |
641cb5a6 | 2 | // { dg-do run { target c++17 } } |
641cb5a6 | 3 | |
8d9254fc | 4 | // Copyright (C) 2014-2020 Free Software Foundation, Inc. |
641cb5a6 JW |
5 | // |
6 | // This file is part of the GNU ISO C++ Library. This library is free | |
7 | // software; you can redistribute it and/or modify it under the | |
8 | // terms of the GNU General Public License as published by the | |
9 | // Free Software Foundation; either version 3, or (at your option) | |
10 | // any later version. | |
11 | ||
12 | // This library is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | ||
17 | // You should have received a copy of the GNU General Public License along | |
18 | // with this library; see the file COPYING3. If not see | |
19 | // <http://www.gnu.org/licenses/>. | |
20 | ||
eeb517d3 | 21 | // 30.10.7.4.4 path concatenation [fs.path.concat] |
641cb5a6 JW |
22 | |
23 | #include <filesystem> | |
24 | #include <testsuite_hooks.h> | |
49d729ea | 25 | #include <testsuite_iterators.h> |
2017595d | 26 | #include <testsuite_fs.h> |
641cb5a6 JW |
27 | |
28 | using std::filesystem::path; | |
2017595d | 29 | using __gnu_test::compare_paths; |
641cb5a6 JW |
30 | |
31 | void | |
32 | test01() | |
33 | { | |
34 | path p("/"); | |
49d729ea JW |
35 | p += "foo"; |
36 | VERIFY( p.filename().string() == "foo" ); | |
641cb5a6 | 37 | p += "bar"; |
49d729ea | 38 | VERIFY( p.filename().string() == "foobar" ); |
641cb5a6 | 39 | p += '/'; |
49d729ea JW |
40 | VERIFY( p.parent_path().string() == "/foobar" ); |
41 | VERIFY( p.filename().string() == "" ); | |
641cb5a6 | 42 | #if _GLIBCXX_USE_WCHAR_T |
49d729ea JW |
43 | VERIFY( p.parent_path().wstring() == L"/foobar" ); |
44 | VERIFY( p.filename().wstring() == L"" ); | |
641cb5a6 JW |
45 | p += L"baz.txt"; |
46 | #else | |
47 | p += "baz.txt"; | |
48 | #endif | |
49d729ea | 49 | VERIFY( p.filename().string() == "baz.txt" ); |
641cb5a6 | 50 | p.concat("/dir/"); |
49d729ea JW |
51 | // N.B. on Windows p.parent_path() is "/foobar\\baz.txt\\dir" |
52 | VERIFY( p.parent_path() == path("/foobar/baz.txt/dir") ); | |
53 | VERIFY( p.filename().string() == "" ); | |
54 | const char file[] = "file"; | |
55 | __gnu_test::test_container<const char, __gnu_test::input_iterator_wrapper> | |
56 | input(file, file + 4); | |
57 | p.concat(input.begin(), input.end()); | |
58 | VERIFY( p.filename().string() == file ); | |
641cb5a6 JW |
59 | } |
60 | ||
4f87bb8d JW |
61 | void |
62 | test02() | |
63 | { | |
2017595d | 64 | std::basic_string_view<path::value_type> s, expected; |
4f87bb8d JW |
65 | |
66 | path p = "0/1/2/3/4/5/6"; | |
67 | // The string_view aliases the path's internal string: | |
68 | s = p.native(); | |
69 | // Append that string_view, which must work correctly even though the | |
70 | // internal string will be reallocated during the operation: | |
71 | p += s; | |
2017595d | 72 | compare_paths(p, "0/1/2/3/4/5/60/1/2/3/4/5/6"); |
4f87bb8d JW |
73 | |
74 | // Same again with a trailing slash: | |
75 | path p2 = "0/1/2/3/4/5/"; | |
76 | s = p2.native(); | |
77 | p2 += s; | |
2017595d | 78 | compare_paths(p2, "0/1/2/3/4/5/0/1/2/3/4/5/"); |
4f87bb8d JW |
79 | |
80 | // And aliasing one of the components of the path: | |
81 | path p3 = "0/123456789"; | |
82 | path::iterator second = std::next(p3.begin()); | |
83 | s = second->native(); | |
84 | p3 += s; | |
2017595d | 85 | compare_paths(p3, "0/123456789123456789" ); |
4f87bb8d JW |
86 | } |
87 | ||
2017595d JW |
88 | void |
89 | test03() | |
90 | { | |
91 | const std::string s0 = "a/b/c"; | |
92 | path p = s0; | |
93 | std::string s; | |
94 | for (int i = 0; i < 10; ++i) | |
95 | s += "0/1/2/3/4/5/6/7/8/9/"; | |
96 | // concat a long string with many components: | |
97 | p += s; | |
98 | compare_paths(p, path(s0+s)); | |
99 | ||
100 | // Same again but with a trailing slash on the left operand: | |
101 | path p2 = s0 + '/'; | |
102 | p2 += s; | |
103 | compare_paths(p2, path(s0+'/'+s)); | |
104 | ||
105 | // And again but with a leading slash on the right operand: | |
106 | path p3 = s0; | |
107 | s.insert(0, 1, '/'); | |
108 | p3 += s; | |
109 | compare_paths(p2, path(s0+s)); | |
110 | ||
111 | // And again but with a slash on both operands: | |
112 | path p4 = s0 + '/'; | |
113 | p4 += s; | |
114 | compare_paths(p4, path(s0+'/'+s)); | |
115 | } | |
1d214c3f JW |
116 | |
117 | void | |
118 | test04() | |
119 | { | |
120 | // Concat every test path onto every test path. | |
121 | for (path p : __gnu_test::test_paths) | |
122 | { | |
123 | for (path x : __gnu_test::test_paths) | |
124 | { | |
125 | auto prior_native = p.native(); | |
126 | p += x.native(); | |
127 | VERIFY( p.native() == prior_native + x.native() ); | |
128 | path copy(p); | |
129 | compare_paths( copy, p ); | |
130 | } | |
131 | } | |
132 | } | |
133 | ||
641cb5a6 JW |
134 | int |
135 | main() | |
136 | { | |
137 | test01(); | |
4f87bb8d | 138 | test02(); |
2017595d | 139 | test03(); |
1d214c3f | 140 | test04(); |
641cb5a6 | 141 | } |