aboutsummaryrefslogtreecommitdiff
path: root/libbutl/optional.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-06-27 14:55:27 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-06-27 14:55:27 +0200
commit524322f78775dc14c61d33cbdb719b8330c2ad5c (patch)
tree4a101a1359025b916ca01d33339197c78bbb1872 /libbutl/optional.ixx
parent0071c616f02de72f8a6ed82448a7b9e8a6c9a40c (diff)
Reimplement optional not to require default-constructible value types
Diffstat (limited to 'libbutl/optional.ixx')
-rw-r--r--libbutl/optional.ixx210
1 files changed, 210 insertions, 0 deletions
diff --git a/libbutl/optional.ixx b/libbutl/optional.ixx
new file mode 100644
index 0000000..2c40d30
--- /dev/null
+++ b/libbutl/optional.ixx
@@ -0,0 +1,210 @@
+// file : libbutl/optional.ixx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+namespace butl
+{
+ namespace details
+ {
+ // optional_data<T, false>
+ //
+
+ template <typename T>
+ inline optional_data<T, false>& optional_data<T, false>::
+ operator= (nullopt_t)
+ {
+ if (v_)
+ {
+ d_.~T ();
+ v_ = false;
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, false>& optional_data<T, false>::
+ operator= (const T& v)
+ {
+ if (v_)
+ {
+ d_.~T ();
+ v_ = false;
+ }
+
+ new (&d_) T (v);
+ v_ = true;
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, false>& optional_data<T, false>::
+ operator= (T&& v)
+ {
+ if (v_)
+ {
+ d_.~T ();
+ v_ = false;
+ }
+
+ new (&d_) T (std::move (v));
+ v_ = true;
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, false>::
+ optional_data (const optional_data& o)
+ : v_ (o.v_)
+ {
+ if (v_)
+ new (&d_) T (o.d_);
+ }
+
+ template <typename T>
+ inline optional_data<T, false>::
+ optional_data (optional_data&& o)
+ : v_ (o.v_)
+ {
+ if (v_)
+ new (&d_) T (std::move (o.d_));
+ }
+
+ template <typename T>
+ inline optional_data<T, false>& optional_data<T, false>::
+ operator= (const optional_data& o)
+ {
+ if (v_)
+ {
+ d_.~T ();
+ v_ = false;
+ }
+
+ if (o.v_)
+ {
+ new (&d_) T (o.d_);
+ v_ = true;
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, false>& optional_data<T, false>::
+ operator= (optional_data&& o)
+ {
+ if (v_)
+ {
+ d_.~T ();
+ v_ = false;
+ }
+
+ if (o.v_)
+ {
+ new (&d_) T (std::move (o.d_));
+ v_ = true;
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, false>::
+ ~optional_data ()
+ {
+ if (v_)
+ d_.~T ();
+ }
+
+ // optional_data<T, true>
+ //
+
+ template <typename T>
+ inline optional_data<T, true>& optional_data<T, true>::
+ operator= (nullopt_t)
+ {
+ if (v_)
+ v_ = false;
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, true>& optional_data<T, true>::
+ operator= (const T& v)
+ {
+ if (v_)
+ v_ = false;
+
+ new (&d_) T (v);
+ v_ = true;
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, true>& optional_data<T, true>::
+ operator= (T&& v)
+ {
+ if (v_)
+ v_ = false;
+
+ new (&d_) T (std::move (v));
+ v_ = true;
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, true>::
+ optional_data (const optional_data& o)
+ : v_ (o.v_)
+ {
+ if (v_)
+ new (&d_) T (o.d_);
+ }
+
+ template <typename T>
+ inline optional_data<T, true>::
+ optional_data (optional_data&& o)
+ : v_ (o.v_)
+ {
+ if (v_)
+ new (&d_) T (std::move (o.d_));
+ }
+
+ template <typename T>
+ inline optional_data<T, true>& optional_data<T, true>::
+ operator= (const optional_data& o)
+ {
+ if (v_)
+ v_ = false;
+
+ if (o.v_)
+ {
+ new (&d_) T (o.d_);
+ v_ = true;
+ }
+
+ return *this;
+ }
+
+ template <typename T>
+ inline optional_data<T, true>& optional_data<T, true>::
+ operator= (optional_data&& o)
+ {
+ if (v_)
+ v_ = false;
+
+ if (o.v_)
+ {
+ new (&d_) T (std::move (o.d_));
+ v_ = true;
+ }
+
+ return *this;
+ }
+ }
+}