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>
doShortStringTest(MultiStringType const & MS)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>
doLongStringTest(MultiStringType const & MS)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
main(int,char **)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