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 9 // UNSUPPORTED: c++03 10 11 // These tests require locale for non-char paths 12 // UNSUPPORTED: libcpp-has-no-localization 13 14 // <filesystem> 15 16 // class path 17 18 // template <class ECharT, class Traits = char_traits<ECharT>, 19 // class Allocator = allocator<ECharT>> 20 // basic_string<ECharT, Traits, Allocator> 21 // string(const Allocator& a = Allocator()) const; 22 23 #include "filesystem_include.h" 24 #include <type_traits> 25 #include <cassert> 26 27 #include "test_macros.h" 28 #include "test_iterators.h" 29 #include "count_new.h" 30 #include "min_allocator.h" 31 #include "filesystem_test_helper.h" 32 33 34 // the SSO is always triggered for strings of size 2. 35 MultiStringType shortString = MKSTR("a"); 36 MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); 37 38 template <class CharT> 39 void doShortStringTest(MultiStringType const& MS) { 40 using namespace fs; 41 using Ptr = CharT const*; 42 using Str = std::basic_string<CharT>; 43 using Alloc = std::allocator<CharT>; 44 Ptr value = MS; 45 const path p((const char*)MS); 46 #ifdef _WIN32 47 // On Windows, charset conversions cause allocations outside of the 48 // provided allocator, but accessing the native type should work without 49 // extra allocations. 50 bool DisableAllocations = std::is_same<CharT, path::value_type>::value; 51 #else 52 // On other platforms, these methods only use the provided allocator, and 53 // no extra allocations should be done. 54 bool DisableAllocations = true; 55 #endif 56 { 57 DisableAllocationGuard g(DisableAllocations); 58 Str s = p.string<CharT>(); 59 assert(s == value); 60 Str s2 = p.string<CharT>(Alloc{}); 61 assert(s2 == value); 62 } 63 using MAlloc = malloc_allocator<CharT>; 64 MAlloc::reset(); 65 { 66 using Traits = std::char_traits<CharT>; 67 using AStr = std::basic_string<CharT, Traits, MAlloc>; 68 DisableAllocationGuard g(DisableAllocations); 69 AStr s = p.string<CharT, Traits, MAlloc>(); 70 assert(s == value); 71 assert(MAlloc::alloc_count == 0); 72 assert(MAlloc::outstanding_alloc() == 0); 73 } 74 MAlloc::reset(); 75 { // Other allocator - provided copy 76 using Traits = std::char_traits<CharT>; 77 using AStr = std::basic_string<CharT, Traits, MAlloc>; 78 DisableAllocationGuard g(DisableAllocations); 79 MAlloc a; 80 // don't allow another allocator to be default constructed. 81 MAlloc::disable_default_constructor = true; 82 AStr s = p.string<CharT, Traits, MAlloc>(a); 83 assert(s == value); 84 assert(MAlloc::alloc_count == 0); 85 assert(MAlloc::outstanding_alloc() == 0); 86 } 87 MAlloc::reset(); 88 } 89 90 template <class CharT> 91 void doLongStringTest(MultiStringType const& MS) { 92 using namespace fs; 93 using Ptr = CharT const*; 94 using Str = std::basic_string<CharT>; 95 Ptr value = MS; 96 const path p((const char*)MS); 97 { // Default allocator 98 using Alloc = std::allocator<CharT>; 99 Str s = p.string<CharT>(); 100 assert(s == value); 101 Str s2 = p.string<CharT>(Alloc{}); 102 assert(s2 == value); 103 } 104 using MAlloc = malloc_allocator<CharT>; 105 MAlloc::reset(); 106 #ifdef _WIN32 107 // On Windows, charset conversions cause allocations outside of the 108 // provided allocator, but accessing the native type should work without 109 // extra allocations. 110 bool DisableAllocations = std::is_same<CharT, path::value_type>::value; 111 #else 112 // On other platforms, these methods only use the provided allocator, and 113 // no extra allocations should be done. 114 bool DisableAllocations = true; 115 #endif 116 117 { // Other allocator - default construct 118 using Traits = std::char_traits<CharT>; 119 using AStr = std::basic_string<CharT, Traits, MAlloc>; 120 DisableAllocationGuard g(DisableAllocations); 121 AStr s = p.string<CharT, Traits, MAlloc>(); 122 assert(s == value); 123 assert(MAlloc::alloc_count > 0); 124 assert(MAlloc::outstanding_alloc() == 1); 125 } 126 MAlloc::reset(); 127 { // Other allocator - provided copy 128 using Traits = std::char_traits<CharT>; 129 using AStr = std::basic_string<CharT, Traits, MAlloc>; 130 DisableAllocationGuard g(DisableAllocations); 131 MAlloc a; 132 // don't allow another allocator to be default constructed. 133 MAlloc::disable_default_constructor = true; 134 AStr s = p.string<CharT, Traits, MAlloc>(a); 135 assert(s == value); 136 assert(MAlloc::alloc_count > 0); 137 assert(MAlloc::outstanding_alloc() == 1); 138 } 139 MAlloc::reset(); 140 ///////////////////////////////////////////////////////////////////////////// 141 } 142 143 int main(int, char**) 144 { 145 using namespace fs; 146 { 147 auto const& S = shortString; 148 doShortStringTest<char>(S); 149 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 150 doShortStringTest<wchar_t>(S); 151 #endif 152 doShortStringTest<char16_t>(S); 153 doShortStringTest<char32_t>(S); 154 #if TEST_STD_VER > 17 && defined(__cpp_lib_char8_t) 155 doShortStringTest<char8_t>(S); 156 #endif 157 } 158 { 159 auto const& S = longString; 160 doLongStringTest<char>(S); 161 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 162 doLongStringTest<wchar_t>(S); 163 #endif 164 doLongStringTest<char16_t>(S); 165 doLongStringTest<char32_t>(S); 166 #if TEST_STD_VER > 17 && defined(__cpp_lib_char8_t) 167 doLongStringTest<char8_t>(S); 168 #endif 169 } 170 171 return 0; 172 } 173