/usr/include/dune/common/std/type_traits.hh is in libdune-common-dev 2.5.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
#define DUNE_COMMON_STD_TYPE_TRAITS_HH
#include <type_traits>
#include <dune/common/typetraits.hh>
#include <dune/common/typeutilities.hh>
namespace Dune
{
namespace Std
{
// to_false_type
// -------------
/** \class to_false_type
*
* \brief template mapping a type to <tt>std::false_type</tt>
*
* \tparam T Some type
*
* Suppose you have a template class. You want to document the required
* members of this class in the non-specialized template, but you know that
* actually instantiating the non-specialized template is an error. You can
* try something like this:
* \code
* template<typename T>
* struct Traits
* {
* static_assert(false,
* "Instanciating this non-specialized template is an "
* "error. You should use one of the specializations "
* "instead.");
* //! The type used to frobnicate T
* typedef void FrobnicateType;
* };
* \endcode
* This will trigger static_assert() as soon as the compiler reads the
* definition for the Traits template, since it knows that "false" can never
* become true, no matter what the template parameters of Traits are. As a
* workaround you can use to_false_type: replace <tt>false</tt> by
* <tt>to_false_type<T>::value</tt>, like this:
* \code
* template<typename T>
* struct Traits
* {
* static_assert(Std::to_false_type<T>::value,
* "Instanciating this non-specialized template is an "
* "error. You should use one of the specializations "
* "instead.");
* //! The type used to frobnicate T
* typedef void FrobnicateType;
* };
* \endcode
* Since there might be an specialization of to_false_type for template
* parameter T, the compiler cannot trigger static_assert() until the type
* of T is known, that is, until Traits<T> is instantiated.
*/
template< typename T >
struct to_false_type : public std::false_type {};
// to_true_type
// ------------
/** \class to_true_type
*
* \brief template mapping a type to <tt>std::true_type</tt>
*
* \tparam T Some type
*
* \note This class exists mostly for consistency with to_false_type.
*/
template< typename T >
struct to_true_type : public std::true_type {};
#if __cpp_lib_bool_constant
using std::bool_constant;
#elif __cpp_lib_experimental_bool_constant
using std::experimental::bool_constant;
#else
/**
* \brief A template alias for std::integral_constant<bool, value>
*
* \tparam value Boolean value to encode as std::integral_constant<bool, value>
*/
template <bool value>
using bool_constant = std::integral_constant<bool, value>;
#endif
namespace Imp {
// If R is void we only need to check if F can be called
// with given Args... list. If this is not possible
// result_of_t is not defined and this overload is disabled.
template<class R, class F, class... Args,
std::enable_if_t<
std::is_same<void_t<std::result_of_t<F(Args...)>>, R>::value
, int> = 0>
std::true_type is_callable_helper(PriorityTag<2>)
{ return {}; }
// Check if result of F(Args...) can be converted to R.
// If F cannot even be called with given Args... then
// result_of_t is not defined and this overload is disabled.
template<class R, class F, class... Args,
std::enable_if_t<
std::is_convertible<std::result_of_t<F(Args...)>, R>::value
, int> = 0>
std::true_type is_callable_helper(PriorityTag<1>)
{ return {}; }
// If none of the above matches, F can either not be called
// with given Args..., or the result cannot be converted to
// void, or R is not void.
template<class R, class F, class... Args>
std::false_type is_callable_helper(PriorityTag<0>)
{ return {}; }
}
/**
* \brief Traits class to check if function is callable
*
* \tparam D Function descriptor
* \tparam R Return value
*
* If D = F(Args...) this checks if F can be called with an
* argument list of type Args..., and if the return value can
* be converted to R. If R is void, any return type is accepted.
* The result is encoded by deriving from std::integral_constant<bool, result>.
*
* If D is not of the form D = F(Args...) this class is not defined.
*
* This implements std::is_callable as proposed in N4446 for C++17.
*/
template <class D, class R= void>
struct is_callable;
/**
* \brief Traits class to check if function is callable
*
* \tparam D Function descriptor
* \tparam R Return value
*
* If D = F(Args...) this checks if F can be called with an
* argument list of type Args..., and if the return value can
* be converted to R. If R is void, any return type is accepted.
* The result is encoded by deriving from std::integral_constant<bool, result>.
*
* If D is not of the form D = F(Args...) this class is not defined.
*
* This implements std::is_callable as proposed in N4446 for C++17.
*/
template <class F, class... Args, class R>
struct is_callable< F(Args...), R> :
decltype(Imp::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
{};
} // namespace Std
} // namespace Dune
#endif // #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
|