Speclib  0.1.2
The library for writing better CUDA libraries
sp::Specialiser Class Reference

The interface for a Specialiser. More...

#include <Specialiser.hpp>

Inheritance diagram for sp::Specialiser:
[legend]

Static Public Member Functions

template<typename T >
static constexpr bool test ()
 Return true iff the specialiser is able to specialise arguments of type T. More...
 
template<typename... O, typename ArgType , typename... Stuff>
static auto run (const ArgType &thisArg, Stuff &&... stuff)
 Specialise an argument. More...
 

Detailed Description

The interface for a Specialiser.

Member Function Documentation

◆ run()

template<typename... O, typename ArgType , typename... Stuff>
static auto sp::Specialiser::run ( const ArgType &  thisArg,
Stuff &&...  stuff 
)
static

Specialise an argument.

The implementation of this function will look like this:

template<typename... O, typename ArgType, typename... Stuff>
static auto run(const ArgType& thisArg, Stuff&&... stuff) {
auto specialisedArgument = ... // <- Left as an exercise for the reader.
return specialiseMore<O...>(specialisedArgument, std::forward<Stuff>(stuff)...);
}
static auto run(const ArgType &thisArg, Stuff &&... stuff)
Specialise an argument.
Definition: Specialiser.hpp:86
auto specialiseMore(NewArg &&newArg, Functor &fn, OutArgs &&outArgs, sp::TypeList< Specialisers... > specialisers, Args &&... args)
Called when the next argument has been finished with by the Specialisers.
Definition: RunSpecialised.hpp:165

Instead of calling specialiseMore, you may instead call the run() function of a different Specialiser. Doing so with an ArgType for which OtherSpecialiser::test<ArgType>() returns false is undefined.

stuff and O are things the specialisation engine uses that must just be blindly propagated. stuff will be the arguments that the specialisation engine wants to get called with again later. O... is the list of types of arguments that have already been deduced during this specialisation run. It is sometimes useful to look at this in a Specialiser implementation to detect unacceptable combinations that warrant a throw instead of a substitution failure.

If your Specialiser encounters a situation where the arguments would be invalid for the function being called in a way that won't be caught by the type system, throw sp::RejectedSpecialisationException. This is useful when implementing void*-based interfaces using specialisers (see the specialiser for TensorDescriptor). Often, a function is made available on the functor type for this purpose, such as onInvalidTensorRank().

See also
Specialisable.hpp

It's expected that specialisers consume thisArg by const-reference, and construct a completely new value to use as the argument. Importantly, this means the no-op specialiser must copy thisArg: you cannot just pass thisArg to specialiseMore(). Since specialisers create new values, it follows that a function that is to be the target of a runSpecialised call must not take any of its specialiseable arguments by lvalue reference.

Template Parameters
OA template parameter pack to pass blindly to specialiseMore().
ArgTypeThe type of the current argument.
Parameters
thisArgThe argument currently being specialised. Specialisers often provide a specific type for this argument that matches the type of value that this specialiser can operate on.
stuffOther arguments to blindly forward to specialiseMore.
Returns
The result of a call to specialiseMore

◆ test()

template<typename T >
static constexpr bool sp::Specialiser::test ( )
staticconstexpr

Return true iff the specialiser is able to specialise arguments of type T.

The type is fed through sp::remove_cvref before passing it to this function.