12a81d304SMarshall Clow //===----------------------------------------------------------------------===//
22a81d304SMarshall Clow //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62a81d304SMarshall Clow //
72a81d304SMarshall Clow //===----------------------------------------------------------------------===//
82a81d304SMarshall Clow 
92a81d304SMarshall Clow // <string>
1031cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
112a81d304SMarshall Clow 
122a81d304SMarshall Clow // template<class InputIterator,
132a81d304SMarshall Clow //      class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
142a81d304SMarshall Clow //  basic_string(InputIterator, InputIterator, Allocator = Allocator())
152a81d304SMarshall Clow //    -> basic_string<typename iterator_traits<InputIterator>::value_type,
162a81d304SMarshall Clow //                 char_traits<typename iterator_traits<InputIterator>::value_type>,
17*425620ccSNikolas Klauser //                 Allocator>; // constexpr since C++20
182a81d304SMarshall Clow //
192a81d304SMarshall Clow //  The deduction guide shall not participate in overload resolution if InputIterator
202a81d304SMarshall Clow //  is a type that does not qualify as an input iterator, or if Allocator is a type
212a81d304SMarshall Clow //  that does not qualify as an allocator.
222a81d304SMarshall Clow 
232a81d304SMarshall Clow #include <cassert>
242a81d304SMarshall Clow #include <cstddef>
258ec49997SLouis Dionne #include <iterator>
268ec49997SLouis Dionne #include <string>
278ec49997SLouis Dionne #include <type_traits>
282a81d304SMarshall Clow 
292a81d304SMarshall Clow #include "test_macros.h"
302a81d304SMarshall Clow #include "test_allocator.h"
312a81d304SMarshall Clow #include "min_allocator.h"
322a81d304SMarshall Clow 
338ec49997SLouis Dionne class NotAnIterator {};
348ec49997SLouis Dionne using NotAnInputIterator = std::back_insert_iterator<std::basic_string<char16_t>>;
358ec49997SLouis Dionne 
368ec49997SLouis Dionne template <typename T>
378ec49997SLouis Dionne struct NotAnAllocator { typedef T value_type; };
388ec49997SLouis Dionne 
398ec49997SLouis Dionne template <class Iter, class Alloc, class = void>
408ec49997SLouis Dionne struct CanDeduce : std::false_type { };
418ec49997SLouis Dionne 
428ec49997SLouis Dionne template <class Iter, class Alloc>
438ec49997SLouis Dionne struct CanDeduce<Iter, Alloc, decltype((void)
448ec49997SLouis Dionne   std::basic_string{std::declval<Iter>(), std::declval<Iter>(), std::declval<Alloc>()}
458ec49997SLouis Dionne )> : std::true_type { };
468ec49997SLouis Dionne 
478ec49997SLouis Dionne static_assert( CanDeduce<int*, std::allocator<int>>::value);
488ec49997SLouis Dionne static_assert(!CanDeduce<NotAnIterator, std::allocator<char>>::value);
498ec49997SLouis Dionne static_assert(!CanDeduce<NotAnInputIterator, std::allocator<char16_t>>::value);
508ec49997SLouis Dionne static_assert(!CanDeduce<wchar_t const*, NotAnAllocator<wchar_t>>::value);
518ec49997SLouis Dionne 
test()52*425620ccSNikolas Klauser TEST_CONSTEXPR_CXX20 bool test() {
532a81d304SMarshall Clow   {
542a81d304SMarshall Clow     const char* s = "12345678901234";
553c839373SMarshall Clow     std::basic_string s1(s, s+10);  // Can't use {} here
563c839373SMarshall Clow     using S = decltype(s1); // what type did we get?
573c839373SMarshall Clow     static_assert(std::is_same_v<S::value_type,                      char>,  "");
583c839373SMarshall Clow     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char>>, "");
593c839373SMarshall Clow     static_assert(std::is_same_v<S::allocator_type,   std::allocator<char>>, "");
603c839373SMarshall Clow     assert(s1.size() == 10);
613c839373SMarshall Clow     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
623c839373SMarshall Clow   }
633c839373SMarshall Clow   {
643c839373SMarshall Clow     const char* s = "12345678901234";
652a81d304SMarshall Clow     std::basic_string s1{s, s+10, std::allocator<char>{}};
662a81d304SMarshall Clow     using S = decltype(s1); // what type did we get?
672a81d304SMarshall Clow     static_assert(std::is_same_v<S::value_type,                      char>,  "");
682a81d304SMarshall Clow     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char>>, "");
692a81d304SMarshall Clow     static_assert(std::is_same_v<S::allocator_type,   std::allocator<char>>, "");
702a81d304SMarshall Clow     assert(s1.size() == 10);
712a81d304SMarshall Clow     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
722a81d304SMarshall Clow   }
732a81d304SMarshall Clow   {
742a81d304SMarshall Clow     const wchar_t* s = L"12345678901234";
752a81d304SMarshall Clow     std::basic_string s1{s, s+10, test_allocator<wchar_t>{}};
762a81d304SMarshall Clow     using S = decltype(s1); // what type did we get?
772a81d304SMarshall Clow     static_assert(std::is_same_v<S::value_type,                      wchar_t>,  "");
782a81d304SMarshall Clow     static_assert(std::is_same_v<S::traits_type,    std::char_traits<wchar_t>>, "");
792a81d304SMarshall Clow     static_assert(std::is_same_v<S::allocator_type,   test_allocator<wchar_t>>, "");
802a81d304SMarshall Clow     assert(s1.size() == 10);
812a81d304SMarshall Clow     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
822a81d304SMarshall Clow   }
832a81d304SMarshall Clow   {
842a81d304SMarshall Clow     const char16_t* s = u"12345678901234";
852a81d304SMarshall Clow     std::basic_string s1{s, s+10, min_allocator<char16_t>{}};
862a81d304SMarshall Clow     using S = decltype(s1); // what type did we get?
872a81d304SMarshall Clow     static_assert(std::is_same_v<S::value_type,                      char16_t>,  "");
882a81d304SMarshall Clow     static_assert(std::is_same_v<S::traits_type,    std::char_traits<char16_t>>, "");
892a81d304SMarshall Clow     static_assert(std::is_same_v<S::allocator_type,    min_allocator<char16_t>>, "");
902a81d304SMarshall Clow     assert(s1.size() == 10);
912a81d304SMarshall Clow     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
922a81d304SMarshall Clow   }
932a81d304SMarshall Clow   {
942a81d304SMarshall Clow     const char32_t* s = U"12345678901234";
952a81d304SMarshall Clow     std::basic_string s1{s, s+10, explicit_allocator<char32_t>{}};
962a81d304SMarshall Clow     using S = decltype(s1); // what type did we get?
972a81d304SMarshall Clow     static_assert(std::is_same_v<S::value_type,                        char32_t>,  "");
982a81d304SMarshall Clow     static_assert(std::is_same_v<S::traits_type,      std::char_traits<char32_t>>, "");
992a81d304SMarshall Clow     static_assert(std::is_same_v<S::allocator_type, explicit_allocator<char32_t>>, "");
1002a81d304SMarshall Clow     assert(s1.size() == 10);
1012a81d304SMarshall Clow     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
1022a81d304SMarshall Clow   }
1032df59c50SJF Bastien 
104e85018b7SNikolas Klauser   return true;
105e85018b7SNikolas Klauser }
106e85018b7SNikolas Klauser 
main(int,char **)107e85018b7SNikolas Klauser int main(int, char**)
108e85018b7SNikolas Klauser {
1098ec49997SLouis Dionne   test();
1108ec49997SLouis Dionne #if TEST_STD_VER > 17
111*425620ccSNikolas Klauser   static_assert(test());
1128ec49997SLouis Dionne #endif
113e85018b7SNikolas Klauser 
1142df59c50SJF Bastien   return 0;
1152a81d304SMarshall Clow }
116