aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-11-20 13:54:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-11-20 14:08:03 +0200
commit47e147c212dd858a23beb6c86708fa1cccd90136 (patch)
treefab82b0afef94d72810bcad9c72a591b87504159
parentdf1f6dac3b80093c39e850f0d07431b921328f80 (diff)
Improve optional class template implementation
-rw-r--r--libbutl/optional.ixx102
-rw-r--r--libbutl/optional.mxx4
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<T, false>& optional_data<T, false>::
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<T, false>& optional_data<T, false>::
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<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;
+ 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<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;
+ 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 <typename T>
struct optional_data<T, false>
{
- 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 <typename T>
struct optional_data<T, true>
{
- struct empty {char x;}; // Note: byte size is important to GCC.
+ struct empty {char x[sizeof(T)];}; // Note: data member important to GCC.
union
{