source.pass.cpp 6.5 KB

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