@@ -103,13 +103,13 @@ class variant_base<Size, Align, First, Rest...>
103
103
variant_base (const First &val)
104
104
: m_owns(true )
105
105
{
106
- new (&m_storage) First (val);
106
+ set (val);
107
107
}
108
108
109
109
variant_base (First &&val)
110
110
: m_owns(true )
111
111
{
112
- new (&m_storage) First (std::move (val));
112
+ set (std::move (val));
113
113
}
114
114
115
115
template <typename T>
@@ -132,17 +132,24 @@ class variant_base<Size, Align, First, Rest...>
132
132
{
133
133
if (!other.m_owns )
134
134
return ;
135
- *reinterpret_cast <First*>(&m_storage)
136
- = *other.get ((First*)nullptr );
135
+ set (*other.get ((First*)nullptr ));
137
136
}
138
137
139
138
variant_base (variant_base &&other)
140
139
: Base(std::move(other))
141
140
{
142
141
if (!other.m_owns )
143
142
return ;
144
- *reinterpret_cast <First*>(&m_storage)
145
- = std::move (*other.get ((First*)nullptr ));
143
+ set (std::move (*other.get ((First*)nullptr )));
144
+ }
145
+
146
+ variant_base& operator =(const variant_base &other)
147
+ {
148
+ if (other.m_owns )
149
+ set (*other.get ((First*)nullptr ));
150
+ else
151
+ Base::operator =(static_cast <const Base&>(other));
152
+ return *this ;
146
153
}
147
154
148
155
void set (const First &val)
@@ -264,6 +271,15 @@ class variant_base<Size, Align>
264
271
{
265
272
assert (false );
266
273
}
274
+
275
+ void operator =(const variant_base&)
276
+ {}
277
+
278
+ template <typename T>
279
+ void operator =(const T&)
280
+ {
281
+ assert (false );
282
+ }
267
283
};
268
284
269
285
} // detail
@@ -277,6 +293,14 @@ class variant
277
293
{
278
294
typedef detail::variant_base<0 ,0 ,Types...> Base;
279
295
296
+ protected:
297
+
298
+ template <typename T>
299
+ const T* get_ptr () const
300
+ {
301
+ return Base::get ((const T*)nullptr );
302
+ }
303
+
280
304
public:
281
305
282
306
variant () {}
@@ -299,6 +323,12 @@ class variant
299
323
: Base(std::move(val))
300
324
{}
301
325
326
+ variant& operator =(const variant &other)
327
+ {
328
+ Base::operator =(static_cast <const Base&>(other));
329
+ return *this ;
330
+ }
331
+
302
332
template <typename T>
303
333
variant& operator =(T&& val)
304
334
{
@@ -334,6 +364,60 @@ class variant
334
364
{
335
365
return *Base::get ((const T*)nullptr );
336
366
}
367
+
368
+ template <typename T>
369
+ const T* operator ->() const
370
+ {
371
+ return get_ptr<T>();
372
+ }
373
+ };
374
+
375
+
376
+ /*
377
+ Object x of type opt<T> can be either empty or hold value of type T. In
378
+ the latter case reference to stored object can be obtained with x.get()
379
+ and stored object's methods can be called via operator->: x->method().
380
+ */
381
+
382
+ template < typename Type >
383
+ class opt
384
+ : private variant<Type>
385
+ {
386
+ typedef variant<Type> Base;
387
+
388
+ public:
389
+
390
+ opt ()
391
+ {}
392
+
393
+ opt (const opt &other)
394
+ : Base(static_cast <const Base&>(other))
395
+ {}
396
+
397
+ template <typename ... T>
398
+ opt (T... args)
399
+ : Base(Type(args...))
400
+ {}
401
+
402
+ opt& operator =(const opt &other)
403
+ {
404
+ Base::operator =(static_cast <const Base&>(other));
405
+ return *this ;
406
+ }
407
+
408
+ opt& operator =(const Type& val)
409
+ {
410
+ Base::operator =(val);
411
+ return *this ;
412
+ }
413
+
414
+ using Base::operator bool ;
415
+ using Base::get;
416
+
417
+ const Type* operator ->() const
418
+ {
419
+ return Base::template get_ptr<Type>();
420
+ }
337
421
};
338
422
339
423
0 commit comments