Skip to content

Commit c351aee

Browse files
committedDec 12, 2017
simplified optional
1 parent 794fc80 commit c351aee

File tree

4 files changed

+73
-24
lines changed

4 files changed

+73
-24
lines changed
 

‎doc/cppdevtk_api.chm

-3.1 KB
Binary file not shown.

‎include/cppdevtk/base/any.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace base {
3939

4040
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4141
/// A type-safe container for single values of any \c CopyConstructible type with no-throw destructor.
42+
/// \attention Arrays are not supported!
4243
/// \note C++ 17 std says that implementations are encouraged to avoid dynamic allocations for small objects.
4344
/// Currently our implementation always uses dynamic allocations.
4445
/// \sa

‎include/cppdevtk/base/optional.hpp

+71-23
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@
2323

2424
#include "config.hpp"
2525
#include "bad_optional_access_exception.hpp"
26-
#include "any.hpp"
2726
#include "dbc.hpp"
2827
#include "unused.hpp"
28+
#include "logger.hpp"
29+
#include "exception.hpp"
30+
#include "cassert.hpp"
2931

3032
#include <cstddef>
33+
#include <new>
34+
#include <algorithm> // swap(), C++98
35+
#include <utility> // swap(), C++11
3136

3237

3338
namespace cppdevtk {
@@ -127,7 +132,7 @@ class Optional {
127132
static void UnspecifiedBoolTrue() CPPDEVTK_NOEXCEPT;
128133

129134

130-
Any any_;
135+
TValue* pValue_;
131136
};
132137

133138

@@ -259,35 +264,40 @@ bool operator>=(const TValue& lhs, const Optional<TValue>& rhs);
259264
// Inline functions, template definitions
260265

261266
template <typename TValue>
262-
inline Optional<TValue>::Optional() CPPDEVTK_NOEXCEPT: any_() {}
267+
inline Optional<TValue>::Optional() CPPDEVTK_NOEXCEPT: pValue_(NULL) {}
263268

264269
template <typename TValue>
265-
inline Optional<TValue>::Optional(NullOptT) CPPDEVTK_NOEXCEPT: any_() {}
270+
inline Optional<TValue>::Optional(NullOptT) CPPDEVTK_NOEXCEPT: pValue_(NULL) {}
266271

267272
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)) {}
269274

270275
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) {
272277
if (cond) {
273-
any_ = value;
278+
pValue_ = new TValue(value);
274279
}
275280
}
276281

277282
template <typename TValue>
278283
template <typename TConvertibleValue>
279-
inline Optional<TValue>::Optional(const Optional<TConvertibleValue>& other): any_() {
284+
inline Optional<TValue>::Optional(const Optional<TConvertibleValue>& other): pValue_(NULL) {
280285
if (other.HasValue()) {
281-
const TValue kTmp = *other;
282-
any_ = kTmp;
286+
pValue_ = new TValue(*other);
283287
}
284288
}
285289

286290
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+
}
288296

289297
template <typename TValue>
290-
inline Optional<TValue>::~Optional() CPPDEVTK_NOEXCEPT {}
298+
inline Optional<TValue>::~Optional() CPPDEVTK_NOEXCEPT {
299+
Reset();
300+
}
291301

292302
template <typename TValue>
293303
inline Optional<TValue>& Optional<TValue>::operator=(NullOptT) CPPDEVTK_NOEXCEPT {
@@ -305,36 +315,74 @@ inline Optional<TValue>& Optional<TValue>::operator=(const TValue& value) {
305315
template <typename TValue>
306316
template <typename TConvertibleValue>
307317
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+
}
310325
return *this;
311326
}
312327

313328
template <typename TValue>
314329
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+
}
317339
return *this;
318340
}
319341

320342
template <typename TValue>
321343
inline void Optional<TValue>::Swap(Optional& other) CPPDEVTK_NOEXCEPT {
322-
any_.Swap(other.any_);
344+
using ::std::swap;
345+
swap(pValue_, other.pValue_);
323346
}
324347

325348
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;
328374
}
329375

330376
template <typename TValue>
331377
inline void Optional<TValue>::Reset(const TValue& value) {
332-
any_ = value;
378+
TValue* pTmpValue = new TValue(value);
379+
Reset();
380+
pValue_ = pTmpValue;
333381
}
334382

335383
template <typename TValue>
336384
inline bool Optional<TValue>::HasValue() const CPPDEVTK_NOEXCEPT {
337-
return any_.HasValue();
385+
return pValue_ != NULL;
338386
}
339387

340388
template <typename TValue>
@@ -387,14 +435,14 @@ inline const TValue& Optional<TValue>::GetValueOr(const TValue& defaultValue) co
387435
template <typename TValue>
388436
TValue* Optional<TValue>::operator->() {
389437
CPPDEVTK_DBC_CHECK_PRECONDITION(HasValue());
390-
return AnyCast<TValue>(&any_);
438+
return pValue_;
391439
}
392440

393441
// NOTE: do not inline (uses dbc macro)
394442
template <typename TValue>
395443
const TValue* Optional<TValue>::operator->() const {
396444
CPPDEVTK_DBC_CHECK_PRECONDITION(HasValue());
397-
return AnyCast<TValue>(&any_);
445+
return pValue_;
398446
}
399447

400448
// NOTE: do not inline (uses dbc macro)

‎test/test_base/boost_test_optional/optional_test_fail2.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ void test_no_implicit_conversion()
2727

2828
// You can compare against 0 or against another optional<>,
2929
// but not against another value
30-
if ( opt == 1 ) {};
30+
if ( opt == 1 ) { ; }
3131
}
3232
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.