Speclib  0.1.2
The library for writing better CUDA libraries
Variable System

Tools for manipulating variables at run time that can then be bound to values at runtime. More...

Classes

class  sp::VariableUser< Subclass, Children >
 Base for anything that uses the expression variable system. More...
 
struct  sp::AnyType
 Can be given as the type for a Variable, in which case the type of bound variable is dependent on the argument type given to bind(). More...
 
class  sp::VariableTuple< Children >
 Represents a list of variable users that might share variables. More...
 
class  sp::VariableBinding< Child, Names, Ts >
 Represents a variable user and values to bind to it. More...
 
class  sp::VariableFunctor< F, Children >
 Represents a functor to be applied in the variable system. More...
 
class  sp::Constant< Value, T >
 A type for use with the VariableUser system to represent a compile time constant. More...
 
class  sp::BoundVariable< T >
 The result of binding a Variable to a specific value. More...
 
class  sp::Variable< Name, T >
 A variable that can be bound at run time. More...
 
struct  sp::IsVariableUser< T >
 Determine if a type is a variable user. More...
 
struct  sp::IsVariableTuple< T >
 Determine if a type is a variable tuple. More...
 
struct  sp::IsVariableBinding< T >
 Determine if a type is a variable binding. More...
 
struct  sp::IsVariableFunctor< T >
 Determine if a type is a variable functor. More...
 
struct  sp::IsConstant< T >
 Determine if a type is a variable user constant. More...
 
struct  sp::IsBoundVariable< T >
 Determine if a type is a bound variable. More...
 
struct  sp::IsVariable< T >
 Determine if a type is a variable. More...
 
struct  sp::IsVariableUserLeaf< typename >
 Determine if a type is one of the variable user leafs. More...
 
struct  sp::RemoveVariableUserLeaf< T >
 Change variable user leaf types to their value types. More...
 
struct  sp::RemoveVariableUserLeafAndRef< T >
 Like RemoveVariableUserLeaf, but removes the reference of a leaf's inner type as well. More...
 
struct  sp::RemoveVariableUserLeafAndCVRef< T >
 Like RemoveVariableUserLeaf, but removes the reference and CV-qualifiers of a leaf's inner type as well. More...
 

Typedefs

using sp::VariableName = char32_t
 The type to use to identify variables in an expression. More...
 
template<char32_t... Cs>
using sp::VariableNames = char32_sequence< Cs... >
 A sequence of variable names. More...
 
template<typename T >
using sp::RemoveVariableUserLeaf_t = typename RemoveVariableUserLeaf< T >::type
 Change variable user leaf types to their value types. More...
 
template<typename T >
using sp::RemoveVariableUserLeafAndRef_t = typename RemoveVariableUserLeafAndRef< T >::type
 Like RemoveVariableUserLeaf_t, but removes the reference of a leaf's inner type as well. More...
 
template<typename T >
using sp::RemoveVariableUserLeafAndCVRef_t = typename RemoveVariableUserLeafAndCVRef< T >::type
 Like RemoveVariableUserLeaf, but removes the reference and CV-qualifiers of a leaf's inner type as well. More...
 
template<auto Value, typename T = decltype(Value)>
using sp::Const = Constant< Value, T >
 Shorthand for sp::Constant. More...
 
template<VariableName Name, typename T = sp::AnyType>
using sp::Var = Variable< Name, T >
 Shorthand for sp::Variable. More...
 

Enumerations

enum  sp::DefaultConstructEnum { DefaultConstruct }
 Using DefaultConstruct as the Value argument to sp::Constant causes default construction of the type rather than construction with a given value. More...
 

Functions

template<VariableName... Names, typename... Ts, typename Child >
requires (sizeof...(Names) > 0)
constexpr auto sp::getVariableBinding (const Child &child, Ts &&... values)
 Construct a VariableBinding with values for the given names. More...
 
template<typename... Ts, typename Child >
requires (sizeof...(Ts) > 0 && sizeof...(Ts) == Child::Vars::Size)
constexpr auto sp::getVariableBinding (const Child &child, Ts &&... values)
 Construct a VariableBinding with one value for each variable in the VariableUser. More...
 
template<typename Child >
constexpr auto sp::getVariableBinding (const Child &child)
 
template<typename T >
constexpr auto sp::bind (T value)
 Produce a single bound variable. More...
 
