|
SpECTRE
v2025.08.19
|
brigand namespace, but in SpECTRE we have aliased this namespace to tmpl, and the latter should be preferred.type member alias that indicates the result: _t suffix. When both versions are provided, it is often convenient (and less error prone!) to define the eager version in terms of the lazy version: _v suffix. These evaluate to compile-time values, rather than types. They can be useful for metaprogramming, but are not the types of metafunctions being discussed here.List1 metafunction being acted upon instead of eager_add_list: type alias from the ultimate base class.tmpl::lazy namespace. These are indicated by calls to the HAS_LAZY_VERSION macro in the examples below.tmpl::_1, tmpl::_2, etc. These are the first, second, etc., arguments of the metalambda, and will be replaced by the actual arguments when the lambda is used. The lazy nature of the metafunctions prevents them from prematurely evaluating to results based on the literal placeholder types. The tmpl::apply function can be used to evaluate a metalambda with specified arguments, and many other Brigand functions take metalambdas that are evaluated internally.tmpl::_1, tmpl::_2, or tmpl::args<n> for unsigned int n. The additional aliases tmpl::_3, tmpl::_4, ..., tmpl::_9 are provided to tmpl::args<2>, tmpl::args<3>, ..., tmpl::args<8>. (The first two arguments have dedicated types in addition to the general tmpl::args<0> and tmpl::args<1>. My best guess is for performance reasons.) tmpl::_1), second (tmpl::_2), or zero-indexed Nth (tmpl::args<N>) entry from the collection of arguments at the top of the argument stack. tmpl::_state and tmpl::_element are aliased to tmpl::_1 and tmpl::_2, primarily for use with tmpl::fold.type type alias is the result of the full lazy-expression. tmpl::bind. It wraps an eager metafunction and its arguments. When evaluated, the arguments are each evaluated as metalambdas, and then the results are passed to the eager metafunction. tmpl::bind metafunction does not convert an eager metafunction to a lazy one. It is handled specially in the evaluation code.tmpl::pin. Evaluating a pin expression gives the (unevaluated) argument to tmpl::pin. This can be used to force a type to be treated as a constant, even if it would normally be treated as a different type of metalambda (usually a lazy expression). tmpl::defer. It does not evaluate its argument, but results in a metaclosure containing the passed metalambda and the current argument stack.Type1 and proceeds to evaluate tmpl::defer<tmpl::_1>.tmpl::_1 and the argument stack from the first apply. This is the result of the inner tmpl::apply.Type2, and proceeds to evaluate the metaclosure created above.tmpl::_1 with a two-element argument stack: head to tail [(Type2), (Type1)].tmpl::_1) in the head of the argument stack is Type2, which is the result of the metaclosure and the entire expression.tmpl::defer are constructing metalambdas to pass to other metafunctions and preventing "speculative" evaluation of a portion of a metalambda that is not valid for some arguments. See the examples below, in particular make_subtracter, multiplication_table, maybe_first, and column_with_zeros.tmpl::parent. It evaluates its argument (treated as a metalambda) after popping the top entry off the argument stack. This provides access to the captured arguments in a metaclosure.tmpl::parent<tmpl::_1> instead of a plain tmpl::_1. The evaluation proceeds as:tmpl::parent<tmpl::_1> with the argument stack [(Type2), (Type1)].tmpl::parent pops the stack, and so evaluates tmpl::_1 with the stack [(Type1)].tmpl::_1) in the stack's head is now Type1, which is the result of the metaclosure and the entire expression.tmpl::parent when the argument stack is empty, i.e., do not attempt to access more sets of captured arguments than have been captured. If you want to prevent evaluation of an expression, use tmpl::pin.tmpl::lazy namespace.L is an empty list tmpl::front<tmpl::list<>> would be evaluated for the first branch. To avoid this we use tmpl::defer to wrap the call to tmpl::front in a metaclosure, which we evaluate only if necessary.L is substituted according to normal C++ rules before any Brigand evaluation. This means that the contents of the tmpl::defer are, for the first call above, tmpl::bind<tmpl::front, tmpl::pin<tmpl::list<Type1>>>. Without the tmpl::pin, the list would be interpreted as a lazy metafunction, resulting in an error because it does not have a type type alias.L in tmpl::size<L> does not need to be protected by a tmpl::pin because tmpl::size is an eager metafunction, so that expression has been converted to a tmpl::integral_constant before the metalambda evaluation starts.tmpl::_1, which is 5 in the example) and the value captured at it's creation (tmpl::parent<tmpl::_1>, which is 3 in the example).make_subtracter could be implemented more simply as tmpl::parent<tmpl::_1>). The tmpl::list (without the tmpl::pin, which has already been evaluated) and metaclosure are then passed to the inner tmpl::lazy::transform.N using the sieve of Eratosthenes. This example defines three helper metafunctions. Two, zero and replace_at, are defined only for clarity's sake and could be inlined. The third, range_from_types, is not easily inlinable, and works around Brigand's lack of sequence generating functions without non-type template parameters. foo being lazy, foo_t being eager, and foo_v being a constexpr value (if applicable). This does not apply to internal-use or special-purpose metafunctions. tmpl::list<T, U, V> is tmpl::list). When taken as a metafunction parameter, these are template template parameters and are usually called Head below.Sequence must be a full specialization of a class template with no non-type template parameters. Many functions do not make sense on sequences with a fixed length, and these require the head of their sequence arguments to take a variable number of template arguments. In practical applications, sequence arguments will usually be specializations of tmpl::list.Predicate must be unary metalambdas returning tmpl::integral_constants of bool or compatible classes.Comparator must be binary metalambdas returning tmpl::integral_constants of bool or compatible classes. They must establish a strict weak ordering on the types they will be applied to in the same manner as runtime comparators from the STL.tmpl::lazy namespace. These cases are indicated by the presence of the HAS_LAZY_VERSION macro in the usage example.value of type T. Very similar to std::integral_constant, except that the constexpr specifiers on the member functions have been omitted. value static member variable.type type alias, integral_constants behave like lazy metafunctions returning themselves. Most lazy metafunctions producing an integral_constant will actually inherit from their result, so value will be directly available without needing to go through the type alias.tmpl::size_t or when necessary for type equality comparison.map that would produce it.set with duplicate entries is an error (but tmpl::insert ignores duplicate entries). See the section on operations on sets for details. set that would produce it.type alias to T. ::type that would otherwise appear is not an evaluation of a lazy metafunction. See tmpl::always or tmpl::identity for similar functionality that is intended for use as a metafunction.tmpl::list<>.false. Similar to std::false_type. true. Similar to std::true_type. n (passed as an unsigned int) of Entry. The head of the list defaults to tmpl::list. T with values n.... tmpl::integral_list when the contents need to be manipulated for more complicated metaprogramming.Start and length n (provided as an unsigned int). The remaining elements are obtained by repeated applications of the metalambda Next, defaulting to tmpl::next. The head of the sequence can be specified, and defaults to tmpl::list. T representing adjacent ascending integers from start to stop, including the starting value and excluding the ending value. T representing adjacent descending integers from start to stop, including the starting value and excluding the ending value. <algorithm>. They are most frequently used with tmpl::list, but similar classes will also work.Predicate is true for all elements of Sequence. The default predicate checks that the element's value is not equal to zero. all to return true. This behaviour may differ by compiler, so it can't be relied upon. Predicate is true for at least one element of Sequence. The default predicate checks that the element's value is not equal to zero. any to return false. This behaviour may differ by compiler, so it can't be relied upon. Sequence, similar to operator[] of the STL containers. The Index is supplied as a tmpl::integral_constant or similar type. Sequence, similar to operator[] of the STL containers. The index n is supplied as an unsigned int. Sequence. Sequence satisfying Predicate. Sequence, initial state State, and metalambda Functor, updates the state by calling Functor on the state and the first element of Sequence, repeats with the second, and so on, returning the final state. tmpl::_state and tmpl::_element aliases to the appropriate arguments for use in folds.bool, whether Predicate matches any element of Sequence. The default predicate checks that the element's value is not equal to zero. Sequence. size_t tmpl::integral_constant of the first type in Sequence satisfying Predicate. Returns NotFound, defaulting to tmpl::no_such_type_ if no elements match. size_t tmpl::integral_constant of the first occurrence of T in Sequence. Returns tmpl::no_such_type_ if the type is not found. T is contained in Sequence, returning a tmpl::integral_constant of bool. Predicate is false for all elements of Sequence. The default predicate checks that the element's value is not equal to zero. none to return true. This behaviour may differ by compiler, so it can't be relied upon. bool, whether Predicate matches no elements of Sequence. The default predicate checks that the element's value is not equal to zero. Sequence as a tmpl::integral_constant of type unsigned int. <algorithm>, but due to the nature of metaprogramming all return a new list rather than modifying an argument. They are most frequently used with tmpl::list, but similar classes will also work.Sequence but no elements. Sequence with the element at index Index (passed as a tmpl::integral_constant or similar type) removed. Sequence with the element at index n (passed as an unsigned int) removed. Predicate from Sequence. Sequence for which Predicate returns true and all subsequent elements. The default predicate checks that the element's value is not equal to zero. Returns an empty list if the predicate returns false for all elements. Sequence that are sequences with the same head. Sequence2 from Sequence1. Sequence for which the Predicate returns true and a list of the elements of Sequence for which the Predicate returns false. Count elements from the end of Sequence. The number of elements to remove is supplied as a tmpl::integral_constant and defaults to 1. Count elements from the beginning of Sequence. The number of elements to remove is supplied as a tmpl::integral_constant and defaults to 1. T... to Sequence. T... to Sequence. The order of the prepended items is retained: they are pushed as a unit, not one-by-one. T from Sequence. Sequence. The first occurrence of each type is kept. Predicate from Sequence. Old in Sequence with New. Sequence matching Predicate with T. Sequence. Sequence for which Predicate returns true and all preceding elements. The default predicate checks that the element's value is not equal to zero. Returns an empty list if the predicate returns false for all elements. Sequence, initial state State, and metalambda Functor, updates the state by calling Functor on the state and the last element of Sequence, repeats with the second to last, and so on, returning the final state. tmpl::_state and tmpl::_element aliases to the appropriate arguments for use in folds.Sequence according to Comparator, which defaults to tmpl::less. Sequence into parts separated by Delimiter, discarding empty parts. Index (supplied as a tmpl::integral_constant) elements or Sequence, and the second containing the remaining elements. Functor on each element of Sequence, collecting the results in a new list. If additional Sequences... are supplied, elements from those lists are passed as additional arguments to Functor. Key in Map. Returns tmpl::no_such_type_ if Key is not in the map. Map with the element with the key Key removed. If Key is not in the map, returns Map unchanged. bool indicating whether Map contains the key Key. Map with Pair added. If the key of Pair is already in the map, the map is returned unchanged. Map as a sequence with head Head, defaulting to tmpl::set. Key in Map. Returns tmpl::no_such_type_ if Key is not in the map. Key in Map, wrapped in a tmpl::type_. Returns type_<no_such_type_> if Key is not in the map. This function has no eager version, but is still in the tmpl::lazy namespace. Map as a sequence with head Head, defaulting to tmpl::list. bool indicating whether Set contains T. Set with the element T removed. If the element is not in the set, returns the set unchanged. bool indicating whether Set contains T. Set containing an additional element T. If T is already in the set, the set is returned unchanged. value static member type of type value_type). The results inherit from tmpl::integral_constants of types noted below.value. This is not generally the same type as the language operator, even when the types of the values of both arguments are the same. (The integer promotion and conversion rules are not applied.) bool. bool. They should only be used on types wrapping bools. The and_ and or_ structs can take any number of arguments. T1 and T2, returning a tmpl::integral_constant of the common type of its arguments. T1 and T2, returning a tmpl::integral_constant of the common type of its arguments. T plus one, returning a tmpl::integral_constant of the same type as its argument. T minus one, returning a tmpl::integral_constant of the same type as its argument. Lambda with arguments Arguments.... unsigned int. TrueResult if the bool b is true, otherwise FalseResult. An optimized version of std::conditional_t. Condition has a true value, evaluates and returns the result of the lazy metafunction (not metalambda) TrueFunction, otherwise, evaluates and returns the result of the lazy metafunction FalseFunction. bool instead of a type. T (defaulting to void), ignoring its first argument. TrueResult if the value static member value of Condition is true, and otherwise FalseResult. Sequence into a linked list. The NodePattern must be a class template (not a lazy metafunction) instantiated with metalambdas. The function performs a left fold, with the Root (defaulting to tmpl::empty_base) as the initial state and the transform function evaluating the arguments to the node pattern. bool. RealType at compile time via its internal memory representation. The value is stored as a tmpl::integral_constant of type IntType with value value (which must be the same size as RealType) and can be extracted at runtime using the conversion operator. Brigand provides the aliases single_<value> and double_<value> with RealType and IntType set to appropriate values. Function on Initial, then on the result of that, then on the result of that, and so on, up to Count calls. sizeof its argument as an unsigned int tmpl::integral_constant. ArgumentList for appearances of tmpl::args (but not tmpl::_1 or tmpl::_2) appearing in Pattern. type from T. type type alias, but, when used outside of a metafunction, it should only be used with tmpl::type_ for clarity.Sequence with Head. functor on each of arguments..., in order. Returns functor. functor on tmpl::type_ objects wrapping each type in Sequence, in order. Returns functor. true_result if Condition's value member is true, and false_result if it is false. as_X taking a list and X_wrapper taking a parameter pack. This makes X_wrapper equivalent to the wrapped class.*_wrapper functions in favor of using the class directly.boost::fusion types deque, list, set, and vector, as well as boost::variant. Because we use brigand instead of boost::fusion and because std::variant replaces boost::variant, these are not available in SpECTRE.pair_wrapper_, which is a lazy form of pair_wrapper. The pair functions all assert that they have received two types. value_type and a value) to tmpl::integral_constant. The lazy metafunction make_integral performs this conversion. The as_integral_list eager metafunction performs this operation on all elements of a list. as_integral_list.as_sequence, is equivalent to tmpl::wrap. The specialized version, tmpl::as_list, produces a tmpl::list. as_list is often not necessary because most metafunctions operate on arbitrary template classes.unsigned int and size_t for size-related things. (Most blatantly, the result of sizeof_<T> is represented as an unsigned int.)