]> git.ipfire.org Git - thirdparty/squid.git/commit
Support non-trivial Optional values (#1106)
authorAlex Rousskov <rousskov@measurement-factory.com>
Sat, 30 Jul 2022 01:12:17 +0000 (01:12 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Sat, 30 Jul 2022 21:27:56 +0000 (21:27 +0000)
commit76ed29975b545600970d026c49b016e8fe952ab0
treef7877fc7f45ce994f75471c494cc3ed690e21e14
parent971c012b645e67767f6bd9d42da4a34d200ced22
Support non-trivial Optional values (#1106)

Commit 7224761 skipped this std::optional feature when adding initial
Optional implementation because that feature is difficult to support.
However, several in-progress projects now need to make non-trivial
objects Optional. This implementation maintains key Optional invariants,
matching those of std::optional:

* A valueless Optional object does not construct or destruct the value.
* A valued Optional object supports move/copy ops supported by value.

Maintaining the first invariant is tricky:

* Union prevents value construction/destruction in a valueless Optional.
* Explicit destructor call destructs the value in a _valued_ Optional.
* A dummy union member works around a C++ requirement for constexpr
  unions to have at least one active (i.e. initialized) member. Since a
  valueless Optional cannot initialize the value, we need another union
  member that we can initialize.
* We use an _anonymous_ union because C++ places more requirements on
  named unions, triggering a more complex implementation with
  placement-new and to-be-deprecated std::aligned_storage_t tricks!

XXX: This simplified implementation violates the following std::optional
invariant. We believe that this violation does not hurt the current and
foreseeable Squid code. In our tests, optimizing compilers still
optimize Optional<Trivial> destructors away.

* std::optional<Value> is trivially destructible if Value is.
src/base/Optional.h