template<typename T >
constexpr decltype(auto) sp::unbind (T &&value)
 Remove BoundVariable or Constant from a value. More...
 

Variables

template<typename T >
constexpr bool sp::IsVariableUser_v = IsVariableUser<T>::value
 Determine if a type is a variable user. More...
 
template<typename T >
constexpr bool sp::IsVariableTuple_v = IsVariableTuple<T>::value
 Determine if a type is a variable tuple. More...
 
template<typename T >
constexpr bool sp::IsVariableBinding_v = IsVariableBinding<T>::value
 Determine if a type is a variable binding. More...
 
template<typename T >
constexpr bool sp::IsVariableFunctor_v = IsVariableFunctor<T>::value
 Determine if a type is a variable functor. More...
 
template<typename T >
constexpr bool sp::IsConstant_v = IsConstant<T>::value
 Determine if a type is a variable user constant. More...
 
template<typename T >
constexpr bool sp::IsBoundVariable_v = IsBoundVariable<T>::value
 Determine if a type is a bound variable. More...
 
template<typename T >
constexpr bool sp::IsVariable_v = IsVariable<T>::value
 Determine if a type is a variable. More...
 
template<typename T >
constexpr bool sp::IsVariableUserLeaf_v = IsVariableUserLeaf<T>::value
 Determine if a type is one of the variable user leafs. More...
 

Detailed Description

Tools for manipulating variables at run time that can then be bound to values at runtime.

An example of a simple variable user that adds its two children together is given below:

Example

template <typename LHS, typename RHS>
class Add final : public sp::VariableUser<Add<LHS, RHS>, LHS, RHS>
{
private:
using Base = sp::VariableUser<Add<LHS, RHS>, LHS, RHS>;
public:
template <typename NewLHS, typename NewRHS>
using ReplaceChildren = Add<NewLHS, NewRHS>;
Add() = default;
Add(const LHS &lhs, const RHS &rhs) : Base(lhs, rhs) {}
using Base::operator();
auto operator()() const requires(Base::IsFullyBound)
{
return this->template get<0>()() + this->template get<1>()();
}
};
Base for anything that uses the expression variable system.
Definition: Var.hpp:130

In real-world usage, the type we actually want to use is likely to be very complex. We recommend using type aliases to represent trees of variable users:

Example

using SimpleVariableUser =
Add<sp::Var<'x', int>,
Add<sp::Var<'y', int>,
>
>;
A variable that can be bound at run time.
Definition: Var.hpp:921

It can be used to calculate a result as follows:

Example

auto bound = SimpleVariableUser{}.bind(30, 10, 2);
int result = bound(); // 42

Or even more simply:

Example

int result = SimpleVariableUser{}(30, 10, 2); // 42

We can bind some of the variables before binding other variables:

Example

auto bound = SimpleVariableUser{}.bind<'y', 'x'>(10, 30);
int result = bound(2); // 42

When a variable is bound, it is stored as exactly the type given. The following code example demonstrates using a reference type:

Example

int x = 40;
auto bound = Add<sp::Var<'x', const int &>, sp::Var<'y', int>>{}.bind(x, 2);
int result1 = bound(); // 42
x = 12345;
int result2 = bound(); // 12347

Abstract algebra is possible with the variable system. Consider the following example, which replaces an specific expression with a different expression:

Example

using Expr = Add<Mul<sp::Var<'t', int>,
using Sub = Expr::Substitute<Mul<sp::Var<'t', int>,
Mul<sp::Var<'x', int>,
constexpr bool Result = std::is_same_v<Sub, Add<Mul<sp::Var<'x', int>,
sp::Const<42>>>; // True
A type for use with the VariableUser system to represent a compile time constant.
Definition: Var.hpp:807

Typedef Documentation

◆ Const

template<auto Value, typename T = decltype(Value)>
using sp::Const = typedef Constant<Value, T>

Shorthand for sp::Constant.

◆ RemoveVariableUserLeaf_t

template<typename T >
using sp::RemoveVariableUserLeaf_t = typedef typename RemoveVariableUserLeaf<T>::type

Change variable user leaf types to their value types.

This only unwraps outer-most types. So sp::Variable<int, 'x'> becomes int, but sp::VariableUser<T, sp::Variable<int, 'x'>> remains the same.

◆ RemoveVariableUserLeafAndCVRef_t

