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