blob: 0e4add84955e9ded77a10c908043249fabfcbccb (
about) (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct non_trivial {
non_trivial();
non_trivial(const non_trivial&);
non_trivial& operator = (const non_trivial&);
~non_trivial();
};
union u {
non_trivial nt;
};
union u2 {
non_trivial nt;
int k;
u2(int k) : k(k) {}
u2() : nt() {}
};
union static_data_member {
static int i;
};
int static_data_member::i;
union bad {
int &i; // expected-error {{union member 'i' has reference type 'int &'}}
};
struct s {
union {
non_trivial nt;
};
};
// Don't crash on this.
struct TemplateCtor { template<typename T> TemplateCtor(T); };
union TemplateCtorMember { TemplateCtor s; };
template<typename T> struct remove_ref { typedef T type; };
template<typename T> struct remove_ref<T&> { typedef T type; };
template<typename T> struct remove_ref<T&&> { typedef T type; };
template<typename T> T &&forward(typename remove_ref<T>::type &&t);
template<typename T> T &&forward(typename remove_ref<T>::type &t);
template<typename T> typename remove_ref<T>::type &&move(T &&t);
using size_t = decltype(sizeof(int));
void *operator new(size_t, void *p) noexcept { return p; }
namespace disabled_dtor {
template<typename T>
union disable_dtor {
T val;
template<typename...U>
disable_dtor(U &&...u) : val(forward<U>(u)...) {}
~disable_dtor() {}
};
struct deleted_dtor {
deleted_dtor(int n, char c) : n(n), c(c) {}
int n;
char c;
~deleted_dtor() = delete;
};
disable_dtor<deleted_dtor> dd(4, 'x');
}
namespace optional {
template<typename T> struct optional {
bool has;
union { T value; };
optional() : has(false) {}
template<typename...U>
optional(U &&...u) : has(true), value(forward<U>(u)...) {}
optional(const optional &o) : has(o.has) {
if (has) new (&value) T(o.value);
}
optional(optional &&o) : has(o.has) {
if (has) new (&value) T(move(o.value));
}
optional &operator=(const optional &o) {
if (has) {
if (o.has)
value = o.value;
else
value.~T();
} else if (o.has) {
new (&value) T(o.value);
}
has = o.has;
}
optional &operator=(optional &&o) {
if (has) {
if (o.has)
value = move(o.value);
else
value.~T();
} else if (o.has) {
new (&value) T(move(o.value));
}
has = o.has;
}
~optional() {
if (has)
value.~T();
}
explicit operator bool() const { return has; }
T &operator*() const { return value; }
};
optional<non_trivial> o1;
optional<non_trivial> o2{non_trivial()};
optional<non_trivial> o3{*o2};
void f() {
if (o2)
o1 = o2;
o2 = optional<non_trivial>();
}
}
|