@@ -29,61 +29,33 @@ namespace llvm {
29
29
class raw_ostream ;
30
30
31
31
namespace optional_detail {
32
- template <typename T> struct OptionalStorageBase {
32
+ // / Storage for any type.
33
+ template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
33
34
AlignedCharArrayUnion<T> storage;
34
35
bool hasVal = false ;
35
36
36
- OptionalStorageBase () = default ;
37
- OptionalStorageBase (const T &y) : hasVal(true ) { new (storage.buffer ) T (y); }
38
- OptionalStorageBase (T &&y) : hasVal(true ) {
39
- new (storage.buffer ) T (std::move (y));
40
- }
41
-
42
- T *getPointer () {
43
- assert (hasVal);
44
- return reinterpret_cast <T *>(storage.buffer );
45
- }
46
- const T *getPointer () const {
47
- assert (hasVal);
48
- return reinterpret_cast <const T *>(storage.buffer );
49
- }
50
- OptionalStorageBase &operator =(T &&y) {
51
- hasVal = true ;
52
- new (this ->storage .buffer ) T (std::move (y));
53
- return *this ;
54
- }
55
- OptionalStorageBase &operator =(const T &y) {
56
- hasVal = true ;
57
- new (this ->storage .buffer ) T (y);
58
- return *this ;
59
- }
60
- void reset () { this ->hasVal = false ; }
61
- };
62
-
63
- // / Storage for any type.
64
- template <typename T, bool = is_trivially_copyable<T>::value>
65
- struct OptionalStorage : OptionalStorageBase<T> {
66
37
OptionalStorage () = default ;
67
38
68
- OptionalStorage (const T &y) : OptionalStorageBase<T>(y) {}
69
- OptionalStorage (const OptionalStorage &O) : OptionalStorageBase<T>() {
70
- this ->hasVal = O.hasVal ;
71
- if (this ->hasVal )
72
- new (this ->storage .buffer ) T (*O.getPointer ());
39
+ OptionalStorage (const T &y) : hasVal(true ) { new (storage.buffer ) T (y); }
40
+ OptionalStorage (const OptionalStorage &O) : hasVal(O.hasVal) {
41
+ if (hasVal)
42
+ new (storage.buffer ) T (*O.getPointer ());
73
43
}
74
- OptionalStorage (T &&y) : OptionalStorageBase<T>(std::move(y)) {}
75
- OptionalStorage (OptionalStorage &&O) : OptionalStorageBase<T>() {
76
- this ->hasVal = O.hasVal ;
44
+ OptionalStorage (T &&y) : hasVal(true ) {
45
+ new (storage.buffer ) T (std::forward<T>(y));
46
+ }
47
+ OptionalStorage (OptionalStorage &&O) : hasVal(O.hasVal) {
77
48
if (O.hasVal ) {
78
- new (this -> storage .buffer ) T (std::move (*O.getPointer ()));
49
+ new (storage.buffer ) T (std::move (*O.getPointer ()));
79
50
}
80
51
}
81
52
82
53
OptionalStorage &operator =(T &&y) {
83
- if (this -> hasVal )
84
- *this -> getPointer () = std::move (y);
54
+ if (hasVal)
55
+ *getPointer () = std::move (y);
85
56
else {
86
- OptionalStorageBase<T>::operator =(std::move (y));
57
+ new (storage.buffer ) T (std::move (y));
58
+ hasVal = true ;
87
59
}
88
60
return *this ;
89
61
}
@@ -102,10 +74,11 @@ struct OptionalStorage : OptionalStorageBase<T> {
102
74
// requirements (notably: the existence of a default ctor) when implemented
103
75
// in that way. Careful SFINAE to avoid such pitfalls would be required.
104
76
OptionalStorage &operator =(const T &y) {
105
- if (this -> hasVal )
106
- *this -> getPointer () = y;
77
+ if (hasVal)
78
+ *getPointer () = y;
107
79
else {
108
- OptionalStorageBase<T>::operator =(y);
80
+ new (storage.buffer ) T (y);
81
+ hasVal = true ;
109
82
}
110
83
return *this ;
111
84
}
@@ -120,30 +93,20 @@ struct OptionalStorage : OptionalStorageBase<T> {
120
93
~OptionalStorage () { reset (); }
121
94
122
95
void reset () {
123
- if (this ->hasVal ) {
124
- (*this ->getPointer ()).~T ();
96
+ if (hasVal) {
97
+ (*getPointer ()).~T ();
98
+ hasVal = false ;
125
99
}
126
- OptionalStorageBase<T>::reset ();
127
100
}
128
- };
129
101
130
- template <typename T> struct OptionalStorage <T, true > : OptionalStorageBase<T> {
131
- OptionalStorage () = default ;
132
- OptionalStorage (const T &y) : OptionalStorageBase<T>(y) {}
133
- OptionalStorage (const OptionalStorage &O) = default ;
134
- OptionalStorage (T &&y) : OptionalStorageBase<T>(std::move(y)) {}
135
- OptionalStorage (OptionalStorage &&O) = default ;
136
- OptionalStorage &operator =(T &&y) {
137
- OptionalStorageBase<T>::operator =(std::move (y));
138
- return *this ;
102
+ T *getPointer () {
103
+ assert (hasVal);
104
+ return reinterpret_cast <T *>(storage.buffer );
139
105
}
140
- OptionalStorage &operator =(OptionalStorage &&O) = default ;
141
- OptionalStorage &operator =(const T &y) {
142
- OptionalStorageBase<T>::operator =(y);
143
- return *this ;
106
+ const T *getPointer () const {
107
+ assert (hasVal);
108
+ return reinterpret_cast <const T *>(storage.buffer );
144
109
}
145
- OptionalStorage &operator =(const OptionalStorage &O) = default ;
146
- ~OptionalStorage () = default ;
147
110
};
148
111
149
112
} // namespace optional_detail
0 commit comments