diff options
author | Hidehiko Abe <hidehiko@chromium.org> | 2018-01-20 08:50:24 +0900 |
---|---|---|
committer | Qijiang Fan <fqj@google.com> | 2020-06-05 08:17:58 +0900 |
commit | 3d6a7ef14c3ad79bebed6020ee30535d0c110586 (patch) | |
tree | 0c73326456eddfe972371f174a80537813ba3c42 /base/optional.h | |
parent | c6b639035cb30b39d382491014d1a74a003eace9 (diff) | |
download | libchrome-3d6a7ef14c3ad79bebed6020ee30535d0c110586.tar.gz |
Fix non-copyable class's optional move.
BUG=784732
TEST=Ran base_unittests -gtest_filter=*Optional*
Change-Id: Ibb5d7cc5d62deacdba7f811f5a7b83c1c58c3907
Reviewed-on: https://chromium-review.googlesource.com/855976
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Hidehiko Abe <hidehiko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#530663}
CrOS-Libchrome-Original-Commit: f1c8789c71dbdaeeef98ecd52c9715495824e6b0
Diffstat (limited to 'base/optional.h')
-rw-r--r-- | base/optional.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/base/optional.h b/base/optional.h index f6619a5758..34e36fabeb 100644 --- a/base/optional.h +++ b/base/optional.h @@ -44,6 +44,15 @@ struct OptionalStorageBase { // When T is not trivially destructible we must call its // destructor before deallocating its memory. + // Note that this hides the (implicitly declared) move constructor, which + // would be used for constexpr move constructor in OptionalStorage<T>. + // It is needed iff T is trivially move constructible. However, the current + // is_trivially_{copy,move}_constructible implementation requires + // is_trivially_destructible (which looks a bug, cf: + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and + // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not + // necessary for this case at the moment. Please see also the destructor + // comment in "is_trivially_destructible = true" specialization below. ~OptionalStorageBase() { if (!is_null_) value_.~T(); @@ -77,9 +86,18 @@ struct OptionalStorageBase<T, true /* trivially destructible */> { : is_null_(false), value_(std::forward<Args>(args)...) {} // When T is trivially destructible (i.e. its destructor does nothing) there - // is no need to call it. Explicitly defaulting the destructor means it's not - // user-provided. Those two together make this destructor trivial. - ~OptionalStorageBase() = default; + // is no need to call it. Implicitly defined destructor is trivial, because + // both members (bool and union containing only variants which are trivially + // destructible) are trivially destructible. + // Explicitly-defaulted destructor is also trivial, but do not use it here, + // because it hides the implicit move constructor. It is needed to implement + // constexpr move constructor in OptionalStorage iff T is trivially move + // constructible. Note that, if T is trivially move constructible, the move + // constructor of OptionalStorageBase<T> is also implicitly defined and it is + // trivially move constructor. If T is not trivially move constructible, + // "not declaring move constructor without destructor declaration" here means + // "delete move constructor", which works because any move constructor of + // OptionalStorage will not refer to it in that case. template <class... Args> void Init(Args&&... args) { |