tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MaybeStorageBase.h (2921B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* Internal storage class used e.g. by Maybe and Result. This file doesn't
      8 * contain any public declarations. */
      9 
     10 #ifndef mfbt_MaybeStorageBase_h
     11 #define mfbt_MaybeStorageBase_h
     12 
     13 #include <type_traits>
     14 #include <utility>
     15 
     16 namespace mozilla::detail {
     17 
     18 template <typename T>
     19 constexpr bool IsTriviallyDestructibleAndCopyable =
     20    std::is_trivially_destructible_v<T> &&
     21    (std::is_trivially_copy_constructible_v<T> ||
     22     !std::is_copy_constructible_v<T>);
     23 
     24 template <typename T, bool TriviallyDestructibleAndCopyable =
     25                          IsTriviallyDestructibleAndCopyable<T>>
     26 struct MaybeStorageBase;
     27 
     28 template <typename T>
     29 struct MaybeStorageBase<T, false> {
     30 protected:
     31  using NonConstT = std::remove_const_t<T>;
     32 
     33  union Union {
     34    Union() {}
     35    explicit Union(const T& aVal) : val{aVal} {}
     36    template <typename U,
     37              typename = std::enable_if_t<std::is_move_constructible_v<U>>>
     38    explicit Union(U&& aVal) : val{std::forward<U>(aVal)} {}
     39    template <typename... Args>
     40    explicit Union(std::in_place_t, Args&&... aArgs)
     41        : val{std::forward<Args>(aArgs)...} {}
     42 
     43    ~Union() {}
     44 
     45    NonConstT val;
     46  } mStorage;
     47 
     48 public:
     49  constexpr MaybeStorageBase() = default;
     50  explicit MaybeStorageBase(const T& aVal) : mStorage{aVal} {}
     51  explicit MaybeStorageBase(T&& aVal) : mStorage{std::move(aVal)} {}
     52  template <typename... Args>
     53  explicit MaybeStorageBase(std::in_place_t, Args&&... aArgs)
     54      : mStorage{std::in_place, std::forward<Args>(aArgs)...} {}
     55 
     56  const T* addr() const { return &mStorage.val; }
     57  T* addr() { return &mStorage.val; }
     58 };
     59 
     60 template <typename T>
     61 struct MaybeStorageBase<T, true> {
     62 protected:
     63  using NonConstT = std::remove_const_t<T>;
     64 
     65  union Union {
     66    constexpr Union() : empty() {}
     67    constexpr explicit Union(const T& aVal) : val{aVal} {}
     68    constexpr explicit Union(T&& aVal) : val{std::move(aVal)} {}
     69    template <typename... Args>
     70    constexpr explicit Union(std::in_place_t, Args&&... aArgs)
     71        : val{std::forward<Args>(aArgs)...} {}
     72 
     73    NonConstT val;
     74    char empty;
     75  } mStorage;
     76 
     77 public:
     78  constexpr MaybeStorageBase() = default;
     79  constexpr explicit MaybeStorageBase(const T& aVal) : mStorage{aVal} {}
     80  constexpr explicit MaybeStorageBase(T&& aVal) : mStorage{std::move(aVal)} {}
     81 
     82  template <typename... Args>
     83  constexpr explicit MaybeStorageBase(std::in_place_t, Args&&... aArgs)
     84      : mStorage{std::in_place, std::forward<Args>(aArgs)...} {}
     85 
     86  constexpr const T* addr() const { return &mStorage.val; }
     87  constexpr T* addr() { return &mStorage.val; }
     88 };
     89 
     90 }  // namespace mozilla::detail
     91 
     92 #endif