/* -*- 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. */
// Optimize storage using the Empty Base Optimization -- that empty base classes // don't take up space -- to optimize size when one or the other class is // stateless and can be used as a base class. // // The extra conditions on storage for B are necessary so that CompactPairHelper // won't ambiguously inherit from either A or B, such that one or the other base // class would be inaccessible. template <typename A, typename B,
detail::StorageType =
std::is_empty_v<A> ? detail::AsBase : detail::AsMember,
detail::StorageType = std::is_empty_v<B> &&
!std::is_base_of<A, B>::value &&
!std::is_base_of<B, A>::value
? detail::AsBase
: detail::AsMember> struct CompactPairHelper;
/** * CompactPair is the logical concatenation of an instance of A with an instance * B. Space is conserved when possible. Neither A nor B may be a final class. * * In general if space conservation is not critical is preferred to use * std::pair. * * It's typically clearer to have individual A and B member fields. Except if * you want the space-conserving qualities of CompactPair, you're probably * better off not using this! * * No guarantees are provided about the memory layout of A and B, the order of * initialization or destruction of A and B, and so on. (This is approximately * required to optimize space usage.) The first/second names are merely * conceptual!
*/ template <typename A, typename B> struct CompactPair : private detail::CompactPairHelper<A, B> { typedeftypename detail::CompactPairHelper<A, B> Base;
/** The A instance. */ using Base::first; /** The B instance. */ using Base::second;
/** Swap this pair with another pair. */ void swap(CompactPair& aOther) { Base::swap(aOther); }
};
/** * 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));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.