File: CompactPair.h

package info (click to toggle)
firefox 147.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,320 kB
  • sloc: cpp: 7,607,359; javascript: 6,533,295; ansic: 3,775,223; python: 1,415,500; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,752; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (104 lines) | stat: -rw-r--r-- 3,371 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* A class holding a pair of objects that tries to conserve storage space. */

#ifndef mozilla_CompactPair_h
#define mozilla_CompactPair_h

#include "mozilla/Attributes.h"

#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>

namespace mozilla {

/**
 * CompactPair is the logical concatenation of an instance of A with an instance
 * B. Space is conserved when possible.
 *
 * In general if space conservation is not critical is preferred to use
 * std::pair.
 *
 */
template <typename A, typename B>
class CompactPair {
  MOZ_NO_UNIQUE_ADDRESS A mFirst;
  MOZ_NO_UNIQUE_ADDRESS B mSecond;

  template <class APack, size_t... AIs, class BPack, size_t... BIs>
  constexpr CompactPair(APack&& aFirst, std::index_sequence<AIs...>,
                        BPack&& aSecond, std::index_sequence<BIs...>)
      : mFirst(std::get<AIs>(aFirst)...), mSecond(std::get<BIs>(aSecond)...) {}

 public:
  template <typename... AArgs, typename... BArgs>
  constexpr CompactPair(std::piecewise_construct_t, std::tuple<AArgs...> aFirst,
                        std::tuple<BArgs...> aSecond)
      : CompactPair(aFirst, std::make_index_sequence<sizeof...(AArgs)>(),
                    aSecond, std::make_index_sequence<sizeof...(BArgs)>()) {}

  template <typename U, typename V>
  explicit constexpr CompactPair(U&& aFirst, V&& aSecond)
      : mFirst(std::forward<U>(aFirst)), mSecond(std::forward<V>(aSecond)) {}
  CompactPair(CompactPair&& aOther) = default;
  CompactPair(const CompactPair& aOther) = default;

  CompactPair& operator=(CompactPair&& aOther) = default;
  CompactPair& operator=(const CompactPair& aOther) = default;

  constexpr A& first() { return mFirst; }
  constexpr const A& first() const { return mFirst; }
  constexpr B& second() { return mSecond; }
  constexpr const B& second() const { return mSecond; }

  /** Swap this pair with another pair. */
  void swap(CompactPair& aOther) {
    using std::swap;
    swap(mFirst, aOther.mFirst);
    swap(mSecond, aOther.mSecond);
  }
};

/**
 * MakeCompactPair allows you to construct a CompactPair instance using type
 * inference. A call like this:
 *
 *   MakeCompactPair(Foo(), Bar())
 *
 * will return a CompactPair<Foo, Bar>.
 */
template <typename A, typename B>
CompactPair<std::remove_cv_t<std::remove_reference_t<A>>,
            std::remove_cv_t<std::remove_reference_t<B>>>
MakeCompactPair(A&& aA, B&& aB) {
  return CompactPair<std::remove_cv_t<std::remove_reference_t<A>>,
                     std::remove_cv_t<std::remove_reference_t<B>>>(
      std::forward<A>(aA), std::forward<B>(aB));
}

/**
 * CompactPair equality comparison
 */
template <typename A, typename B>
bool operator==(const CompactPair<A, B>& aLhs, const CompactPair<A, B>& aRhs) {
  return aLhs.first() == aRhs.first() && aLhs.second() == aRhs.second();
}

}  // namespace mozilla

namespace std {

template <typename A, class B>
void swap(mozilla::CompactPair<A, B>& aX, mozilla::CompactPair<A, B>& aY) {
  aX.swap(aY);
}

}  // namespace std

#endif /* mozilla_CompactPair_h */