tor-browser

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

CompactPair.h (3371B)


      1 /* -*- Mode: C++; tab-width: 8; 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 /* A class holding a pair of objects that tries to conserve storage space. */
      8 
      9 #ifndef mozilla_CompactPair_h
     10 #define mozilla_CompactPair_h
     11 
     12 #include "mozilla/Attributes.h"
     13 
     14 #include <cstddef>
     15 #include <tuple>
     16 #include <type_traits>
     17 #include <utility>
     18 
     19 namespace mozilla {
     20 
     21 /**
     22 * CompactPair is the logical concatenation of an instance of A with an instance
     23 * B. Space is conserved when possible.
     24 *
     25 * In general if space conservation is not critical is preferred to use
     26 * std::pair.
     27 *
     28 */
     29 template <typename A, typename B>
     30 class CompactPair {
     31  MOZ_NO_UNIQUE_ADDRESS A mFirst;
     32  MOZ_NO_UNIQUE_ADDRESS B mSecond;
     33 
     34  template <class APack, size_t... AIs, class BPack, size_t... BIs>
     35  constexpr CompactPair(APack&& aFirst, std::index_sequence<AIs...>,
     36                        BPack&& aSecond, std::index_sequence<BIs...>)
     37      : mFirst(std::get<AIs>(aFirst)...), mSecond(std::get<BIs>(aSecond)...) {}
     38 
     39 public:
     40  template <typename... AArgs, typename... BArgs>
     41  constexpr CompactPair(std::piecewise_construct_t, std::tuple<AArgs...> aFirst,
     42                        std::tuple<BArgs...> aSecond)
     43      : CompactPair(aFirst, std::make_index_sequence<sizeof...(AArgs)>(),
     44                    aSecond, std::make_index_sequence<sizeof...(BArgs)>()) {}
     45 
     46  template <typename U, typename V>
     47  explicit constexpr CompactPair(U&& aFirst, V&& aSecond)
     48      : mFirst(std::forward<U>(aFirst)), mSecond(std::forward<V>(aSecond)) {}
     49  CompactPair(CompactPair&& aOther) = default;
     50  CompactPair(const CompactPair& aOther) = default;
     51 
     52  CompactPair& operator=(CompactPair&& aOther) = default;
     53  CompactPair& operator=(const CompactPair& aOther) = default;
     54 
     55  constexpr A& first() { return mFirst; }
     56  constexpr const A& first() const { return mFirst; }
     57  constexpr B& second() { return mSecond; }
     58  constexpr const B& second() const { return mSecond; }
     59 
     60  /** Swap this pair with another pair. */
     61  void swap(CompactPair& aOther) {
     62    using std::swap;
     63    swap(mFirst, aOther.mFirst);
     64    swap(mSecond, aOther.mSecond);
     65  }
     66 };
     67 
     68 /**
     69 * MakeCompactPair allows you to construct a CompactPair instance using type
     70 * inference. A call like this:
     71 *
     72 *   MakeCompactPair(Foo(), Bar())
     73 *
     74 * will return a CompactPair<Foo, Bar>.
     75 */
     76 template <typename A, typename B>
     77 CompactPair<std::remove_cv_t<std::remove_reference_t<A>>,
     78            std::remove_cv_t<std::remove_reference_t<B>>>
     79 MakeCompactPair(A&& aA, B&& aB) {
     80  return CompactPair<std::remove_cv_t<std::remove_reference_t<A>>,
     81                     std::remove_cv_t<std::remove_reference_t<B>>>(
     82      std::forward<A>(aA), std::forward<B>(aB));
     83 }
     84 
     85 /**
     86 * CompactPair equality comparison
     87 */
     88 template <typename A, typename B>
     89 bool operator==(const CompactPair<A, B>& aLhs, const CompactPair<A, B>& aRhs) {
     90  return aLhs.first() == aRhs.first() && aLhs.second() == aRhs.second();
     91 }
     92 
     93 }  // namespace mozilla
     94 
     95 namespace std {
     96 
     97 template <typename A, class B>
     98 void swap(mozilla::CompactPair<A, B>& aX, mozilla::CompactPair<A, B>& aY) {
     99  aX.swap(aY);
    100 }
    101 
    102 }  // namespace std
    103 
    104 #endif /* mozilla_CompactPair_h */