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 105 106 107
|
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_COMMON_REFERENCE_HELPER_HH
#define DUNE_COMMON_REFERENCE_HELPER_HH
#include <type_traits>
#include <functional>
namespace Dune {
namespace Impl {
template<class T>
class IsReferenceWrapper : public std::false_type {};
template<class T>
class IsReferenceWrapper<std::reference_wrapper<T>> : public std::true_type {};
template<class T>
class IsReferenceWrapper<const std::reference_wrapper<T>> : public std::true_type {};
} // namespace Dune::Impl
/**
* \brief Helper to detect if given type is a std::reference_wrapper
*
* \ingroup CxxUtilities
*/
template<class T>
constexpr bool IsReferenceWrapper_v = Impl::IsReferenceWrapper<T>::value;
/**
* \brief Helper function to resolve std::reference_wrapper
*
* This is the overload for plain (mutable or const) l-value reference types.
* It simply forwards the passed l-value reference.
*
* \ingroup CxxUtilities
*/
template<class T>
constexpr T& resolveRef(T& gf) noexcept
{
return gf;
}
// There's no overload for non std::reference_wrapper r-values,
// because this may lead to undefined behavior whenever the
// return value is stored.
// Notice that deleting the overload is not necessary, but
// helps to document that it is missing on purpose. It also
// leads to nicer error messages.
template<class T>
const auto& resolveRef(T&& gf) = delete;
/**
* \brief Helper function to resolve std::reference_wrapper
*
* This is the overload for std::reference_wrapper<T>.
* It resolves the reference by returning the stored
* (mutable or const) l-value reference. It is safe
* to call this with mutable or cost l-values
* as well as r-values of std::reference_wrapper,
* because the life time of the wrapped l-value reference
* is independent of the wrapping std::reference_wrapper<T>
* object.
*
* Notice that the copy created by calling this function
* is easily elided by the compiler, since std::reference_wrapper
* is trivially copyable.
*
* \ingroup CxxUtilities
*/
template<class T>
constexpr T& resolveRef(std::reference_wrapper<T> gf) noexcept
{
return gf.get();
}
/**
* \brief Type trait to resolve std::reference_wrapper
*
* This is an alias for result of resolveRef.
* Plain types T or const T are forwarded while
* for T=std::reference_wrapper\<S\> the wrapped
* type S is returned.
*
* \ingroup Utilities
*/
template<class T>
using ResolveRef_t = std::remove_reference_t<decltype(Dune::resolveRef(std::declval<T&>()))>;
} // namespace Dune
#endif // DUNE_COMMON_REFERENCE_HELPER_HH
|