]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp
Vendor import of libc++ trunk r300422:
[FreeBSD/FreeBSD.git] / test / std / experimental / filesystem / class.path / path.member / path.assign / source.pass.cpp
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03
11
12 // <experimental/filesystem>
13
14 // class path
15
16 // template <class Source>
17 //      path& operator=(Source const&);
18 //  path& operator=(string_type&&);
19 // template <class Source>
20 //      path& assign(Source const&);
21 // template <class InputIterator>
22 //      path& assign(InputIterator first, InputIterator last);
23
24
25 #include <experimental/filesystem>
26 #include <type_traits>
27 #include <string_view>
28 #include <cassert>
29
30 #include "test_macros.h"
31 #include "test_iterators.h"
32 #include "count_new.hpp"
33 #include "filesystem_test_helper.hpp"
34 #include <iostream>
35
36 namespace fs = std::experimental::filesystem;
37
38 template <class CharT>
39 void RunTestCase(MultiStringType const& MS) {
40   using namespace fs;
41   const char* Expect = MS;
42   const CharT* TestPath = MS;
43   const CharT* TestPathEnd = StrEnd(TestPath);
44   const std::size_t Size = TestPathEnd - TestPath;
45   const std::size_t SSize = StrEnd(Expect) - Expect;
46   assert(Size == SSize);
47   //////////////////////////////////////////////////////////////////////////////
48   // basic_string<Char, Traits, Alloc>
49   {
50     const std::basic_string<CharT> S(TestPath);
51     path p; PathReserve(p, S.length() + 1);
52     {
53       // string provides a contiguous iterator. No allocation needed.
54       DisableAllocationGuard g;
55       path& pref = (p = S);
56       assert(&pref == &p);
57     }
58     assert(p.native() == Expect);
59     assert(p.string<CharT>() == TestPath);
60     assert(p.string<CharT>() == S);
61   }
62   {
63     const std::basic_string<CharT> S(TestPath);
64     path p; PathReserve(p, S.length() + 1);
65     {
66       DisableAllocationGuard g;
67       path& pref = p.assign(S);
68       assert(&pref == &p);
69     }
70     assert(p.native() == Expect);
71     assert(p.string<CharT>() == TestPath);
72     assert(p.string<CharT>() == S);
73   }
74   // basic_string<Char, Traits, Alloc>
75   {
76     const std::basic_string_view<CharT> S(TestPath);
77     path p; PathReserve(p, S.length() + 1);
78     {
79       // string provides a contiguous iterator. No allocation needed.
80       DisableAllocationGuard g;
81       path& pref = (p = S);
82       assert(&pref == &p);
83     }
84     assert(p.native() == Expect);
85     assert(p.string<CharT>() == TestPath);
86     assert(p.string<CharT>() == S);
87   }
88   {
89     const std::basic_string_view<CharT> S(TestPath);
90     path p; PathReserve(p, S.length() + 1);
91     {
92       DisableAllocationGuard g;
93       path& pref = p.assign(S);
94       assert(&pref == &p);
95     }
96     assert(p.native() == Expect);
97     assert(p.string<CharT>() == TestPath);
98     assert(p.string<CharT>() == S);
99   }
100   //////////////////////////////////////////////////////////////////////////////
101   // Char* pointers
102   {
103     path p; PathReserve(p, Size + 1);
104     {
105       // char* pointers are contiguous and can be used with code_cvt directly.
106       // no allocations needed.
107       DisableAllocationGuard g;
108       path& pref = (p = TestPath);
109       assert(&pref == &p);
110     }
111     assert(p.native() == Expect);
112     assert(p.string<CharT>() == TestPath);
113   }
114   {
115     path p; PathReserve(p, Size + 1);
116     {
117       DisableAllocationGuard g;
118       path& pref = p.assign(TestPath);
119       assert(&pref == &p);
120     }
121     assert(p.native() == Expect);
122     assert(p.string<CharT>() == TestPath);
123   }
124   {
125     path p; PathReserve(p, Size + 1);
126     {
127       DisableAllocationGuard g;
128       path& pref = p.assign(TestPath, TestPathEnd);
129       assert(&pref == &p);
130     }
131     assert(p.native() == Expect);
132     assert(p.string<CharT>() == TestPath);
133   }
134   //////////////////////////////////////////////////////////////////////////////
135   // Iterators
136   {
137     using It = input_iterator<const CharT*>;
138     path p; PathReserve(p, Size + 1);
139     It it(TestPath);
140     {
141       // Iterators cannot be used with code_cvt directly. This assignment
142       // may allocate if it's larger than a "short-string".
143       path& pref = (p = it);
144       assert(&pref == &p);
145     }
146     assert(p.native() == Expect);
147     assert(p.string<CharT>() == TestPath);
148   }
149   {
150     using It = input_iterator<const CharT*>;
151     path p; PathReserve(p, Size + 1);
152     It it(TestPath);
153     {
154       path& pref = p.assign(it);
155       assert(&pref == &p);
156     }
157     assert(p.native() == Expect);
158     assert(p.string<CharT>() == TestPath);
159   }
160   {
161     using It = input_iterator<const CharT*>;
162     path p; PathReserve(p, Size + 1);
163     It it(TestPath);
164     It e(TestPathEnd);
165     {
166       path& pref = p.assign(it, e);
167       assert(&pref == &p);
168     }
169     assert(p.native() == Expect);
170     assert(p.string<CharT>() == TestPath);
171   }
172 }
173
174 template <class It, class = decltype(fs::path{}.assign(std::declval<It>()))>
175 constexpr bool has_assign(int) { return true; }
176 template <class It>
177 constexpr bool has_assign(long) { return false; }
178 template <class It>
179 constexpr bool has_assign() { return has_assign<It>(0); }
180
181 void test_sfinae() {
182   using namespace fs;
183   {
184     using It = const char* const;
185     static_assert(std::is_assignable<path, It>::value, "");
186     static_assert(has_assign<It>(), "");
187   }
188   {
189     using It = input_iterator<const char*>;
190     static_assert(std::is_assignable<path, It>::value, "");
191     static_assert(has_assign<It>(), "");
192   }
193   {
194     struct Traits {
195       using iterator_category = std::input_iterator_tag;
196       using value_type = const char;
197       using pointer = const char*;
198       using reference = const char&;
199       using difference_type = std::ptrdiff_t;
200     };
201     using It = input_iterator<const char*, Traits>;
202     static_assert(std::is_assignable<path, It>::value, "");
203     static_assert(has_assign<It>(), "");
204   }
205   {
206     using It = output_iterator<const char*>;
207     static_assert(!std::is_assignable<path, It>::value, "");
208     static_assert(!has_assign<It>(), "");
209
210   }
211   {
212     static_assert(!std::is_assignable<path, int*>::value, "");
213     static_assert(!has_assign<int*>(), "");
214   }
215 }
216
217 void RunStringMoveTest(const char* Expect) {
218   using namespace fs;
219   std::string ss(Expect);
220   path p;
221   {
222     DisableAllocationGuard g; ((void)g);
223     path& pr = (p = std::move(ss));
224     assert(&pr == &p);
225   }
226   assert(p == Expect);
227   {
228     // Signature test
229     ASSERT_NOEXCEPT(p = std::move(ss));
230   }
231 }
232
233 int main() {
234   for (auto const& MS : PathList) {
235     RunTestCase<char>(MS);
236     RunTestCase<wchar_t>(MS);
237     RunTestCase<char16_t>(MS);
238     RunTestCase<char32_t>(MS);
239     RunStringMoveTest(MS);
240   }
241   test_sfinae();
242 }