Loading...
Searching...
No Matches
signature.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-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
#ifndef DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
#define DUNE_FUNCTIONS_COMMON_SIGNATURE_HH
#include <type_traits>
#include <tuple>
#include <dune/functions/common/defaultderivativetraits.hh>
namespace Dune {
namespace Functions {
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
template<class Signature, bool isCallable = IsCallable<Signature>::value >
struct SignatureTraits {};
#ifndef DOXYGEN
template<class T>
struct SignatureTraits<T, true>
: public SignatureTraits<decltype(&T::operator()), true>
{};
template <typename C, typename R, typename D>
struct SignatureTraits<R(C::*)(D) const, true>
: public SignatureTraits<R(D), true>
{};
template <typename C, typename R, typename D>
struct SignatureTraits<R(C::*)(D), true>
: public SignatureTraits<R(D), true>
{};
template <typename R, typename D>
struct SignatureTraits<R(*)(D), true>
: public SignatureTraits<R(D), true>
{};
template<class R, class D>
struct SignatureTraits<R(D), true>
{
using Range = R;
using Domain = D;
using RawRange = std::decay_t<Range>;
using RawDomain = std::decay_t<Domain>;
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;
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>;
};
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>();
}
template<std::size_t maxOrder, class Signature, template<class> class DerivativeTraits>
auto derivativeSignatureTags(Dune::Functions::SignatureTag<Signature, DerivativeTraits> tag)
{
if constexpr (maxOrder==0) {
// If maxOrder== 0 we just need the given SignatureTag
return std::make_tuple(tag);
} else {
// else we first construct the tail tuple with SignatureTags for derivatives
// of order 1 to maxOrder
auto tailTagsTuple = derivativeSignatureTags<std::size_t(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
defaultderivativetraits.hh
Dune::Functions::derivativeSignatureTag
auto derivativeSignatureTag(SignatureTag< Range(Domain), DerivativeTraits > tag)
Construct SignatureTag for derivative.
Definition signature.hh:137
Dune::Functions::derivativeSignatureTags
auto derivativeSignatureTags(Dune::Functions::SignatureTag< Signature, DerivativeTraits > tag)
Construct SignatureTags for derivatives.
Definition signature.hh:159
Dune
Definition monomialset.hh:19
Dune::Functions
Definition monomialset.hh:19
Dune::Functions::DefaultDerivativeTraits
Default implementation for derivative traits.
Definition defaultderivativetraits.hh:41
Dune::Functions::IsCallable
Helper class to check that F is callable.
Definition signature.hh:24
Dune::Functions::SignatureTraits
Helper class to deduce the signature of a callable.
Definition signature.hh:60
Dune::Functions::SignatureTag
Definition signature.hh:106
Dune::Functions::SignatureTag< Range(Domain), DerivativeTraitsT >::DerivativeTraits
DerivativeTraitsT< T > DerivativeTraits
Definition signature.hh:123
Dune::Functions::SignatureTag< Range(Domain), DerivativeTraitsT >::Signature
Range(Domain) Signature
Definition signature.hh:120