1f7b43230SLouis Dionne //===----------------------------------------------------------------------===// 2f7b43230SLouis Dionne // 3f7b43230SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f7b43230SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 5f7b43230SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f7b43230SLouis Dionne // 7f7b43230SLouis Dionne //===----------------------------------------------------------------------===// 8f7b43230SLouis Dionne 931cbe0f2SLouis Dionne // UNSUPPORTED: c++03 10f7b43230SLouis Dionne 1188ffc727SLouis Dionne // These tests require locale for non-char paths 1288ffc727SLouis Dionne // UNSUPPORTED: libcpp-has-no-localization 1388ffc727SLouis Dionne 14f7b43230SLouis Dionne // <filesystem> 15f7b43230SLouis Dionne 16f7b43230SLouis Dionne // class path 17f7b43230SLouis Dionne 18f7b43230SLouis Dionne // path& operator/=(path const&) 19f7b43230SLouis Dionne // template <class Source> 20f7b43230SLouis Dionne // path& operator/=(Source const&); 21f7b43230SLouis Dionne // template <class Source> 22f7b43230SLouis Dionne // path& append(Source const&); 23f7b43230SLouis Dionne // template <class InputIterator> 24f7b43230SLouis Dionne // path& append(InputIterator first, InputIterator last); 25f7b43230SLouis Dionne 26f7b43230SLouis Dionne 27cc89063bSNico Weber #include "filesystem_include.h" 28f7b43230SLouis Dionne #include <type_traits> 29f7b43230SLouis Dionne #include <string_view> 30f7b43230SLouis Dionne #include <cassert> 31f7b43230SLouis Dionne 32f7b43230SLouis Dionne #include "test_macros.h" 33f7b43230SLouis Dionne #include "test_iterators.h" 34cc89063bSNico Weber #include "count_new.h" 35cc89063bSNico Weber #include "filesystem_test_helper.h" 36f7b43230SLouis Dionne 37f7b43230SLouis Dionne 38f7b43230SLouis Dionne struct AppendOperatorTestcase { 39f7b43230SLouis Dionne MultiStringType lhs; 40f7b43230SLouis Dionne MultiStringType rhs; 4153d7c636SMartin Storsjö MultiStringType expect_posix; 4253d7c636SMartin Storsjö MultiStringType expect_windows; 4353d7c636SMartin Storsjö 4453d7c636SMartin Storsjö MultiStringType const& expected_result() const { 4553d7c636SMartin Storsjö #ifdef _WIN32 4653d7c636SMartin Storsjö return expect_windows; 4753d7c636SMartin Storsjö #else 4853d7c636SMartin Storsjö return expect_posix; 4953d7c636SMartin Storsjö #endif 5053d7c636SMartin Storsjö } 51f7b43230SLouis Dionne }; 52f7b43230SLouis Dionne 53f7b43230SLouis Dionne #define S(Str) MKSTR(Str) 54f7b43230SLouis Dionne const AppendOperatorTestcase Cases[] = 55f7b43230SLouis Dionne { 5653d7c636SMartin Storsjö {S(""), S(""), S(""), S("")} 5753d7c636SMartin Storsjö , {S("p1"), S("p2"), S("p1/p2"), S("p1\\p2")} 5853d7c636SMartin Storsjö , {S("p1/"), S("p2"), S("p1/p2"), S("p1/p2")} 5953d7c636SMartin Storsjö , {S("p1"), S("/p2"), S("/p2"), S("/p2")} 6053d7c636SMartin Storsjö , {S("p1/"), S("/p2"), S("/p2"), S("/p2")} 6153d7c636SMartin Storsjö , {S("p1"), S("\\p2"), S("p1/\\p2"), S("\\p2")} 6253d7c636SMartin Storsjö , {S("p1\\"), S("p2"), S("p1\\/p2"), S("p1\\p2")} 6353d7c636SMartin Storsjö , {S("p1\\"), S("\\p2"), S("p1\\/\\p2"), S("\\p2")} 6453d7c636SMartin Storsjö , {S(""), S("p2"), S("p2"), S("p2")} 6553d7c636SMartin Storsjö , {S("/p1"), S("p2"), S("/p1/p2"), S("/p1\\p2")} 6653d7c636SMartin Storsjö , {S("/p1"), S("/p2"), S("/p2"), S("/p2")} 6753d7c636SMartin Storsjö , {S("/p1/p3"), S("p2"), S("/p1/p3/p2"), S("/p1/p3\\p2")} 6853d7c636SMartin Storsjö , {S("/p1/p3/"), S("p2"), S("/p1/p3/p2"), S("/p1/p3/p2")} 6953d7c636SMartin Storsjö , {S("/p1/"), S("p2"), S("/p1/p2"), S("/p1/p2")} 7053d7c636SMartin Storsjö , {S("/p1/p3/"), S("/p2/p4"), S("/p2/p4"), S("/p2/p4")} 7153d7c636SMartin Storsjö , {S("/"), S(""), S("/"), S("/")} 7253d7c636SMartin Storsjö , {S("/p1"), S("/p2/"), S("/p2/"), S("/p2/")} 7353d7c636SMartin Storsjö , {S("p1"), S(""), S("p1/"), S("p1\\")} 7453d7c636SMartin Storsjö , {S("p1/"), S(""), S("p1/"), S("p1/")} 7578d693faSMartin Storsjö 7653d7c636SMartin Storsjö , {S("//host"), S("foo"), S("//host/foo"), S("//host\\foo")} 7753d7c636SMartin Storsjö , {S("//host/"), S("foo"), S("//host/foo"), S("//host/foo")} 7853d7c636SMartin Storsjö , {S("//host"), S(""), S("//host/"), S("//host\\")} 7978d693faSMartin Storsjö 8053d7c636SMartin Storsjö , {S("foo"), S("C:/bar"), S("foo/C:/bar"), S("C:/bar")} 8153d7c636SMartin Storsjö , {S("foo"), S("C:"), S("foo/C:"), S("C:")} 8278d693faSMartin Storsjö 8353d7c636SMartin Storsjö , {S("C:"), S(""), S("C:/"), S("C:")} 8453d7c636SMartin Storsjö , {S("C:foo"), S("/bar"), S("/bar"), S("C:/bar")} 8553d7c636SMartin Storsjö , {S("C:foo"), S("bar"), S("C:foo/bar"), S("C:foo\\bar")} 8653d7c636SMartin Storsjö , {S("C:/foo"), S("bar"), S("C:/foo/bar"), S("C:/foo\\bar")} 8753d7c636SMartin Storsjö , {S("C:/foo"), S("/bar"), S("/bar"), S("C:/bar")} 8878d693faSMartin Storsjö 8953d7c636SMartin Storsjö , {S("C:foo"), S("C:/bar"), S("C:foo/C:/bar"), S("C:/bar")} 9053d7c636SMartin Storsjö , {S("C:foo"), S("C:bar"), S("C:foo/C:bar"), S("C:foo\\bar")} 9153d7c636SMartin Storsjö , {S("C:/foo"), S("C:/bar"), S("C:/foo/C:/bar"), S("C:/bar")} 9253d7c636SMartin Storsjö , {S("C:/foo"), S("C:bar"), S("C:/foo/C:bar"), S("C:/foo\\bar")} 9378d693faSMartin Storsjö 9453d7c636SMartin Storsjö , {S("C:foo"), S("c:/bar"), S("C:foo/c:/bar"), S("c:/bar")} 9553d7c636SMartin Storsjö , {S("C:foo"), S("c:bar"), S("C:foo/c:bar"), S("c:bar")} 9653d7c636SMartin Storsjö , {S("C:/foo"), S("c:/bar"), S("C:/foo/c:/bar"), S("c:/bar")} 9753d7c636SMartin Storsjö , {S("C:/foo"), S("c:bar"), S("C:/foo/c:bar"), S("c:bar")} 9878d693faSMartin Storsjö 9953d7c636SMartin Storsjö , {S("C:/foo"), S("D:bar"), S("C:/foo/D:bar"), S("D:bar")} 100f7b43230SLouis Dionne }; 101f7b43230SLouis Dionne 102f7b43230SLouis Dionne 103f7b43230SLouis Dionne const AppendOperatorTestcase LongLHSCases[] = 104f7b43230SLouis Dionne { 10553d7c636SMartin Storsjö {S("p1"), S("p2"), S("p1/p2"), S("p1\\p2")} 10653d7c636SMartin Storsjö , {S("p1/"), S("p2"), S("p1/p2"), S("p1/p2")} 10753d7c636SMartin Storsjö , {S("p1"), S("/p2"), S("/p2"), S("/p2")} 10853d7c636SMartin Storsjö , {S("/p1"), S("p2"), S("/p1/p2"), S("/p1\\p2")} 109f7b43230SLouis Dionne }; 110f7b43230SLouis Dionne #undef S 111f7b43230SLouis Dionne 112f7b43230SLouis Dionne 113f7b43230SLouis Dionne // The append operator may need to allocate a temporary buffer before a code_cvt 114f7b43230SLouis Dionne // conversion. Test if this allocation occurs by: 115f7b43230SLouis Dionne // 1. Create a path, `LHS`, and reserve enough space to append `RHS`. 116f7b43230SLouis Dionne // This prevents `LHS` from allocating during the actual appending. 117f7b43230SLouis Dionne // 2. Create a `Source` object `RHS`, which represents a "large" string. 118f7b43230SLouis Dionne // (The string must not trigger the SSO) 119f7b43230SLouis Dionne // 3. Append `RHS` to `LHS` and check for the expected allocation behavior. 120f7b43230SLouis Dionne template <class CharT> 121f7b43230SLouis Dionne void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) 122f7b43230SLouis Dionne { 123f7b43230SLouis Dionne using namespace fs; 124f7b43230SLouis Dionne using Ptr = CharT const*; 125f7b43230SLouis Dionne using Str = std::basic_string<CharT>; 126f7b43230SLouis Dionne using StrView = std::basic_string_view<CharT>; 127f7b43230SLouis Dionne using InputIter = input_iterator<Ptr>; 128f7b43230SLouis Dionne 129f7b43230SLouis Dionne const Ptr L = TC.lhs; 130f7b43230SLouis Dionne Str RShort = (Ptr)TC.rhs; 13153d7c636SMartin Storsjö Str EShort = (Ptr)TC.expected_result(); 132f7b43230SLouis Dionne assert(RShort.size() >= 2); 133f7b43230SLouis Dionne CharT c = RShort.back(); 134f7b43230SLouis Dionne RShort.append(100, c); 135f7b43230SLouis Dionne EShort.append(100, c); 136f7b43230SLouis Dionne const Ptr R = RShort.data(); 137f7b43230SLouis Dionne const Str& E = EShort; 138f7b43230SLouis Dionne std::size_t ReserveSize = E.size() + 3; 139f7b43230SLouis Dionne // basic_string 140f7b43230SLouis Dionne { 141f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 142f7b43230SLouis Dionne Str RHS(R); 143f7b43230SLouis Dionne { 144f7b43230SLouis Dionne DisableAllocationGuard g; 145f7b43230SLouis Dionne LHS /= RHS; 146f7b43230SLouis Dionne } 147e557b6a6SLouis Dionne assert(PathEq(LHS, E)); 148f7b43230SLouis Dionne } 149f7b43230SLouis Dionne // basic_string_view 150f7b43230SLouis Dionne { 151f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 152f7b43230SLouis Dionne StrView RHS(R); 153f7b43230SLouis Dionne { 154f7b43230SLouis Dionne DisableAllocationGuard g; 155f7b43230SLouis Dionne LHS /= RHS; 156f7b43230SLouis Dionne } 157f7b43230SLouis Dionne assert(PathEq(LHS, E)); 158f7b43230SLouis Dionne } 159f7b43230SLouis Dionne // CharT* 160f7b43230SLouis Dionne { 161f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 162f7b43230SLouis Dionne Ptr RHS(R); 163f7b43230SLouis Dionne { 164f7b43230SLouis Dionne DisableAllocationGuard g; 165f7b43230SLouis Dionne LHS /= RHS; 166f7b43230SLouis Dionne } 167f7b43230SLouis Dionne assert(PathEq(LHS, E)); 168f7b43230SLouis Dionne } 169f7b43230SLouis Dionne { 170f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 171f7b43230SLouis Dionne Ptr RHS(R); 172f7b43230SLouis Dionne { 173f7b43230SLouis Dionne DisableAllocationGuard g; 174f7b43230SLouis Dionne LHS.append(RHS, StrEnd(RHS)); 175f7b43230SLouis Dionne } 176f7b43230SLouis Dionne assert(PathEq(LHS, E)); 177f7b43230SLouis Dionne } 178*49173ca4SMartin Storsjö { 179*49173ca4SMartin Storsjö path LHS(L); PathReserve(LHS, ReserveSize); 180*49173ca4SMartin Storsjö path RHS(R); 181*49173ca4SMartin Storsjö { 182*49173ca4SMartin Storsjö DisableAllocationGuard g; 183*49173ca4SMartin Storsjö LHS /= RHS; 184*49173ca4SMartin Storsjö } 185*49173ca4SMartin Storsjö assert(PathEq(LHS, E)); 186*49173ca4SMartin Storsjö } 187f7b43230SLouis Dionne // input iterator - For non-native char types, appends needs to copy the 188f7b43230SLouis Dionne // iterator range into a contiguous block of memory before it can perform the 189f7b43230SLouis Dionne // code_cvt conversions. 190f7b43230SLouis Dionne // For "char" no allocations will be performed because no conversion is 191f7b43230SLouis Dionne // required. 192f7b43230SLouis Dionne bool DisableAllocations = std::is_same<CharT, char>::value; 193f7b43230SLouis Dionne { 194f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 195f7b43230SLouis Dionne InputIter RHS(R); 196f7b43230SLouis Dionne { 197f7b43230SLouis Dionne RequireAllocationGuard g; // requires 1 or more allocations occur by default 198f7b43230SLouis Dionne if (DisableAllocations) g.requireExactly(0); 199f7b43230SLouis Dionne LHS /= RHS; 200f7b43230SLouis Dionne } 201f7b43230SLouis Dionne assert(PathEq(LHS, E)); 202f7b43230SLouis Dionne } 203f7b43230SLouis Dionne { 204f7b43230SLouis Dionne path LHS(L); PathReserve(LHS, ReserveSize); 205f7b43230SLouis Dionne InputIter RHS(R); 206f7b43230SLouis Dionne InputIter REnd(StrEnd(R)); 207f7b43230SLouis Dionne { 208f7b43230SLouis Dionne RequireAllocationGuard g; 209f7b43230SLouis Dionne if (DisableAllocations) g.requireExactly(0); 210f7b43230SLouis Dionne LHS.append(RHS, REnd); 211f7b43230SLouis Dionne } 212f7b43230SLouis Dionne assert(PathEq(LHS, E)); 213f7b43230SLouis Dionne } 214f7b43230SLouis Dionne } 215f7b43230SLouis Dionne 216f7b43230SLouis Dionne template <class CharT> 217f7b43230SLouis Dionne void doAppendSourceTest(AppendOperatorTestcase const& TC) 218f7b43230SLouis Dionne { 219f7b43230SLouis Dionne using namespace fs; 220f7b43230SLouis Dionne using Ptr = CharT const*; 221f7b43230SLouis Dionne using Str = std::basic_string<CharT>; 222f7b43230SLouis Dionne using StrView = std::basic_string_view<CharT>; 223f7b43230SLouis Dionne using InputIter = input_iterator<Ptr>; 224f7b43230SLouis Dionne const Ptr L = TC.lhs; 225f7b43230SLouis Dionne const Ptr R = TC.rhs; 22653d7c636SMartin Storsjö const Ptr E = TC.expected_result(); 227f7b43230SLouis Dionne // basic_string 228f7b43230SLouis Dionne { 229f7b43230SLouis Dionne path Result(L); 230f7b43230SLouis Dionne Str RHS(R); 231f7b43230SLouis Dionne path& Ref = (Result /= RHS); 232e557b6a6SLouis Dionne assert(Result == E); 233f7b43230SLouis Dionne assert(&Ref == &Result); 234f7b43230SLouis Dionne } 235f7b43230SLouis Dionne { 236f7b43230SLouis Dionne path LHS(L); 237f7b43230SLouis Dionne Str RHS(R); 238f7b43230SLouis Dionne path& Ref = LHS.append(RHS); 239f7b43230SLouis Dionne assert(PathEq(LHS, E)); 240f7b43230SLouis Dionne assert(&Ref == &LHS); 241f7b43230SLouis Dionne } 242f7b43230SLouis Dionne // basic_string_view 243f7b43230SLouis Dionne { 244f7b43230SLouis Dionne path LHS(L); 245f7b43230SLouis Dionne StrView RHS(R); 246f7b43230SLouis Dionne path& Ref = (LHS /= RHS); 247f7b43230SLouis Dionne assert(PathEq(LHS, E)); 248f7b43230SLouis Dionne assert(&Ref == &LHS); 249f7b43230SLouis Dionne } 250f7b43230SLouis Dionne { 251f7b43230SLouis Dionne path LHS(L); 252f7b43230SLouis Dionne StrView RHS(R); 253f7b43230SLouis Dionne path& Ref = LHS.append(RHS); 254f7b43230SLouis Dionne assert(PathEq(LHS, E)); 255f7b43230SLouis Dionne assert(&Ref == &LHS); 256f7b43230SLouis Dionne } 257f7b43230SLouis Dionne // Char* 258f7b43230SLouis Dionne { 259f7b43230SLouis Dionne path LHS(L); 260f7b43230SLouis Dionne Str RHS(R); 261f7b43230SLouis Dionne path& Ref = (LHS /= RHS); 262f7b43230SLouis Dionne assert(PathEq(LHS, E)); 263f7b43230SLouis Dionne assert(&Ref == &LHS); 264f7b43230SLouis Dionne } 265f7b43230SLouis Dionne { 266f7b43230SLouis Dionne path LHS(L); 267f7b43230SLouis Dionne Ptr RHS(R); 268f7b43230SLouis Dionne path& Ref = LHS.append(RHS); 269f7b43230SLouis Dionne assert(PathEq(LHS, E)); 270f7b43230SLouis Dionne assert(&Ref == &LHS); 271f7b43230SLouis Dionne } 272f7b43230SLouis Dionne { 273f7b43230SLouis Dionne path LHS(L); 274f7b43230SLouis Dionne Ptr RHS(R); 275f7b43230SLouis Dionne path& Ref = LHS.append(RHS, StrEnd(RHS)); 276e557b6a6SLouis Dionne assert(PathEq(LHS, E)); 277f7b43230SLouis Dionne assert(&Ref == &LHS); 278f7b43230SLouis Dionne } 279f7b43230SLouis Dionne // iterators 280f7b43230SLouis Dionne { 281f7b43230SLouis Dionne path LHS(L); 282f7b43230SLouis Dionne InputIter RHS(R); 283f7b43230SLouis Dionne path& Ref = (LHS /= RHS); 284f7b43230SLouis Dionne assert(PathEq(LHS, E)); 285f7b43230SLouis Dionne assert(&Ref == &LHS); 286f7b43230SLouis Dionne } 287f7b43230SLouis Dionne { 288f7b43230SLouis Dionne path LHS(L); InputIter RHS(R); 289f7b43230SLouis Dionne path& Ref = LHS.append(RHS); 290f7b43230SLouis Dionne assert(PathEq(LHS, E)); 291f7b43230SLouis Dionne assert(&Ref == &LHS); 292f7b43230SLouis Dionne } 293f7b43230SLouis Dionne { 294f7b43230SLouis Dionne path LHS(L); 295f7b43230SLouis Dionne InputIter RHS(R); 296f7b43230SLouis Dionne InputIter REnd(StrEnd(R)); 297f7b43230SLouis Dionne path& Ref = LHS.append(RHS, REnd); 298f7b43230SLouis Dionne assert(PathEq(LHS, E)); 299f7b43230SLouis Dionne assert(&Ref == &LHS); 300f7b43230SLouis Dionne } 301f7b43230SLouis Dionne } 302f7b43230SLouis Dionne 303f7b43230SLouis Dionne 304f7b43230SLouis Dionne 305f7b43230SLouis Dionne template <class It, class = decltype(fs::path{}.append(std::declval<It>()))> 306f7b43230SLouis Dionne constexpr bool has_append(int) { return true; } 307f7b43230SLouis Dionne template <class It> 308f7b43230SLouis Dionne constexpr bool has_append(long) { return false; } 309f7b43230SLouis Dionne 310f7b43230SLouis Dionne template <class It, class = decltype(fs::path{}.operator/=(std::declval<It>()))> 311f7b43230SLouis Dionne constexpr bool has_append_op(int) { return true; } 312f7b43230SLouis Dionne template <class It> 313f7b43230SLouis Dionne constexpr bool has_append_op(long) { return false; } 314f7b43230SLouis Dionne 315f7b43230SLouis Dionne template <class It> 316f7b43230SLouis Dionne constexpr bool has_append() { 317f7b43230SLouis Dionne static_assert(has_append<It>(0) == has_append_op<It>(0), "must be same"); 318f7b43230SLouis Dionne return has_append<It>(0) && has_append_op<It>(0); 319f7b43230SLouis Dionne } 320f7b43230SLouis Dionne 321f7b43230SLouis Dionne void test_sfinae() 322f7b43230SLouis Dionne { 323f7b43230SLouis Dionne using namespace fs; 324f7b43230SLouis Dionne { 325f7b43230SLouis Dionne using It = const char* const; 326f7b43230SLouis Dionne static_assert(has_append<It>(), ""); 327f7b43230SLouis Dionne } 328f7b43230SLouis Dionne { 329f7b43230SLouis Dionne using It = input_iterator<const char*>; 330f7b43230SLouis Dionne static_assert(has_append<It>(), ""); 331f7b43230SLouis Dionne } 332f7b43230SLouis Dionne { 333f7b43230SLouis Dionne struct Traits { 334f7b43230SLouis Dionne using iterator_category = std::input_iterator_tag; 335f7b43230SLouis Dionne using value_type = const char; 336f7b43230SLouis Dionne using pointer = const char*; 337f7b43230SLouis Dionne using reference = const char&; 338f7b43230SLouis Dionne using difference_type = std::ptrdiff_t; 339f7b43230SLouis Dionne }; 340f7b43230SLouis Dionne using It = input_iterator<const char*, Traits>; 341f7b43230SLouis Dionne static_assert(has_append<It>(), ""); 342f7b43230SLouis Dionne } 343f7b43230SLouis Dionne { 344f7b43230SLouis Dionne using It = output_iterator<const char*>; 345f7b43230SLouis Dionne static_assert(!has_append<It>(), ""); 346f7b43230SLouis Dionne 347f7b43230SLouis Dionne } 348f7b43230SLouis Dionne { 349f7b43230SLouis Dionne static_assert(!has_append<int*>(), ""); 350f7b43230SLouis Dionne } 351f7b43230SLouis Dionne { 352f7b43230SLouis Dionne static_assert(!has_append<char>(), ""); 353f7b43230SLouis Dionne static_assert(!has_append<const char>(), ""); 354f7b43230SLouis Dionne } 355f7b43230SLouis Dionne } 356f7b43230SLouis Dionne 357f7b43230SLouis Dionne int main(int, char**) 358f7b43230SLouis Dionne { 359f7b43230SLouis Dionne using namespace fs; 360f7b43230SLouis Dionne for (auto const & TC : Cases) { 361f7b43230SLouis Dionne { 362f7b43230SLouis Dionne const char* LHS_In = TC.lhs; 363f7b43230SLouis Dionne const char* RHS_In = TC.rhs; 364f7b43230SLouis Dionne path LHS(LHS_In); 365f7b43230SLouis Dionne path RHS(RHS_In); 366f7b43230SLouis Dionne path& Res = (LHS /= RHS); 36753d7c636SMartin Storsjö assert(PathEq(Res, (const char*)TC.expected_result())); 368f7b43230SLouis Dionne assert(&Res == &LHS); 369f7b43230SLouis Dionne } 370f7b43230SLouis Dionne doAppendSourceTest<char> (TC); 371f7b43230SLouis Dionne doAppendSourceTest<wchar_t> (TC); 372f7b43230SLouis Dionne doAppendSourceTest<char16_t>(TC); 373f7b43230SLouis Dionne doAppendSourceTest<char32_t>(TC); 374f7b43230SLouis Dionne } 375f7b43230SLouis Dionne for (auto const & TC : LongLHSCases) { 37622e5ee0eSMartin Storsjö (void)TC; 377afe40b30SMartin Storsjö LIBCPP_ONLY(doAppendSourceAllocTest<char>(TC)); 378afe40b30SMartin Storsjö LIBCPP_ONLY(doAppendSourceAllocTest<wchar_t>(TC)); 379f7b43230SLouis Dionne } 380f7b43230SLouis Dionne test_sfinae(); 381f7b43230SLouis Dionne 382f7b43230SLouis Dionne return 0; 383f7b43230SLouis Dionne } 384