cxx11-user-defined-literals.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
1// RUN: %clang_cc1 -std=c++11 -verify %s -fms-extensions -triple x86_64-apple-darwin9.0.0 2 3using size_t = decltype(sizeof(int)); 4enum class LitKind { 5 Char, WideChar, Char16, Char32, 6 CharStr, WideStr, Char16Str, Char32Str, 7 Integer, Floating, Raw, Template 8}; 9constexpr LitKind operator"" _kind(char p) { return LitKind::Char; } 10constexpr LitKind operator"" _kind(wchar_t p) { return LitKind::WideChar; } 11constexpr LitKind operator"" _kind(char16_t p) { return LitKind::Char16; } 12constexpr LitKind operator"" _kind(char32_t p) { return LitKind::Char32; } 13constexpr LitKind operator"" _kind(const char *p, size_t n) { return LitKind::CharStr; } 14constexpr LitKind operator"" _kind(const wchar_t *p, size_t n) { return LitKind::WideStr; } 15constexpr LitKind operator"" _kind(const char16_t *p, size_t n) { return LitKind::Char16Str; } 16constexpr LitKind operator"" _kind(const char32_t *p, size_t n) { return LitKind::Char32Str; } 17constexpr LitKind operator"" _kind(unsigned long long n) { return LitKind::Integer; } 18constexpr LitKind operator"" _kind(long double n) { return LitKind::Floating; } 19constexpr LitKind operator"" _kind2(const char *p) { return LitKind::Raw; } 20template<char ...Cs> constexpr LitKind operator"" _kind3() { return LitKind::Template; } 21 22static_assert('x'_kind == LitKind::Char, ""); 23static_assert(L'x'_kind == LitKind::WideChar, ""); 24static_assert(u'x'_kind == LitKind::Char16, ""); 25static_assert(U'x'_kind == LitKind::Char32, ""); 26static_assert("foo"_kind == LitKind::CharStr, ""); 27static_assert(u8"foo"_kind == LitKind::CharStr, ""); 28static_assert(L"foo"_kind == LitKind::WideStr, ""); 29static_assert(u"foo"_kind == LitKind::Char16Str, ""); 30static_assert(U"foo"_kind == LitKind::Char32Str, ""); 31static_assert(194_kind == LitKind::Integer, ""); 32static_assert(0377_kind == LitKind::Integer, ""); 33static_assert(0x5ffc_kind == LitKind::Integer, ""); 34static_assert(.5954_kind == LitKind::Floating, ""); 35static_assert(1._kind == LitKind::Floating, ""); 36static_assert(1.e-2_kind == LitKind::Floating, ""); 37static_assert(4e6_kind == LitKind::Floating, ""); 38static_assert(4e6_kind2 == LitKind::Raw, ""); 39static_assert(4e6_kind3 == LitKind::Template, ""); 40 41constexpr const char *fractional_digits_impl(const char *p) { 42 return *p == '.' ? p + 1 : *p ? fractional_digits_impl(p + 1) : 0; 43} 44constexpr const char *operator"" _fractional_digits(const char *p) { 45 return fractional_digits_impl(p) ?: p; 46} 47constexpr bool streq(const char *p, const char *q) { 48 return *p == *q && (!*p || streq(p+1, q+1)); 49} 50 51static_assert(streq(143.97_fractional_digits, "97"), ""); 52static_assert(streq(0x786_fractional_digits, "0x786"), ""); 53static_assert(streq(.4_fractional_digits, "4"), ""); 54static_assert(streq(4._fractional_digits, ""), ""); 55static_assert(streq(1e+97_fractional_digits, "1e+97"), ""); 56static_assert(streq(0377_fractional_digits, "0377"), ""); 57static_assert(streq(0377.5_fractional_digits, "5"), ""); 58 59int operator"" _ambiguous(char); // expected-note {{candidate}} 60namespace N { 61 void *operator"" _ambiguous(char); // expected-note {{candidate}} 62} 63using namespace N; 64int k = 'x'_ambiguous; // expected-error {{ambiguous}} 65 66int operator"" _deleted(unsigned long long) = delete; // expected-note {{here}} 67int m = 42_deleted; // expected-error {{attempt to use a deleted}} 68 69namespace Using { 70 namespace M { 71 int operator"" _using(char); 72 } 73 int k1 = 'x'_using; // expected-error {{no matching literal operator for call to 'operator "" _using'}} 74 75 using M::operator "" _using; 76 int k2 = 'x'_using; 77} 78 79namespace AmbiguousRawTemplate { 80 int operator"" _ambig1(const char *); // expected-note {{candidate}} 81 template<char...> int operator"" _ambig1(); // expected-note {{candidate}} 82 83 int k1 = 123_ambig1; // expected-error {{call to 'operator "" _ambig1' is ambiguous}} 84 85 namespace Inner { 86 template<char...> int operator"" _ambig2(); // expected-note 3{{candidate}} 87 } 88 int operator"" _ambig2(const char *); // expected-note 3{{candidate}} 89 using Inner::operator"" _ambig2; 90 91 int k2 = 123_ambig2; // expected-error {{call to 'operator "" _ambig2' is ambiguous}} 92 93 namespace N { 94 using Inner::operator"" _ambig2; 95 96 int k3 = 123_ambig2; // ok 97 98 using AmbiguousRawTemplate::operator"" _ambig2; 99 100 int k4 = 123_ambig2; // expected-error {{ambiguous}} 101 102 namespace M { 103 104 template<char...> int operator"" _ambig2(); 105 106 int k5 = 123_ambig2; // ok 107 } 108 109 int operator"" _ambig2(unsigned long long); 110 111 int k6 = 123_ambig2; // ok 112 int k7 = 123._ambig2; // expected-error {{ambiguous}} 113 } 114} 115 116constexpr unsigned mash(unsigned a) { 117 return 0x93ae27b5 * ((a >> 13) | a << 19); 118} 119template<typename=void> constexpr unsigned hash(unsigned a) { return a; } 120template<char C, char...Cs> constexpr unsigned hash(unsigned a) { 121 return hash<Cs...>(mash(a ^ mash(C))); 122} 123template<typename T, T v> struct constant { constexpr static T value = v; }; 124template<char...Cs> constexpr unsigned operator"" _hash() { 125 return constant<unsigned, hash<Cs...>(0)>::value; 126} 127static_assert(0x1234_hash == 0x103eff5e, ""); 128static_assert(hash<'0', 'x', '1', '2', '3', '4'>(0) == 0x103eff5e, ""); 129 130// Functions and literal suffixes go in separate namespaces. 131namespace Namespace { 132 template<char...> int operator"" _x(); 133 int k = _x(); // expected-error {{undeclared identifier '_x'}} 134 135 int _y(unsigned long long); 136 int k2 = 123_y; // expected-error {{no matching literal operator for call to 'operator "" _y'}} 137} 138 139namespace PR14950 { 140 template<...> // expected-error {{expected template parameter}} 141 int operator"" _b(); // expected-error {{no function template matches function template specialization}} 142 int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator "" _b'}} 143} 144 145namespace bad_names { 146 template<char...> int operator""_x(); 147 148 template<typename T> void f() { 149 class T:: // expected-error {{anonymous class}} expected-warning {{does not declare anything}} 150 operator // expected-error {{expected identifier}} 151 ""_q<'a'>; 152 153 T::template operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}} 154 T::template operator""_q<'a'>::X; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}} 155 T::operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}} 156 typename T::template operator""_q<'a'> a; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}} 157 typename T::operator""_q(""); // expected-error +{{}} expected-note {{to match}} 158 T::operator""_q(""); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} 159 160 bad_names::operator""_x<'a', 'b', 'c'>(); 161 }; 162 163 struct S {}; 164 void g() { 165 S::operator""_q(); // expected-error {{non-namespace scope 'S::' cannot have a literal operator member}} 166 } 167} 168