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 // GCC 5 does not evaluate static assertions dependent on a template parameter.
10 // UNSUPPORTED: gcc-5
11 
12 // UNSUPPORTED: c++03
13 
14 // <string>
15 
16 // Test that hash specializations for <string> require "char_traits<_CharT>" not just any "_Trait".
17 
18 #include <string>
19 
20 template <class _CharT>
21 struct trait // copied from <__string>
22 {
23     typedef _CharT         char_type;
24     typedef int            int_type;
25     typedef std::streamoff off_type;
26     typedef std::streampos pos_type;
27     typedef std::mbstate_t state_type;
28 
assigntrait29     static inline void assign(char_type& __c1, const char_type& __c2) {
30         __c1 = __c2;
31     }
eqtrait32     static inline bool eq(char_type __c1, char_type __c2) { return __c1 == __c2; }
lttrait33     static inline bool lt(char_type __c1, char_type __c2) { return __c1 < __c2; }
34 
35     static int compare(const char_type* __s1, const char_type* __s2, size_t __n);
36     static size_t length(const char_type* __s);
37     static const char_type* find(const char_type* __s, size_t __n,
38                                  const char_type& __a);
39 
40     static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
41     static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
42     static char_type* assign(char_type* __s, size_t __n, char_type __a);
43 
not_eoftrait44     static inline int_type not_eof(int_type __c) {
45         return eq_int_type(__c, eof()) ? ~eof() : __c;
46     }
to_char_typetrait47     static inline char_type to_char_type(int_type __c) { return char_type(__c); }
to_int_typetrait48     static inline int_type to_int_type(char_type __c) { return int_type(__c); }
eq_int_typetrait49     static inline bool eq_int_type(int_type __c1, int_type __c2) {
50         return __c1 == __c2;
51     }
eoftrait52     static inline int_type eof() { return int_type(EOF); }
53 };
54 
55 template <class CharT>
test()56 void test() {
57     typedef std::basic_string<CharT, trait<CharT> > str_t;
58     std::hash<str_t>
59         h; // expected-error-re 4 {{{{call to implicitly-deleted default constructor of 'std::hash<str_t>'|implicit instantiation of undefined template}} {{.+}}}}}}
60     (void)h;
61 }
62 
main(int,char **)63 int main(int, char**) {
64     test<char>();
65     test<wchar_t>();
66     test<char16_t>();
67     test<char32_t>();
68 
69     return 0;
70 }
71