/usr/include/dune/functions/common/signature.hh is in libdune-functions-dev 2.5.1-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 183 184 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
#define DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
#include <type_traits>
#include <tuple>
#include <dune/common/hybridutilities.hh>
#include <dune/common/std/apply.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
namespace Dune {
namespace Functions {
/**
* \brief Helper class to check that F is callable
*
* \ingroup FunctionUtility
*/
template<typename F>
struct IsCallable;
#ifndef DOXYGEN
template<typename F>
struct IsCallable
{
struct yes { std::size_t dummy[2]; };
struct no { std::size_t dummy[1]; };
template<typename C>
static yes test(const decltype(&C::operator()) *);
template<typename C>
static no test(...);
enum { value = (sizeof(test<F>(0)) == sizeof(yes)) };
};
template<typename R, typename D>
struct IsCallable<R(D)>
{
enum { value = true };
};
template<typename R, typename D>
struct IsCallable<R(*)(D)>
{
enum { value = true };
};
#endif
/**
* \brief Helper class to deduce the signature of a callable
*
* \ingroup FunctionUtility
*/
template<class Signature, bool isCallable = IsCallable<Signature>::value >
struct SignatureTraits {};
#ifndef DOXYGEN
/** \brief deduce the signature of the operator() of a class T */
template<class T>
struct SignatureTraits<T, true>
: public SignatureTraits<decltype(&T::operator()), true>
{};
/** \brief deduce the signature of an arbitrary const member function of class C */
template <typename C, typename R, typename D>
struct SignatureTraits<R(C::*)(D) const, true>
: public SignatureTraits<R(D), true>
{};
/** \brief deduce the signature of an arbitrary member function of class C */
template <typename C, typename R, typename D>
struct SignatureTraits<R(C::*)(D), true>
: public SignatureTraits<R(D), true>
{};
/** \brief extract domain and range from a free functions pointer */
template <typename R, typename D>
struct SignatureTraits<R(*)(D), true>
: public SignatureTraits<R(D), true>
{};
/** \brief extract domain and range from a signature (works only for free functions) */
template<class R, class D>
struct SignatureTraits<R(D), true>
{
using Range = R;
using Domain = D;
using RawRange = typename std::decay<Range>::type;
using RawDomain = typename std::decay<Domain>::type;
using RawSignature = RawRange(RawDomain);
template<template<class> class DerivativeTraits=DefaultDerivativeTraits>
using DerivativeSignature = typename DerivativeTraits<RawSignature>::Range(Domain);
};
#endif
template<class Signature, template<class> class DerivativeTraits=DefaultDerivativeTraits>
struct SignatureTag;
/**
* \brief Tag-class to encapsulate signature information
*
* \ingroup FunctionUtility
*
* \tparam Range range type
* \tparam Domain domain type
* \tparam DerivativeTraits traits template used to determine derivative traits
*/
template<class Range, class Domain, template<class> class DerivativeTraitsT>
struct SignatureTag<Range(Domain), DerivativeTraitsT>
{
using Signature = Range(Domain);
template<class T>
using DerivativeTraits = DerivativeTraitsT<T>;
};
/**
* \brief Construct SignatureTag for derivative
*
* \ingroup FunctionUtility
*
* \param tag SignatureTag for a function
* \returns SignatureTags of the derivative
*/
template<class Range, class Domain, template<class> class DerivativeTraits>
auto derivativeSignatureTag(SignatureTag<Range(Domain), DerivativeTraits> tag)
{
using DerivativeRange = typename DerivativeTraits<Range(Domain)>::Range;
return SignatureTag<DerivativeRange(Domain), DerivativeTraits>();
}
/**
* \brief Construct SignatureTags for derivatives
*
* \ingroup FunctionUtility
*
* \tparam maxOrder Maximal order of derivatives
* \param tag SignatureTag for a function
*
* \returns Tuple of SignatureTags
*
* This constructs an std::tuple of SignatureTags for
* all derivatives of order 0 up to maxOrder.
*/
template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
auto derivativeSignatureTags(Dune::Functions::SignatureTag<Signature, DerivativeTraits> tag)
{
// using namespace Dune::Hybrid;
// using namespace Dune::Std;
return Hybrid::ifElse(Std::bool_constant<maxOrder==0>(), [&](auto id) {
// If maxOrder== 0 we just need the given SignatureTag
return std::make_tuple(tag);
}, [&](auto id) {
// else we first construct the tail tuple with SignatureTags for derivatives
// of order 1 to maxOrder
auto tailTagsTuple = derivativeSignatureTags<decltype(id,std::size_t(0))(maxOrder-1)>(derivativeSignatureTag(tag));
// and prepend this with the given SignatureTag.
// This is done by unpacking the tail tuple with apply().
return Std::apply([&](auto&&... tailTags){
return std::make_tuple(tag, tailTags...);
}, tailTagsTuple);
});
}
} // namespace Functions
} // namespace Dune
#endif // DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
|