• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Test the set of C++11 features that Clang provides as an extension in C++03 mode.
10 // The language features we expect are:
11 //
12 // 1. rvalue references (and perfect forwarding)
13 // 2. variadic templates
14 // 3. alias templates
15 // 4. defaulted and deleted functions.
16 // 5. default values for non-type template parameters.
17 //
18 // Some features we don't get and can't be used in extended C++03 mode:
19 //
20 // 1. noexcept and constexpr
21 // 2. Two closing '>' without a space.
22 
23 #include <type_traits>
24 #include <cassert>
25 
26 // Equals delete and default are allowed in minimal C++03 mode.
27 namespace test_eq_delete_and_default {
28 void t1() = delete;
29 struct T2 {
30   T2() = default;
31   T2(T2 const&) = delete;
32 };
33 }
34 
35 namespace alias_templates {
36 template <class T>
37 using X = T;
38 static_assert((std::is_same<X<int>, int>::value), "");
39 }
40 
41 namespace variadics_templates {
42 template <class ...Args>
t1(Args...)43 int t1(Args...) {
44   return sizeof...(Args);
45 }
test()46 void test() {
47   assert(t1() == 0);
48   assert(t1(42) == 1);
49   assert(t1(1, 2, 3) == 3);
50 }
51 }
52 
53 namespace rvalue_references_move_semantics {
54 struct T {
Trvalue_references_move_semantics::T55   T() : moved(0) {}
Trvalue_references_move_semantics::T56   T(T const& other) : moved(other.moved) {}
Trvalue_references_move_semantics::T57   T(T&& other) : moved(other.moved) { ++moved; other.moved = -1; }
58   int moved;
59 };
f(T o,int expect_moved)60 void f(T o, int expect_moved) { assert(o.moved == expect_moved); }
test()61 void test() {
62   {
63     T t;
64     assert(t.moved == 0);
65     T t2(static_cast<T&&>(t));
66     assert(t2.moved == 1);
67     assert(t.moved == -1);
68   }
69   {
70     T t;
71     f(t, 0);
72     f(static_cast<T&&>(t), 1);
73   }
74 }
75 }
76 
77 namespace rvalue_references_perfect_forwarding {
78 template <class Expect, class T>
f(T &&)79 void f(T&&) {
80   static_assert((std::is_same<Expect, T&&>::value), "");
81 }
test()82 void test() {
83   int x = 42;
84   f<int&>(x);
85   f<int&&>(42);
86   f<int&&>(static_cast<int&&>(x));
87 }
88 }
89 
90 namespace default_values_for_nttp {
91 template <int I = 42>
f()92 void f() { assert(I == 42); }
test()93 void test() {
94   f();
95 }
96 }
97 
98 namespace reference_qualified_functions {
99 struct T {
Treference_qualified_functions::T100   T() : lvalue_called(0), rvalue_called(0) {}
fooreference_qualified_functions::T101   void foo() const & { lvalue_called++; }
fooreference_qualified_functions::T102   void foo() && { rvalue_called++; }
103   mutable int lvalue_called;
104   int rvalue_called;
105 };
106 
test()107 void test() {
108   {
109     T t;
110     t.foo();
111     assert(t.lvalue_called == 1);
112     assert(t.rvalue_called == 0);
113   }
114   {
115     T t;
116     static_cast<T&&>(t).foo();
117     assert(t.lvalue_called == 0);
118     assert(t.rvalue_called == 1);
119   }
120 }
121 }
122 
main(int,char **)123 int main(int, char**) {
124   variadics_templates::test();
125   rvalue_references_move_semantics::test();
126   rvalue_references_perfect_forwarding::test();
127   default_values_for_nttp::test();
128   reference_qualified_functions::test();
129   return 0;
130 }
131