Loading...
Searching...
No Matches
typetraits.hh
Go to the documentation of this file.
// -*- 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_TYPETRAITS_HH
#define DUNE_TYPETRAITS_HH
#include <complex>
#include <type_traits>
#include <utility>
#include <vector>
namespace Dune
{
namespace Impl
{
template <class...>
struct voider
{
using type = void;
};
}
template <class... Types>
using void_t = typename Impl::voider<Types...>::type;
struct Empty {};
template<class T1, class T2>
struct IsInteroperable
{
constexpr static bool value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value;
};
template<class T1, class T2, class Type>
struct EnableIfInterOperable
: public std::enable_if<IsInteroperable<T1,T2>::value, Type>
{};
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 AlwaysFalse: replace <tt>false</tt> by
<tt>AlwaysFalse<T>::value</tt>, like this:
\code
template<typename T>
struct Traits {
static_assert(AlwaysFalse<T>::value,
"Instantiating this non-specialized template is an "
"error. You should use one of the specializations "
"instead.");
typedef void FrobnicateType;
};
\endcode
Since there might be an specialization of AlwaysFalse 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 AlwaysFalse : public std::false_type {};
template<typename T>
struct AlwaysTrue : public std::true_type {};
template<typename D, typename R = void>
struct IsCallable;
template<typename R, typename F, typename... Args>
struct IsCallable<F(Args...), R>
: public std::bool_constant<
std::is_invocable_r_v<R, F, Args...>
&& !std::is_member_pointer_v<std::decay_t<F>>
> {};
template <typename T>
struct IsNumber
: public std::integral_constant<bool, std::is_arithmetic<T>::value> {
};
#ifndef DOXYGEN
template <typename T>
struct IsNumber<std::complex<T>>
: public std::integral_constant<bool, IsNumber<T>::value> {
};
#endif // DOXYGEN
template <typename T>
struct HasNaN
: public std::integral_constant<bool, std::is_floating_point<T>::value> {
};
#ifndef DOXYGEN
template <typename T>
struct HasNaN<std::complex<T>>
: public std::integral_constant<bool, std::is_floating_point<T>::value> {
};
#endif // DOXYGEN
#ifndef DOXYGEN
namespace Impl {
template<typename T, typename I, typename = int>
struct IsIndexable
: public std::false_type
{};
template<typename T, typename I>
struct IsIndexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
: public std::true_type
{};
}
#endif // DOXYGEN
template<typename T, typename I = std::size_t>
struct IsIndexable
: public Impl::IsIndexable<T,I>
{};
#ifndef DOXYGEN
namespace Impl {
// This function does nothing.
// By passing expressions to this function one can avoid
// "value computed is not used" warnings that may show up
// in a comma expression.
template<class...T>
void ignore(T&&... /*t*/)
{}
}
#endif // DOXYGEN
// default version, gets picked if SFINAE fails
template<typename T, typename = void>
struct IsIterable
: public std::false_type
{};
#ifndef DOXYGEN
// version for types with begin() and end()
template<typename T>
struct IsIterable<T, decltype(Impl::ignore(
std::declval<T>().begin(),
std::declval<T>().end(),
std::declval<T>().begin() != std::declval<T>().end(),
decltype(std::declval<T>().begin()){std::declval<T>().end()},
++(std::declval<std::add_lvalue_reference_t<decltype(std::declval<T>().begin())>>()),
*(std::declval<T>().begin())
))>
: public std::true_type
{};
#endif
#ifndef DOXYGEN
// this is just a forward declaration
template <class> struct FieldTraits;
#endif
template <class Type>
using field_t = typename FieldTraits<Type>::field_type;
template <class Type>
using real_t = typename FieldTraits<Type>::real_type;
#ifndef DOXYGEN
// Implementation of IsTuple
namespace Impl {
template<class T>
struct IsTuple : public std::false_type
{};
template<class... T>
struct IsTuple<std::tuple<T...>> : public std::true_type
{};
} // namespace Impl
#endif // DOXYGEN
template<class T>
struct IsTuple :
public Impl::IsTuple<T>
{};
#ifndef DOXYGEN
// Implementation of IsTupleOrDerived
namespace Impl {
template<class... T, class Dummy>
std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
{ return {}; }
template<class Dummy>
std::false_type isTupleOrDerived(const void*, Dummy)
{ return {}; }
} // namespace Impl
#endif // DOXYGEN
template<class T>
struct IsTupleOrDerived :
public decltype(Impl::isTupleOrDerived(std::declval<T*>(), true))
{};
#ifndef DOXYGEN
// Implementation of is IsIntegralConstant
namespace Impl {
template<class T>
struct IsIntegralConstant : public std::false_type
{};
template<class T, T t>
struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
{};
} // namespace Impl
#endif // DOXYGEN
template<class T>
struct IsIntegralConstant : public Impl::IsIntegralConstant<std::decay_t<T>>
{};
#ifndef DOXYGEN
namespace Impl {
struct IsCompileTimeConstant
{
template <class T, T value>
static std::true_type check(std::integral_constant<T,value>);
static std::false_type check(...);
};
} // namespace Impl
#endif // DOXYGEN
template<class T>
struct IsCompileTimeConstant
: public decltype(Impl::IsCompileTimeConstant::check(std::declval<T>()))
{};
#ifndef DOXYGEN
namespace Impl {
template<class T, T...>
struct IntegerSequenceHelper;
// Helper struct to compute the i-th entry of a std::integer_sequence
//
// This could also be implemented using std::get<index>(std::make_tuple(t...)).
// However, the gcc-6 implementation of std::make_tuple increases the instantiation
// depth by 15 levels for each argument, such that the maximal instantiation depth
// is easily hit, especially with clang where it is set to 256.
template<class T, T head, T... tail>
struct IntegerSequenceHelper<T, head, tail...>
{
// get first entry
static constexpr auto get(std::integral_constant<std::size_t, 0>)
{
return std::integral_constant<T, head>();
}
// call get with first entry cut off and decremented index
template<std::size_t index,
std::enable_if_t<(index > 0) and (index < sizeof...(tail)+1), int> = 0>
static constexpr auto get(std::integral_constant<std::size_t, index>)
{
return IntegerSequenceHelper<T, tail...>::get(std::integral_constant<std::size_t, index-1>());
}
// use static assertion if index exceeds size
template<std::size_t index,
std::enable_if_t<(index >= sizeof...(tail)+1), int> = 0>
static constexpr auto get(std::integral_constant<std::size_t, index>)
{
static_assert(index < sizeof...(tail)+1, "index used in IntegerSequenceEntry exceed size");
}
};
} // end namespace Impl
#endif // DOXYGEN
template<class T, T... t, std::size_t index>
[[deprecated("Use get(std::integer_sequence<...>, index) instead.")]]
constexpr auto integerSequenceEntry(std::integer_sequence<T, t...> /*seq*/, std::integral_constant<std::size_t, index> i)
{
static_assert(index < sizeof...(t), "index used in IntegerSequenceEntry exceed size");
return Impl::IntegerSequenceHelper<T, t...>::get(i);
}
template<class IntegerSequence, std::size_t index>
struct IntegerSequenceEntry;
#ifndef DOXYGEN
template<class T, T... t, std::size_t i>
struct [[deprecated("Use get(std::integer_sequence<...>, index) instead.")]]IntegerSequenceEntry<std::integer_sequence<T, t...>, i>
: public decltype(Impl::IntegerSequenceHelper<T, t...>::get(std::integral_constant<std::size_t, i>()))
{};
#endif // DOXYGEN
template<class T>
struct AutonomousValueType { using type = T; };
template<class T>
struct AutonomousValueType<T&> : AutonomousValueType<T> {};
template<class T>
struct AutonomousValueType<T&&> : AutonomousValueType<T> {};
template<class T>
struct AutonomousValueType<const T> : AutonomousValueType<T> {};
template<class T>
struct AutonomousValueType<volatile T> : AutonomousValueType<T> {};
template<>
struct AutonomousValueType<std::vector<bool>::reference>
{
using type = bool;
};
template<class T>
struct AutonomousValueType<volatile const T> : AutonomousValueType<T> {};
template<class T>
using AutonomousValue = typename AutonomousValueType<T>::type;
template<class T>
constexpr AutonomousValue<T> autoCopy(T &&v)
{
return v;
}
}
#endif
Dune::integerSequenceEntry
constexpr auto integerSequenceEntry(std::integer_sequence< T, t... >, std::integral_constant< std::size_t, index > i)
Get entry of std::integer_sequence.
Definition typetraits.hh:470
Dune::void_t
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition typetraits.hh:40
Dune::real_t
typename FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition typetraits.hh:301
Dune::field_t
typename FieldTraits< Type >::field_type field_t
Convenient access to FieldTraits<Type>::field_type.
Definition typetraits.hh:297
Dune::autoCopy
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition typetraits.hh:650
Dune::AutonomousValue
typename AutonomousValueType< T >::type AutonomousValue
Type free of internal references that T can be converted to.
Definition typetraits.hh:566
Dune::type
MPI_Datatype MPITraits< ParallelLocalIndex< T > >::type
Definition plocalindex.hh:317
std
STL namespace.
Dune
Dune namespace
Definition alignedallocator.hh:13
Dune::tail
constexpr std::integer_sequence< T, II... > tail(std::integer_sequence< T, I0, II... >)
For a sequence [head,tail...) return the tail sequence.
Definition integersequence.hh:58
Dune::head
constexpr std::integral_constant< T, I0 > head(std::integer_sequence< T, I0, II... >)
For a sequence [head,tail...) return the single head element.
Definition integersequence.hh:53
Dune::get
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition integersequence.hh:22
Dune::IsNumber
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition typetraits.hh:194
Dune::FieldTraits::field_type
T field_type
export the type representing the field
Definition ftraits.hh:28
Dune::FieldTraits::real_type
T real_type
export the type representing the real type of the field
Definition ftraits.hh:30
Dune::type
Dune::Empty
Just an empty class.
Definition typetraits.hh:55
Dune::IsInteroperable
Checks whether two types are interoperable.
Definition typetraits.hh:65
Dune::IsInteroperable::value
static constexpr bool value
True if either a conversion from T1 to T2 or vice versa exists.
Definition typetraits.hh:70
Dune::EnableIfInterOperable
Enable typedef if two types are interoperable.
Definition typetraits.hh:81
Dune::AlwaysFalse
template which always yields a false value
Definition typetraits.hh:124
Dune::AlwaysTrue
template which always yields a true value
Definition typetraits.hh:134
Dune::IsCallable
Check if a type is callable with ()-operator and given arguments.
Definition typetraits.hh:162
Dune::HasNaN
Whether this type has a value of NaN.
Definition typetraits.hh:212
Dune::IsIndexable
Type trait to determine whether an instance of T has an operator[](I), i.e. whether it can be indexed...
Definition typetraits.hh:250
Dune::IsIterable
typetrait to check that a class has begin() and end() members
Definition typetraits.hh:273
Dune::IsTuple
Check if T is a std::tuple<...>.
Definition typetraits.hh:329
Dune::IsTupleOrDerived
Check if T derived from a std::tuple<...>.
Definition typetraits.hh:357
Dune::IsIntegralConstant
Check if T is an std::integral_constant<I, i>.
Definition typetraits.hh:384
Dune::IsCompileTimeConstant
Check if T is an integral constant or any type derived from std::integral_constant.
Definition typetraits.hh:411
Dune::IntegerSequenceEntry
Get entry of std::integer_sequence.
Definition typetraits.hh:484
Dune::AutonomousValueType
Type free of internal references that T can be converted to.
Definition typetraits.hh:509
Dune::AutonomousValueType::type
T type
Definition typetraits.hh:509
Dune::AutonomousValueType< std::vector< bool >::reference >::type
bool type
Definition typetraits.hh:531