source.pass.cpp 6.5 KB

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