From 47e147c212dd858a23beb6c86708fa1cccd90136 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 20 Nov 2018 13:54:00 +0200 Subject: Improve optional class template implementation --- libbutl/optional.ixx | 102 ++++++++++++++++++++++++++++++--------------------- libbutl/optional.mxx | 4 +- 2 files changed, 62 insertions(+), 44 deletions(-) diff --git a/libbutl/optional.ixx b/libbutl/optional.ixx index 18c0b0b..ccc7852 100644 --- a/libbutl/optional.ixx +++ b/libbutl/optional.ixx @@ -27,14 +27,13 @@ namespace butl operator= (const T& v) { if (v_) + d_ = v; + else { - d_.~T (); - v_ = false; + new (&d_) T (v); + v_ = true; } - new (&d_) T (v); - v_ = true; - return *this; } @@ -43,14 +42,13 @@ namespace butl operator= (T&& v) { if (v_) + d_ = std::move (v); + else { - d_.~T (); - v_ = false; + new (&d_) T (std::move (v)); + v_ = true; } - new (&d_) T (std::move (v)); - v_ = true; - return *this; } @@ -58,16 +56,20 @@ namespace butl inline optional_data& optional_data:: operator= (const optional_data& o) { - if (v_) + if (o.v_) { - d_.~T (); - v_ = false; + if (v_) + d_ = o.d_; + else + { + new (&d_) T (o.d_); + v_ = true; + } } - - if (o.v_) + else if (v_) { - new (&d_) T (o.d_); - v_ = true; + d_.~T (); + v_ = false; } return *this; @@ -77,16 +79,20 @@ namespace butl inline optional_data& optional_data:: operator= (optional_data&& o) { - if (v_) + if (o.v_) { - d_.~T (); - v_ = false; + if (v_) + d_ = std::move (o.d_); + else + { + new (&d_) T (std::move (o.d_)); + v_ = true; + } } - - if (o.v_) + else if (v_) { - new (&d_) T (std::move (o.d_)); - v_ = true; + d_.~T (); + v_ = false; } return *this; @@ -118,10 +124,12 @@ namespace butl operator= (const T& v) { if (v_) - v_ = false; - - new (&d_) T (v); - v_ = true; + d_ = v; + else + { + new (&d_) T (v); + v_ = true; + } return *this; } @@ -131,10 +139,12 @@ namespace butl operator= (T&& v) { if (v_) - v_ = false; - - new (&d_) T (std::move (v)); - v_ = true; + d_ = std::move (v); + else + { + new (&d_) T (std::move (v)); + v_ = true; + } return *this; } @@ -143,14 +153,18 @@ namespace butl inline optional_data& optional_data:: operator= (const optional_data& o) { - if (v_) - v_ = false; - if (o.v_) { - new (&d_) T (o.d_); - v_ = true; + if (v_) + d_ = o.d_; + else + { + new (&d_) T (o.d_); + v_ = true; + } } + else if (v_) + v_ = false; return *this; } @@ -159,14 +173,18 @@ namespace butl inline optional_data& optional_data:: operator= (optional_data&& o) { - if (v_) - v_ = false; - if (o.v_) { - new (&d_) T (std::move (o.d_)); - v_ = true; + if (v_) + d_ = std::move (o.d_); + else + { + new (&d_) T (std::move (o.d_)); + v_ = true; + } } + else if (v_) + v_ = false; return *this; } diff --git a/libbutl/optional.mxx b/libbutl/optional.mxx index 0f18c11..470c608 100644 --- a/libbutl/optional.mxx +++ b/libbutl/optional.mxx @@ -43,7 +43,7 @@ LIBBUTL_MODEXPORT namespace butl template struct optional_data { - struct empty {char x;}; // Note: byte size is important to GCC. + struct empty {char x[sizeof(T)];}; // Note: data member important to GCC. union { @@ -86,7 +86,7 @@ LIBBUTL_MODEXPORT namespace butl template struct optional_data { - struct empty {char x;}; // Note: byte size is important to GCC. + struct empty {char x[sizeof(T)];}; // Note: data member important to GCC. union { -- cgit v1.1