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