зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1661457 - Add in-place constructor to CompactPair. r=froydnj
Differential Revision: https://phabricator.services.mozilla.com/D88418
This commit is contained in:
Родитель
5cacc3e1dc
Коммит
d85bd68479
|
@ -10,6 +10,7 @@
|
|||
#define mozilla_CompactPair_h
|
||||
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -40,6 +41,16 @@ struct CompactPairHelper;
|
|||
template <typename A, typename B>
|
||||
struct CompactPairHelper<A, B, AsMember, AsMember> {
|
||||
protected:
|
||||
template <typename... AArgs, std::size_t... AIndexes, typename... BArgs,
|
||||
std::size_t... BIndexes>
|
||||
CompactPairHelper(std::tuple<AArgs...>& aATuple,
|
||||
std::tuple<BArgs...>& aBTuple,
|
||||
std::index_sequence<AIndexes...>,
|
||||
std::index_sequence<BIndexes...>)
|
||||
: mFirstA(std::forward<AArgs>(std::get<AIndexes>(aATuple))...),
|
||||
mSecondB(std::forward<BArgs>(std::get<BIndexes>(aBTuple))...) {}
|
||||
|
||||
public:
|
||||
template <typename AArg, typename BArg>
|
||||
CompactPairHelper(AArg&& aA, BArg&& aB)
|
||||
: mFirstA(std::forward<AArg>(aA)), mSecondB(std::forward<BArg>(aB)) {}
|
||||
|
@ -62,6 +73,16 @@ struct CompactPairHelper<A, B, AsMember, AsMember> {
|
|||
template <typename A, typename B>
|
||||
struct CompactPairHelper<A, B, AsMember, AsBase> : private B {
|
||||
protected:
|
||||
template <typename... AArgs, std::size_t... AIndexes, typename... BArgs,
|
||||
std::size_t... BIndexes>
|
||||
CompactPairHelper(std::tuple<AArgs...>& aATuple,
|
||||
std::tuple<BArgs...>& aBTuple,
|
||||
std::index_sequence<AIndexes...>,
|
||||
std::index_sequence<BIndexes...>)
|
||||
: B(std::forward<BArgs>(std::get<BIndexes>(aBTuple))...),
|
||||
mFirstA(std::forward<AArgs>(std::get<AIndexes>(aATuple))...) {}
|
||||
|
||||
public:
|
||||
template <typename AArg, typename BArg>
|
||||
CompactPairHelper(AArg&& aA, BArg&& aB)
|
||||
: B(std::forward<BArg>(aB)), mFirstA(std::forward<AArg>(aA)) {}
|
||||
|
@ -83,6 +104,16 @@ struct CompactPairHelper<A, B, AsMember, AsBase> : private B {
|
|||
template <typename A, typename B>
|
||||
struct CompactPairHelper<A, B, AsBase, AsMember> : private A {
|
||||
protected:
|
||||
template <typename... AArgs, std::size_t... AIndexes, typename... BArgs,
|
||||
std::size_t... BIndexes>
|
||||
CompactPairHelper(std::tuple<AArgs...>& aATuple,
|
||||
std::tuple<BArgs...>& aBTuple,
|
||||
std::index_sequence<AIndexes...>,
|
||||
std::index_sequence<BIndexes...>)
|
||||
: A(std::forward<AArgs>(std::get<AIndexes>(aATuple))...),
|
||||
mSecondB(std::forward<BArgs>(std::get<BIndexes>(aBTuple))...) {}
|
||||
|
||||
public:
|
||||
template <typename AArg, typename BArg>
|
||||
CompactPairHelper(AArg&& aA, BArg&& aB)
|
||||
: A(std::forward<AArg>(aA)), mSecondB(std::forward<BArg>(aB)) {}
|
||||
|
@ -104,6 +135,16 @@ struct CompactPairHelper<A, B, AsBase, AsMember> : private A {
|
|||
template <typename A, typename B>
|
||||
struct CompactPairHelper<A, B, AsBase, AsBase> : private A, private B {
|
||||
protected:
|
||||
template <typename... AArgs, std::size_t... AIndexes, typename... BArgs,
|
||||
std::size_t... BIndexes>
|
||||
CompactPairHelper(std::tuple<AArgs...>& aATuple,
|
||||
std::tuple<BArgs...>& aBTuple,
|
||||
std::index_sequence<AIndexes...>,
|
||||
std::index_sequence<BIndexes...>)
|
||||
: A(std::forward<AArgs>(std::get<AIndexes>(aATuple))...),
|
||||
B(std::forward<BArgs>(std::get<BIndexes>(aBTuple))...) {}
|
||||
|
||||
public:
|
||||
template <typename AArg, typename BArg>
|
||||
CompactPairHelper(AArg&& aA, BArg&& aB)
|
||||
: A(std::forward<AArg>(aA)), B(std::forward<BArg>(aB)) {}
|
||||
|
@ -141,10 +182,13 @@ template <typename A, typename B>
|
|||
struct CompactPair : private detail::CompactPairHelper<A, B> {
|
||||
typedef typename detail::CompactPairHelper<A, B> Base;
|
||||
|
||||
public:
|
||||
template <typename AArg, typename BArg>
|
||||
CompactPair(AArg&& aA, BArg&& aB)
|
||||
: Base(std::forward<AArg>(aA), std::forward<BArg>(aB)) {}
|
||||
using Base::Base;
|
||||
|
||||
template <typename... AArgs, typename... BArgs>
|
||||
CompactPair(std::piecewise_construct_t, std::tuple<AArgs...> aFirst,
|
||||
std::tuple<BArgs...> aSecond)
|
||||
: Base(aFirst, aSecond, std::index_sequence_for<AArgs...>(),
|
||||
std::index_sequence_for<BArgs...>()) {}
|
||||
|
||||
CompactPair(CompactPair&& aOther) = default;
|
||||
CompactPair(const CompactPair& aOther) = default;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <type_traits>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/CompactPair.h"
|
||||
|
||||
using mozilla::CompactPair;
|
||||
|
@ -67,6 +68,55 @@ INSTANTIATE(A, A, class1, 2);
|
|||
INSTANTIATE(A, B, class2, 2);
|
||||
INSTANTIATE(A, EmptyClass, class3, 1);
|
||||
|
||||
struct EmptyNonMovableNonDefaultConstructible {
|
||||
explicit EmptyNonMovableNonDefaultConstructible(int) {}
|
||||
|
||||
EmptyNonMovableNonDefaultConstructible(
|
||||
const EmptyNonMovableNonDefaultConstructible&) = delete;
|
||||
EmptyNonMovableNonDefaultConstructible(
|
||||
EmptyNonMovableNonDefaultConstructible&&) = delete;
|
||||
EmptyNonMovableNonDefaultConstructible& operator=(
|
||||
const EmptyNonMovableNonDefaultConstructible&) = delete;
|
||||
EmptyNonMovableNonDefaultConstructible& operator=(
|
||||
EmptyNonMovableNonDefaultConstructible&&) = delete;
|
||||
};
|
||||
|
||||
static void TestInPlaceConstruction() {
|
||||
constexpr int firstValue = 42;
|
||||
constexpr int secondValue = 43;
|
||||
|
||||
{
|
||||
const CompactPair<EmptyNonMovableNonDefaultConstructible, int> pair{
|
||||
std::piecewise_construct, std::tuple(firstValue),
|
||||
std::tuple(secondValue)};
|
||||
MOZ_RELEASE_ASSERT(pair.second() == secondValue);
|
||||
}
|
||||
|
||||
{
|
||||
const CompactPair<int, EmptyNonMovableNonDefaultConstructible> pair{
|
||||
std::piecewise_construct, std::tuple(firstValue),
|
||||
std::tuple(secondValue)};
|
||||
MOZ_RELEASE_ASSERT(pair.first() == firstValue);
|
||||
}
|
||||
|
||||
{
|
||||
const CompactPair<int, int> pair{std::piecewise_construct,
|
||||
std::tuple(firstValue),
|
||||
std::tuple(secondValue)};
|
||||
MOZ_RELEASE_ASSERT(pair.first() == firstValue);
|
||||
MOZ_RELEASE_ASSERT(pair.second() == secondValue);
|
||||
}
|
||||
|
||||
{
|
||||
const CompactPair<EmptyNonMovableNonDefaultConstructible,
|
||||
EmptyNonMovableNonDefaultConstructible>
|
||||
pair{std::piecewise_construct, std::tuple(firstValue),
|
||||
std::tuple(secondValue)};
|
||||
|
||||
// nothing to assert here...
|
||||
}
|
||||
}
|
||||
|
||||
struct OtherEmpty : EmptyClass {
|
||||
explicit OtherEmpty(int aI) : EmptyClass(aI) {}
|
||||
};
|
||||
|
@ -104,5 +154,7 @@ int main() {
|
|||
a = constA;
|
||||
a = A(0);
|
||||
|
||||
TestInPlaceConstruction();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче