]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc
PR libstdc++/71044 fix off-by-one errors introduced recently
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 27_io / filesystem / path / append / source.cc
CommitLineData
6cda876d
JW
1// { dg-options "-std=gnu++17 -lstdc++fs" }
2// { dg-do run { target c++17 } }
3// { dg-require-filesystem-ts "" }
4
5// Copyright (C) 2018 Free Software Foundation, Inc.
6//
7// This file is part of the GNU ISO C++ Library. This library is free
8// software; you can redistribute it and/or modify it under the
9// terms of the GNU General Public License as published by the
10// Free Software Foundation; either version 3, or (at your option)
11// any later version.
12
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License along
19// with this library; see the file COPYING3. If not see
20// <http://www.gnu.org/licenses/>.
21
22// C++17 30.10.8.4.3 path appends [fs.path.append]
23
24#include <filesystem>
25#include <string_view>
26#include <testsuite_fs.h>
27#include <testsuite_iterators.h>
28
29using std::filesystem::path;
30using __gnu_test::compare_paths;
31
32// path::operator/=(const Source& source)
33// path::append(const Source& source)
34// Equivalent to: return operator/=(path(source));
35
36// path::append(InputIterator first, InputIterator last)
37// Equivalent to: return operator/=(path(first, last));
38
49d729ea
JW
39template<typename Char>
40void test(const path& p, const Char* s)
6cda876d
JW
41{
42 path expected = p;
43 expected /= path(s);
44
45 path oper = p;
46 oper /= s;
47
48 path func = p;
49 func.append(s);
50
49d729ea
JW
51 __gnu_test::test_container<const Char, __gnu_test::input_iterator_wrapper>
52 input_range(s, s + std::char_traits<Char>::length(s));
6cda876d
JW
53 path range = p;
54 range.append(input_range.begin(), input_range.end());
55
56 compare_paths( oper, expected );
57 compare_paths( func, expected );
58 compare_paths( range, expected );
59}
60
61void
62test01()
63{
64 test( "/foo/bar", "/foo/" );
65
66 test( "baz", "baz" );
67 test( "baz/", "baz" );
68 test( "baz", "/foo/bar" );
69 test( "baz/", "/foo/bar" );
70
71 test( "", "" );
72 test( "", "rel" );
73
74 test( "dir/", "/file" );
75 test( "dir/", "file" );
76}
77
78void
79test02()
80{
81 // C++17 [fs.path.append] p4
82 test( "//host", "foo" );
83 test( "//host/", "foo" );
84 test( "foo", "" );
85 test( "foo", "/bar" );
86 test( "foo", "c:/bar" );
87 test( "foo", "c:" );
88 test( "c:", "" );
89 test( "c:foo", "/bar" );
90 test( "foo", "c:\\bar" );
91}
92
93void
94test03()
95{
96 for (const path& p : __gnu_test::test_paths)
97 for (const path& q : __gnu_test::test_paths)
49d729ea
JW
98 {
99 test(p, q.c_str());
100 if constexpr (!std::is_same_v<path::value_type, char>)
101 test(p, q.string().c_str());
102 }
103}
104
105void
106test04()
107{
108#ifdef _GLIBCXX_USE_WCHAR_T
109 test( "foo", L"/bar" );
110 test( L"foo", "/bar" );
111 test( L"foo", L"/bar" );
112#endif
6cda876d
JW
113}
114
4f87bb8d
JW
115void
116test05()
117{
118 std::basic_string_view<path::value_type> s;
119
120 path p = "0/1/2/3/4/5/6";
121 // The string_view aliases the path's internal string:
122 s = p.native();
123 // Append that string_view, which must work correctly even though the
124 // internal string will be reallocated during the operation:
125 p /= s;
126 VERIFY( p.string() == "0/1/2/3/4/5/6/0/1/2/3/4/5/6" );
127
128 // Same again with a trailing slash:
129 path p2 = "0/1/2/3/4/5/";
130 s = p2.native();
131 p2 /= s;
132 VERIFY( p2.string() == "0/1/2/3/4/5/0/1/2/3/4/5/" );
133
134 // And aliasing one of the components of the path:
135 path p3 = "0/123456789/a";
136 path::iterator second = std::next(p3.begin());
137 s = second->native();
138 p3 /= s;
139 VERIFY( p3.string() == "0/123456789/a/123456789" );
2017595d
JW
140 }
141
142void
143test06()
144{
145 const std::string s0 = "a/b/c";
146 path p = s0;
147 std::string s;
148 for (int i = 0; i < 10; ++i)
149 s += "0/1/2/3/4/5/6/7/8/9/";
150 // append a long string with many components
151 test(p, s.c_str());
152
153 // Same again but with a trailing slash on the left operand:
154 path p2 = s0 + '/';
155 test(p2, s.c_str());
4f87bb8d
JW
156}
157
6cda876d
JW
158int
159main()
160{
161 test01();
162 test02();
163 test03();
49d729ea 164 test04();
4f87bb8d 165 test05();
2017595d 166 test06();
6cda876d 167}