23
23
24
24
#include " config.hpp"
25
25
#include " bad_optional_access_exception.hpp"
26
- #include " any.hpp"
27
26
#include " dbc.hpp"
28
27
#include " unused.hpp"
28
+ #include " logger.hpp"
29
+ #include " exception.hpp"
30
+ #include " cassert.hpp"
29
31
30
32
#include < cstddef>
33
+ #include < new>
34
+ #include < algorithm> // swap(), C++98
35
+ #include < utility> // swap(), C++11
31
36
32
37
33
38
namespace cppdevtk {
@@ -127,7 +132,7 @@ class Optional {
127
132
static void UnspecifiedBoolTrue () CPPDEVTK_NOEXCEPT;
128
133
129
134
130
- Any any_ ;
135
+ TValue* pValue_ ;
131
136
};
132
137
133
138
@@ -259,35 +264,40 @@ bool operator>=(const TValue& lhs, const Optional<TValue>& rhs);
259
264
// Inline functions, template definitions
260
265
261
266
template <typename TValue>
262
- inline Optional<TValue>::Optional() CPPDEVTK_NOEXCEPT: any_( ) {}
267
+ inline Optional<TValue>::Optional() CPPDEVTK_NOEXCEPT: pValue_( NULL ) {}
263
268
264
269
template <typename TValue>
265
- inline Optional<TValue>::Optional(NullOptT) CPPDEVTK_NOEXCEPT: any_( ) {}
270
+ inline Optional<TValue>::Optional(NullOptT) CPPDEVTK_NOEXCEPT: pValue_( NULL ) {}
266
271
267
272
template <typename TValue>
268
- inline Optional<TValue>::Optional(const TValue& value): any_( value) {}
273
+ inline Optional<TValue>::Optional(const TValue& value): pValue_( new TValue( value) ) {}
269
274
270
275
template <typename TValue>
271
- inline Optional<TValue>::Optional(bool cond, const TValue& value): any_( ) {
276
+ inline Optional<TValue>::Optional(bool cond, const TValue& value): pValue_( NULL ) {
272
277
if (cond) {
273
- any_ = value;
278
+ pValue_ = new TValue ( value) ;
274
279
}
275
280
}
276
281
277
282
template <typename TValue>
278
283
template <typename TConvertibleValue>
279
- inline Optional<TValue>::Optional(const Optional<TConvertibleValue>& other): any_( ) {
284
+ inline Optional<TValue>::Optional(const Optional<TConvertibleValue>& other): pValue_( NULL ) {
280
285
if (other.HasValue ()) {
281
- const TValue kTmp = *other;
282
- any_ = kTmp ;
286
+ pValue_ = new TValue (*other);
283
287
}
284
288
}
285
289
286
290
template <typename TValue>
287
- inline Optional<TValue>::Optional(const Optional& other): any_(other.any_) {}
291
+ inline Optional<TValue>::Optional(const Optional& other): pValue_(NULL ) {
292
+ if (other.HasValue ()) {
293
+ pValue_ = new TValue (*other);
294
+ }
295
+ }
288
296
289
297
template <typename TValue>
290
- inline Optional<TValue>::~Optional () CPPDEVTK_NOEXCEPT {}
298
+ inline Optional<TValue>::~Optional () CPPDEVTK_NOEXCEPT {
299
+ Reset ();
300
+ }
291
301
292
302
template <typename TValue>
293
303
inline Optional<TValue>& Optional<TValue>::operator =(NullOptT) CPPDEVTK_NOEXCEPT {
@@ -305,36 +315,74 @@ inline Optional<TValue>& Optional<TValue>::operator=(const TValue& value) {
305
315
template <typename TValue>
306
316
template <typename TConvertibleValue>
307
317
inline Optional<TValue>& Optional<TValue>::operator =(const Optional<TConvertibleValue>& other) {
308
- Optional tmp (other);
309
- Swap (tmp);
318
+ if (other.HasValue ()) {
319
+ Optional tmp (other);
320
+ Swap (tmp);
321
+ }
322
+ else {
323
+ Reset ();
324
+ }
310
325
return *this ;
311
326
}
312
327
313
328
template <typename TValue>
314
329
inline Optional<TValue>& Optional<TValue>::operator =(const Optional& other) {
315
- Optional tmp (other);
316
- Swap (tmp);
330
+ if (this != &other) {
331
+ if (other.HasValue ()) {
332
+ Optional tmp (other);
333
+ Swap (tmp);
334
+ }
335
+ else {
336
+ Reset ();
337
+ }
338
+ }
317
339
return *this ;
318
340
}
319
341
320
342
template <typename TValue>
321
343
inline void Optional<TValue>::Swap(Optional& other) CPPDEVTK_NOEXCEPT {
322
- any_.Swap (other.any_ );
344
+ using ::std::swap;
345
+ swap (pValue_, other.pValue_ );
323
346
}
324
347
325
348
template <typename TValue>
326
- inline void Optional<TValue>::Reset() CPPDEVTK_NOEXCEPT {
327
- any_.Reset ();
349
+ void Optional<TValue>::Reset() CPPDEVTK_NOEXCEPT {
350
+ using ::std::terminate;
351
+
352
+
353
+ if (pValue_ == NULL ) {
354
+ return ;
355
+ }
356
+
357
+ try {
358
+ delete pValue_;
359
+ }
360
+ catch (const ::std::exception & exc) {
361
+ CPPDEVTK_LOG_FATAL (" Optional::Reset(): destructor of TValue (" << typeid (TValue).name ()
362
+ << " ) threw exception: " << Exception::GetDetailedInfo (exc));
363
+ CPPDEVTK_ASSERT (0 && " Optional::Reset(): destructor of TValue threw exception" );
364
+ terminate ();
365
+ }
366
+ catch (...) {
367
+ CPPDEVTK_LOG_FATAL (" Optional::Reset(): destructor of TValue (" << typeid (TValue).name ()
368
+ << " ) threw unknown exception" );
369
+ CPPDEVTK_ASSERT (0 && " Optional::Reset(): destructor of TValue threw unknown exception" );
370
+ terminate ();
371
+ }
372
+
373
+ pValue_ = NULL ;
328
374
}
329
375
330
376
template <typename TValue>
331
377
inline void Optional<TValue>::Reset(const TValue& value) {
332
- any_ = value;
378
+ TValue* pTmpValue = new TValue (value);
379
+ Reset ();
380
+ pValue_ = pTmpValue;
333
381
}
334
382
335
383
template <typename TValue>
336
384
inline bool Optional<TValue>::HasValue() const CPPDEVTK_NOEXCEPT {
337
- return any_. HasValue () ;
385
+ return pValue_ != NULL ;
338
386
}
339
387
340
388
template <typename TValue>
@@ -387,14 +435,14 @@ inline const TValue& Optional<TValue>::GetValueOr(const TValue& defaultValue) co
387
435
template <typename TValue>
388
436
TValue* Optional<TValue>::operator ->() {
389
437
CPPDEVTK_DBC_CHECK_PRECONDITION (HasValue ());
390
- return AnyCast<TValue>(&any_) ;
438
+ return pValue_ ;
391
439
}
392
440
393
441
// NOTE: do not inline (uses dbc macro)
394
442
template <typename TValue>
395
443
const TValue* Optional<TValue>::operator ->() const {
396
444
CPPDEVTK_DBC_CHECK_PRECONDITION (HasValue ());
397
- return AnyCast<TValue>(&any_) ;
445
+ return pValue_ ;
398
446
}
399
447
400
448
// NOTE: do not inline (uses dbc macro)
0 commit comments