/* -*- 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 #include #include #include 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 class CompactPair { MOZ_NO_UNIQUE_ADDRESS A mFirst; MOZ_NO_UNIQUE_ADDRESS B mSecond; template constexpr CompactPair(APack&& aFirst, std::index_sequence, BPack&& aSecond, std::index_sequence) : mFirst(std::get(aFirst)...), mSecond(std::get(aSecond)...) {} public: template constexpr CompactPair(std::piecewise_construct_t, std::tuple aFirst, std::tuple aSecond) : CompactPair(aFirst, std::make_index_sequence(), aSecond, std::make_index_sequence()) {} template explicit constexpr CompactPair(U&& aFirst, V&& aSecond) : mFirst(std::forward(aFirst)), mSecond(std::forward(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. */ template CompactPair>, std::remove_cv_t>> MakeCompactPair(A&& aA, B&& aB) { return CompactPair>, std::remove_cv_t>>( std::forward(aA), std::forward(aB)); } /** * CompactPair equality comparison */ template bool operator==(const CompactPair& aLhs, const CompactPair& aRhs) { return aLhs.first() == aRhs.first() && aLhs.second() == aRhs.second(); } } // namespace mozilla namespace std { template void swap(mozilla::CompactPair& aX, mozilla::CompactPair& aY) { aX.swap(aY); } } // namespace std #endif /* mozilla_CompactPair_h */