Tools for manipulating variables at run time that can then be bound to values at runtime.
More...
|
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...
|
|
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>
{
private:
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();
Or even more simply:
Example
int result = SimpleVariableUser{}(30, 10, 2);
We can bind some of the variables before binding other variables:
Example
auto bound = SimpleVariableUser{}.bind<'y', 'x'>(10, 30);
int result = bound(2);
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;
int result1 = bound();
x = 12345;
int result2 = bound();
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>,
A type for use with the VariableUser system to represent a compile time constant.
Definition: Var.hpp:807
◆ Const
template<auto Value, typename T = decltype(Value)>
◆ RemoveVariableUserLeaf_t
◆ RemoveVariableUserLeafAndCVRef_t
◆ RemoveVariableUserLeafAndRef_t
Like RemoveVariableUserLeaf_t, but removes the reference of a leaf's inner type as well.
◆ Var
◆ VariableName
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
A sequence of variable names.
◆ DefaultConstructEnum
Using DefaultConstruct as the Value argument to sp::Constant causes default construction of the type rather than construction with a given value.
◆ bind()
template<typename T >
constexpr auto sp::bind |
( |
T |
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
-
child | The variable user. |
values | The values that are to be bound if getBindResult() is called. |
- Template Parameters
-
Names | The 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
-
child | The variable user. |
values | The values that are to be bound if getBindResult() is called. |
- Template Parameters
-
Names | The 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 |
◆ IsBoundVariable_v
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
Determine if a type is a variable binding.
◆ IsVariableFunctor_v
Determine if a type is a variable functor.
◆ IsVariableTuple_v
Determine if a type is a variable tuple.
◆ IsVariableUser_v
Determine if a type is a variable user.
◆ IsVariableUserLeaf_v