xref: /llvm-project/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp (revision 425620ccdd47e56b59512913cdc71e116f951e4e)
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 // <string>
10 // UNSUPPORTED: c++03, c++11, c++14
11 
12 // XFAIL: LIBCXX-AIX-FIXME
13 
14 // template<class InputIterator,
15 //      class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
16 //  basic_string(InputIterator, InputIterator, Allocator = Allocator())
17 //    -> basic_string<typename iterator_traits<InputIterator>::value_type,
18 //                 char_traits<typename iterator_traits<InputIterator>::value_type>,
19 //                 Allocator>; // constexpr since C++20
20 //
21 //  The deduction guide shall not participate in overload resolution if InputIterator
22 //  is a type that does not qualify as an input iterator, or if Allocator is a type
23 //  that does not qualify as an allocator.
24 
25 #include <cassert>
26 #include <cstddef>
27 #include <iterator>
28 #include <string>
29 #include <type_traits>
30 
31 #include "test_macros.h"
32 #include "test_allocator.h"
33 #include "min_allocator.h"
34 
35 class NotAnIterator {};
36 using NotAnInputIterator = std::back_insert_iterator<std::basic_string<char16_t>>;
37 
38 template <typename T>
39 struct NotAnAllocator { typedef T value_type; };
40 
41 template <class Iter, class Alloc, class = void>
42 struct CanDeduce : std::false_type { };
43 
44 template <class Iter, class Alloc>
45 struct CanDeduce<Iter, Alloc, decltype((void)
46   std::basic_string{std::declval<Iter>(), std::declval<Iter>(), std::declval<Alloc>()}
47 )> : std::true_type { };
48 
49 static_assert( CanDeduce<int*, std::allocator<int>>::value);
50 static_assert(!CanDeduce<NotAnIterator, std::allocator<char>>::value);
51 static_assert(!CanDeduce<NotAnInputIterator, std::allocator<char16_t>>::value);
52 static_assert(!CanDeduce<wchar_t const*, NotAnAllocator<wchar_t>>::value);
53 
54 TEST_CONSTEXPR_CXX20 bool test() {
55   {
56     const char* s = "12345678901234";
57     std::basic_string s1(s, s+10);  // Can't use {} here
58     using S = decltype(s1); // what type did we get?
59     static_assert(std::is_same_v<S::value_type,                      char>,  "");
60     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char>>, "");
61     static_assert(std::is_same_v<S::allocator_type,   std::allocator<char>>, "");
62     assert(s1.size() == 10);
63     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
64   }
65   {
66     const char* s = "12345678901234";
67     std::basic_string s1{s, s+10, std::allocator<char>{}};
68     using S = decltype(s1); // what type did we get?
69     static_assert(std::is_same_v<S::value_type,                      char>,  "");
70     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char>>, "");
71     static_assert(std::is_same_v<S::allocator_type,   std::allocator<char>>, "");
72     assert(s1.size() == 10);
73     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
74   }
75   {
76     const wchar_t* s = L"12345678901234";
77     std::basic_string s1{s, s+10, test_allocator<wchar_t>{}};
78     using S = decltype(s1); // what type did we get?
79     static_assert(std::is_same_v<S::value_type,                      wchar_t>,  "");
80     static_assert(std::is_same_v<S::traits_type,    std::char_traits<wchar_t>>, "");
81     static_assert(std::is_same_v<S::allocator_type,   test_allocator<wchar_t>>, "");
82     assert(s1.size() == 10);
83     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
84   }
85   {
86     const char16_t* s = u"12345678901234";
87     std::basic_string s1{s, s+10, min_allocator<char16_t>{}};
88     using S = decltype(s1); // what type did we get?
89     static_assert(std::is_same_v<S::value_type,                      char16_t>,  "");
90     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char16_t>>, "");
91     static_assert(std::is_same_v<S::allocator_type,    min_allocator<char16_t>>, "");
92     assert(s1.size() == 10);
93     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
94   }
95   {
96     const char32_t* s = U"12345678901234";
97     std::basic_string s1{s, s+10, explicit_allocator<char32_t>{}};
98     using S = decltype(s1); // what type did we get?
99     static_assert(std::is_same_v<S::value_type,                        char32_t>,  "");
100     static_assert(std::is_same_v<S::traits_type,      std::char_traits<char32_t>>, "");
101     static_assert(std::is_same_v<S::allocator_type, explicit_allocator<char32_t>>, "");
102     assert(s1.size() == 10);
103     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
104   }
105 
106   return true;
107 }
108 
109 int main(int, char**)
110 {
111   test();
112 #if TEST_STD_VER > 17
113   static_assert(test());
114 #endif
115 
116   return 0;
117 }
118