template<typename T >
using sp::RemoveVariableUserLeafAndCVRef_t = typedef typename RemoveVariableUserLeafAndCVRef<T>::type

Like RemoveVariableUserLeaf, but removes the reference and CV-qualifiers of a leaf's inner type as well.

◆ RemoveVariableUserLeafAndRef_t

template<typename T >
using sp::RemoveVariableUserLeafAndRef_t = typedef typename RemoveVariableUserLeafAndRef<T>::type

Like RemoveVariableUserLeaf_t, but removes the reference of a leaf's inner type as well.

◆ Var

template<VariableName Name, typename T = sp::AnyType>
using sp::Var = typedef Variable<Name, T>

Shorthand for sp::Variable.

◆ VariableName

using sp::VariableName = typedef char32_t

The type to use to identify variables in an expression.

At the moment, this is a single (32-bit) character. But this might get expanded to include strings.

◆ VariableNames

template<char32_t... Cs>
using sp::VariableNames = typedef char32_sequence<Cs...>

A sequence of variable names.

Enumeration Type Documentation

◆ DefaultConstructEnum

Using DefaultConstruct as the Value argument to sp::Constant causes default construction of the type rather than construction with a given value.

Function Documentation

◆ bind()

template<typename T >
constexpr auto sp::bind ( value)
constexpr

Produce a single bound variable.

By default, this binds to a copy of the given value (even if the argument is a reference, the bound variable type will be deduced to be a non-reference). To bind with a reference, explicitly specify a reference type as the template parameter to this function.

◆ getVariableBinding() [1/2]

template<VariableName... Names, typename... Ts, typename Child >
requires (sizeof...(Names) > 0)
constexpr auto sp::getVariableBinding ( const Child &  child,
Ts &&...  values 
)
constexpr

Construct a VariableBinding with values for the given names.

Parameters
childThe variable user.
valuesThe values that are to be bound if getBindResult() is called.
Template Parameters
NamesThe names of the values that are to be bound if getBindResult() is called.

◆ getVariableBinding() [2/2]

template<typename... Ts, typename Child >
requires (sizeof...(Ts) > 0 && sizeof...(Ts) == Child::Vars::Size)
constexpr auto sp::getVariableBinding ( const Child &  child,
Ts &&...  values 
)
constexpr

Construct a VariableBinding with one value for each variable in the VariableUser.

Parameters
childThe variable user.
valuesThe values that are to be bound if getBindResult() is called.
Template Parameters
NamesThe names of the values that are to be bound if getBindResult() is called.

◆ unbind()

template<typename T >
constexpr decltype(auto) sp::unbind ( T &&  value)
constexpr

Remove BoundVariable or Constant from a value.

If the given value is not a BoundVariable or a Constant, then it is returned unchanged.

Variable Documentation

◆ IsBoundVariable_v

template<typename T >
constexpr bool sp::IsBoundVariable_v = IsBoundVariable<T>::value
constexpr

Determine if a type is a bound variable.

◆ IsConstant_v

template<typename T >
constexpr bool sp::IsConstant_v = IsConstant<T>::value
constexpr

Determine if a type is a variable user constant.

◆ IsVariable_v

template<typename T >
constexpr bool sp::IsVariable_v = IsVariable<T>::value
constexpr

Determine if a type is a variable.

◆ IsVariableBinding_v

template<typename T >
constexpr bool sp::IsVariableBinding_v = IsVariableBinding<T>::value
constexpr

Determine if a type is a variable binding.

◆ IsVariableFunctor_v

template<typename T >
constexpr bool sp::IsVariableFunctor_v = IsVariableFunctor<T>::value
constexpr

Determine if a type is a variable functor.

◆ IsVariableTuple_v

template<typename T >
constexpr bool sp::IsVariableTuple_v = IsVariableTuple<T>::value
constexpr

Determine if a type is a variable tuple.

◆ IsVariableUser_v

template<typename T >
constexpr bool sp::IsVariableUser_v = IsVariableUser<T>::value
constexpr

Determine if a type is a variable user.

◆ IsVariableUserLeaf_v

template<typename T >
constexpr bool sp::IsVariableUserLeaf_v = IsVariableUserLeaf<T>::value
constexpr

Determine if a type is one of the variable user leafs.

The variable user leafs are: Constant, BoundVariable, and Variable.