diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-09 08:00:36 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-09 08:00:36 +0000 |
commit | 36f5cfe4df32af6c5fe01228102512996f566f9d (patch) | |
tree | 28e2c2562f781f6dbe711d15a00af596b21b9c9b /test/SemaCXX/cxx11-user-defined-literals.cpp | |
parent | 8a26fc15d4647da863f0cca73a203823b01da7e5 (diff) |
Support for raw and template forms of numeric user-defined literals,
and lots of tidying up.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152392 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/cxx11-user-defined-literals.cpp')
-rw-r--r-- | test/SemaCXX/cxx11-user-defined-literals.cpp | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/test/SemaCXX/cxx11-user-defined-literals.cpp b/test/SemaCXX/cxx11-user-defined-literals.cpp index e77e80739c..4cfd4d382b 100644 --- a/test/SemaCXX/cxx11-user-defined-literals.cpp +++ b/test/SemaCXX/cxx11-user-defined-literals.cpp @@ -4,7 +4,7 @@ using size_t = decltype(sizeof(int)); enum class LitKind { Char, WideChar, Char16, Char32, CharStr, WideStr, Char16Str, Char32Str, - Integer, Floating + Integer, Floating, Raw, Template }; constexpr LitKind operator"" _kind(char p) { return LitKind::Char; } constexpr LitKind operator"" _kind(wchar_t p) { return LitKind::WideChar; } @@ -16,6 +16,8 @@ constexpr LitKind operator"" _kind(const char16_t *p, size_t n) { return LitKind constexpr LitKind operator"" _kind(const char32_t *p, size_t n) { return LitKind::Char32Str; } constexpr LitKind operator"" _kind(unsigned long long n) { return LitKind::Integer; } constexpr LitKind operator"" _kind(long double n) { return LitKind::Floating; } +constexpr LitKind operator"" _kind2(const char *p) { return LitKind::Raw; } +template<char ...Cs> constexpr LitKind operator"" _kind3() { return LitKind::Template; } static_assert('x'_kind == LitKind::Char, ""); static_assert(L'x'_kind == LitKind::WideChar, ""); @@ -33,3 +35,94 @@ static_assert(.5954_kind == LitKind::Floating, ""); static_assert(1._kind == LitKind::Floating, ""); static_assert(1.e-2_kind == LitKind::Floating, ""); static_assert(4e6_kind == LitKind::Floating, ""); +static_assert(4e6_kind2 == LitKind::Raw, ""); +static_assert(4e6_kind3 == LitKind::Template, ""); + +constexpr const char *fractional_digits_impl(const char *p) { + return *p == '.' ? p + 1 : *p ? fractional_digits_impl(p + 1) : 0; +} +constexpr const char *operator"" _fractional_digits(const char *p) { + return fractional_digits_impl(p) ?: p; +} +constexpr bool streq(const char *p, const char *q) { + return *p == *q && (!*p || streq(p+1, q+1)); +} + +static_assert(streq(143.97_fractional_digits, "97"), ""); +static_assert(streq(0x786_fractional_digits, "0x786"), ""); +static_assert(streq(.4_fractional_digits, "4"), ""); +static_assert(streq(4._fractional_digits, ""), ""); +static_assert(streq(1e+97_fractional_digits, "1e+97"), ""); +static_assert(streq(0377_fractional_digits, "0377"), ""); +static_assert(streq(0377.5_fractional_digits, "5"), ""); + +int operator"" _ambiguous(char); // expected-note {{candidate}} +namespace N { + void *operator"" _ambiguous(char); // expected-note {{candidate}} +} +using namespace N; +int k = 'x'_ambiguous; // expected-error {{ambiguous}} + +int operator"" _deleted(unsigned long long) = delete; // expected-note {{here}} +int m = 42_deleted; // expected-error {{attempt to use a deleted}} + +namespace Using { + namespace M { + int operator"" _using(char); + } + int k1 = 'x'_using; // expected-error {{no matching literal operator for call to 'operator "" _using'}} + + using M::operator "" _using; + int k2 = 'x'_using; +} + +namespace AmbiguousRawTemplate { + int operator"" _ambig1(const char *); // expected-note {{candidate}} + template<char...> int operator"" _ambig1(); // expected-note {{candidate}} + + int k1 = 123_ambig1; // expected-error {{call to 'operator "" _ambig1' is ambiguous}} + + namespace Inner { + template<char...> int operator"" _ambig2(); // expected-note 3{{candidate}} + } + int operator"" _ambig2(const char *); // expected-note 3{{candidate}} + using Inner::operator"" _ambig2; + + int k2 = 123_ambig2; // expected-error {{call to 'operator "" _ambig2' is ambiguous}} + + namespace N { + using Inner::operator"" _ambig2; + + int k3 = 123_ambig2; // ok + + using AmbiguousRawTemplate::operator"" _ambig2; + + int k4 = 123_ambig2; // expected-error {{ambiguous}} + + namespace M { + + template<char...> int operator"" _ambig2(); + + int k5 = 123_ambig2; // ok + } + + int operator"" _ambig2(unsigned long long); + + int k6 = 123_ambig2; // ok + int k7 = 123._ambig2; // expected-error {{ambiguous}} + } +} + +constexpr unsigned mash(unsigned a) { + return 0x93ae27b5 * ((a >> 13) | a << 19); +} +template<typename=void> constexpr unsigned hash(unsigned a) { return a; } +template<char C, char...Cs> constexpr unsigned hash(unsigned a) { + return hash<Cs...>(mash(a ^ mash(C))); +} +template<typename T, T v> struct constant { constexpr static T value = v; }; +template<char...Cs> constexpr unsigned operator"" _hash() { + return constant<unsigned, hash<Cs...>(0)>::value; +} +static_assert(0x1234_hash == 0x103eff5e, ""); +static_assert(hash<'0', 'x', '1', '2', '3', '4'>(0) == 0x103eff5e, ""); |