Line data Source code
1 0 : \cond NEVER
2 : Distributed under the MIT License.
3 : See LICENSE.txt for details.
4 : \endcond
5 : # Metaprogramming with Brigand {#brigand}
6 :
7 : \tableofcontents
8 :
9 : \note
10 : This document covers Brigand as of commit
11 : [66b3d9276ed95425ac919ac1841286d088b5f4b1](https://github.com/edouarda/brigand/commit/66b3d9276ed95425ac919ac1841286d088b5f4b1)
12 : in January 2022.
13 :
14 : \tableofcontents{HTML:2}
15 :
16 : [comment]: # (The \pars improve the spacing in the generated document when)
17 : [comment]: # (many \snippets are involved.)
18 :
19 : \par
20 : In SpECTRE, most complex TMP is done using the [Brigand metaprogramming
21 : library](https://github.com/edouarda/brigand). Brigand is a collection of
22 : templated classes, type aliases, and functions, primarily intended to help with
23 : the manipulation and use of lists of types. This document is organized to
24 : roughly parallel the structure of the C++ standard, rather than following
25 : Brigand's classifications.
26 :
27 : \par
28 : Brigand provides all of its functionality in the `brigand` namespace, but in
29 : SpECTRE we have aliased this namespace to `tmpl`, and the latter should be
30 : preferred.
31 :
32 : \par
33 : All functionality described here is provided by SpECTRE's Brigand wrapper
34 : header:
35 : \snippet Test_TMPLDocumentation.cpp include
36 :
37 : \par
38 : Examples in this document use the following declarations and definitions:
39 : \snippet Test_TMPLDocumentation.cpp example_declarations
40 :
41 :
42 : \section Metafunctions
43 :
44 : \par
45 : A metafunction is an analog of a familiar C++ function that is coded in the C++
46 : type system. It turns out that, using metafunction programming, it is possible
47 : to perform arbitrary computations at compile time.
48 :
49 : \par
50 : There are multiple ways to encode a calculation in the type system. When using
51 : Brigand, the relevant ones are eager and lazy metafunctions.
52 :
53 :
54 : \subsection lazy Eager and lazy metafunctions
55 :
56 : \par
57 : Metafunctions commonly appear in two forms: eager and lazy. Lazy metafunctions
58 : are templated structs (or templated aliases to structs) with a `type` member
59 : alias that indicates the result:
60 : \snippet Test_TMPLDocumentation.cpp metafunctions:lazy
61 : The type traits in the standard library, such as std::is_same, are lazy
62 : metafunctions.
63 :
64 : \par
65 : Eager metafunctions are aliases to their result types. As a trivial case,
66 : struct templates can be viewed as eager metafunctions returning themselves. An
67 : eager version of the previous example could be implemented as:
68 : \snippet Test_TMPLDocumentation.cpp metafunctions:eager
69 : The standard library provides eager versions of some of its metafunctions
70 : (generally those that modify a type, rather than predicates) using an `_t`
71 : suffix. When both versions are provided, it is often convenient (and less
72 : error prone!) to define the eager version in terms of the lazy version:
73 : \snippet Test_TMPLDocumentation.cpp metafunctions:eager_from_lazy
74 : And the two definitions agree:
75 : \snippet Test_TMPLDocumentation.cpp metafunctions:agreement
76 :
77 : \note
78 : The standard library also provides versions of many of its type traits with an
79 : `_v` suffix. These evaluate to compile-time *values*, rather than types. They
80 : can be useful for metaprogramming, but are not the types of metafunctions being
81 : discussed here.
82 :
83 : \par
84 : Eager metafunctions are usually more convenient to use, so what is the point of
85 : additionally creating lazy ones? The answer is that lazy metafunctions can be
86 : used as compile-time functors. As a simple example, we can write an (eager)
87 : metafunction that calls an arbitrary lazy metafunction twice
88 : \snippet Test_TMPLDocumentation.cpp metafunctions:call_lazy_metafunction
89 : and get the expected output:
90 : \snippet Test_TMPLDocumentation.cpp metafunctions:call_lazy_metafunction_assert
91 : But it fails if you try to call an arbitrary *eager* metafunction
92 : twice in the same way, because the function is evaluated too early,
93 : resulting in the `List1` metafunction being acted upon instead of
94 : `eager_add_list`:
95 : \snippet Test_TMPLDocumentation.cpp metafunctions:call_eager_metafunction
96 : \snippet Test_TMPLDocumentation.cpp metafunctions:call_eager_metafunction_assert
97 : (In this simple case we could have used a template template parameter to pass
98 : the eager metafunction in a form more similar to a runtime lambda, but the
99 : possibilities for generic manipulation of parameter lists containing template
100 : template parameters are limited, so their use must be minimized in complex
101 : metaprogramming.)
102 :
103 : \note
104 : In practice, lazy metafunctions are often implemented as empty structs
105 : inheriting from other lazy metafunctions. The entire inheritance chain then
106 : inherits a `type` alias from the ultimate base class.
107 :
108 : \par
109 : Most of the standard Brigand functions are eager, but many have lazy versions
110 : in the nested `tmpl::lazy` namespace. These are indicated by calls to the
111 : `HAS_LAZY_VERSION` macro in the examples below.
112 :
113 :
114 : \subsection metalambdas Brigand metalambdas
115 :
116 : \par
117 : This use of lazy metafunctions is too limited for general use, however, because
118 : it requires the definition of a new templated struct for every new function.
119 : Brigand uses a more general notation, known as metalambdas. A metalambda is a
120 : (possibly nested set of) lazy metafunctions with some template arguments
121 : replaced by the placeholders `tmpl::_1`, `tmpl::_2`, etc. These are the first,
122 : second, etc., arguments of the metalambda, and will be replaced by the actual
123 : arguments when the lambda is used. The lazy nature of the metafunctions
124 : prevents them from prematurely evaluating to results based on the literal
125 : placeholder types. The \ref apply "tmpl::apply" function can be used to
126 : evaluate a metalambda with specified arguments, and many other Brigand
127 : functions take metalambdas that are evaluated internally.
128 :
129 :
130 : \subsection metalambda_structure Evaluation of metalambdas
131 :
132 : \note
133 : None of the terminology introduced in this section is standard.
134 :
135 : \par
136 : When evaluating a metalambda, the values of any \ref args "arguments"
137 : encountered are taken from the evaluation's argument stack. The argument stack
138 : is a stack (in the CS sense) of collections of zero or more arguments. The
139 : values of any \ref args "arguments" that are evaluated are taken from the
140 : collection at the head of the stack. The remaining collections are arguments
141 : captures in closures, and will not be present in code not using \ref defer
142 : "tmpl::defer".
143 :
144 : \par
145 : The \ref apply "tmpl::apply" metafunction is the Brigand metafunction for
146 : evaluating metalambdas. It can be called explicitly, and is called internally
147 : by many other functions. It takes a metalambda and arguments to be passed to
148 : that metalambda. The argument stack for the evaluation has one entry: the
149 : passed arguments.
150 :
151 : \par
152 : The argument stack can gain additional entries through the creation of
153 : metaclosures using \ref defer "tmpl::defer". When \ref defer "tmpl::defer" is
154 : evaluated, it produces a \ref metalambda_metaclosure "metaclosure" containing a
155 : copy of the current argument stack, acting as the lambda captures. When that
156 : metaclosure is evaluated, the previously active stack is replaced by the stored
157 : stack with the head of the old stack pushed onto it.
158 :
159 : \par
160 : This makes \ref args "arguments" in a \ref metalambda_metaclosure "metaclosure"
161 : refer to the arguments "passed" to it. (No explicit call syntax is used, but
162 : the arguments are inherited from the calling context.) The captured arguments
163 : are accessible using \ref parent "tmpl::parent", which pops off the last entry
164 : in the argument stack.
165 :
166 : \par
167 : There are eight forms that a metalambda can take: an argument, a lazy
168 : expression, a bind expression, a pin expression, a defer expression, a parent
169 : expression, a constant, or a metaclosure.
170 :
171 : \subsubsection args Argument
172 :
173 : \par
174 : An argument is one of the structs `tmpl::_1`, `tmpl::_2`, or `tmpl::args<n>`
175 : for `unsigned int` n. The additional aliases `tmpl::_3`, `tmpl::_4`, ...,
176 : `tmpl::_9` are provided to `tmpl::args<2>`, `tmpl::args<3>`, ...,
177 : `tmpl::args<8>`. (The first two arguments have dedicated types in addition to
178 : the general `tmpl::args<0>` and `tmpl::args<1>`. My best guess is for
179 : performance reasons.)
180 : \snippet Test_TMPLDocumentation.cpp tmpl::args
181 : When evaluated, they give the first (`tmpl::_1`), second (`tmpl::_2`), or
182 : zero-indexed Nth (`tmpl::args<N>`) entry from the collection of arguments at
183 : the top of the argument stack.
184 : \snippet Test_TMPLDocumentation.cpp tmpl::args:eval
185 : Additionally, `tmpl::_state` and `tmpl::_element` are aliased to `tmpl::_1` and
186 : `tmpl::_2`, primarily for use with \ref fold "tmpl::fold".
187 :
188 : \par
189 : When evaluating a metalambdas, the metalambda must be passed enough arguments
190 : to define all argument placeholders in its body. When evaluating using \ref
191 : apply "tmpl::apply", arguments are passed as template parameters after the
192 : metalambda. Other Brigand functions that evaluate metalambdas pass them a
193 : specified number of arguments (usually 1 or 2). Failure to pass enough
194 : arguments may error or produce unintuitive results.
195 :
196 : \subsubsection metalambda_lazy Lazy expression
197 :
198 : \par
199 : A lazy expression is a fully-specialized struct template with only type
200 : template parameters that is not a specialization of \ref pin "tmpl::pin", \ref
201 : defer "tmpl::defer", or \ref parent "tmpl::parent" and is not a \ref
202 : metalambda_metaclosure "metaclosure". When evaluated, each of its template
203 : parameters is evaluated as a metalambda and replaced by the result, and then
204 : the struct's `type` type alias is the result of the full lazy-expression.
205 : \snippet Test_TMPLDocumentation.cpp metalambda_lazy
206 :
207 : \subsubsection bind Bind expression
208 :
209 : \par
210 : A bind expression is a specialization of `tmpl::bind`. It wraps an eager
211 : metafunction and its arguments. When evaluated, the arguments are each
212 : evaluated as metalambdas, and then the results are passed to the eager
213 : metafunction.
214 : \snippet Test_TMPLDocumentation.cpp tmpl::bind
215 :
216 : \note
217 : The `tmpl::bind` metafunction does not convert an eager metafunction to a lazy
218 : one. It is handled specially in the evaluation code.
219 :
220 : \subsubsection pin Pin expression
221 :
222 : \par
223 : A pin expression is a specialization of `tmpl::pin`. Evaluating a pin
224 : expression gives the (unevaluated) argument to `tmpl::pin`. This can be used
225 : to force a type to be treated as a \ref metalambda_constant "constant", even if
226 : it would normally be treated as a different type of metalambda (usually a \ref
227 : metalambda_lazy "lazy expression").
228 : \snippet Test_TMPLDocumentation.cpp tmpl::pin
229 :
230 : \par
231 : Pin expressions are often used to protect template arguments to eager
232 : metafunctions:
233 : \snippet Test_TMPLDocumentation.cpp tmpl::pin:protect_eager
234 :
235 : \subsubsection defer Defer expression
236 :
237 : \par
238 : A defer expression is a specialization of `tmpl::defer`. It does not evaluate
239 : its argument, but results in a \ref metalambda_metaclosure "metaclosure"
240 : containing the passed metalambda and the current argument stack.
241 :
242 : \par
243 : Example:
244 : \snippet Test_TMPLDocumentation.cpp tmpl::defer
245 : The evaluation here proceeds as follows:
246 :
247 : 1. The innermost eager metafunction is the second \ref apply "tmpl::apply". It
248 : creates an argument stack with one collection containing the single argument
249 : `Type1` and proceeds to evaluate `tmpl::defer<tmpl::_1>`.
250 :
251 : 2. Evaluating the defer expression creates a \ref metalambda_metaclosure
252 : "metaclosure" with the contents `tmpl::_1` and the argument stack from the
253 : first apply. This is the result of the inner \ref apply "tmpl::apply".
254 :
255 : 3. Next the outer \ref apply "tmpl::apply" is evaluated. It creates an
256 : argument stack with one collection containing the single argument`Type2`,
257 : and proceeds to evaluate the \ref metalambda_metaclosure "metaclosure"
258 : created above.
259 :
260 : [comment]: # (Keep the numbering here in sync with the `parent` example.)
261 :
262 : 4. Evaluating the \ref metalambda_metaclosure "metaclosure" (see that section
263 : below) evaluates the contained `tmpl::_1` with a two-element argument stack:
264 : head to tail [(`Type2`), (`Type1`)].
265 :
266 : 5. The first (and only) argument (`tmpl::_1`) in the head of the argument stack
267 : is `Type2`, which is the result of the \ref metalambda_metaclosure
268 : "metaclosure" and the entire expression.
269 :
270 :
271 : \par
272 : The primary purposes for `tmpl::defer` are constructing metalambdas to pass to
273 : other metafunctions and preventing "speculative" evaluation of a portion of a
274 : metalambda that is not valid for some arguments. See the examples below, in
275 : particular \ref make_subtracter, \ref multiplication_table, \ref maybe_first,
276 : and \ref column_with_zeros.
277 :
278 : \subsubsection parent Parent expression
279 :
280 : \par
281 : A parent expression is a specialization of `tmpl::parent`. It evaluates its
282 : argument (treated as a metalambda) after popping the top entry off the argument
283 : stack. This provides access to the captured arguments in a \ref
284 : metalambda_metaclosure "metaclosure".
285 :
286 : \par
287 : Example:
288 : \snippet Test_TMPLDocumentation.cpp tmpl::parent
289 : The creation of the \ref metalambda_metaclosure "metaclosure" here is similar
290 : to the example for \ref defer "tmpl::defer", except that the contained
291 : metalambda is `tmpl::parent<tmpl::_1>` instead of a plain `tmpl::_1`. The
292 : evaluation proceeds as:
293 :
294 : 1. As in \ref defer "tmpl::defer" example.
295 :
296 : 2. As in \ref defer "tmpl::defer" example.
297 :
298 : 3. As in \ref defer "tmpl::defer" example.
299 :
300 : 4. The \ref metalambda_metaclosure "metaclosure" evaluates the contained
301 : `tmpl::parent<tmpl::_1>` with the argument stack [(`Type2`), (`Type1`)].
302 :
303 : 5. Evaluating the `tmpl::parent` pops the stack, and so evaluates `tmpl::_1`
304 : with the stack [(`Type1`)].
305 :
306 : 6. The first (and only) argument (`tmpl::_1`) in the stack's head is now
307 : `Type1`, which is the result of the \ref metalambda_metaclosure
308 : "metaclosure" and the entire expression.
309 :
310 : \warning
311 : Do not call `tmpl::parent` when the argument stack is empty, i.e., do not
312 : attempt to access more sets of captured arguments than have been captured. If
313 : you want to prevent evaluation of an expression, use \ref pin "tmpl::pin".
314 :
315 : \subsubsection metalambda_constant Constant
316 :
317 : \par
318 : A constant metalambda is any type that is not a struct template with only type
319 : template parameters, a specialization of \ref bind "tmpl::bind", or a
320 : metaclosure. A constant metalambda evaluates to itself.
321 : \snippet Test_TMPLDocumentation.cpp metalambda_constant
322 :
323 : \subsubsection metalambda_metaclosure Metaclosure
324 :
325 : \par
326 : A metaclosure is an opaque type produced by \ref defer "tmpl::defer",
327 : containing a metalambda and an argument stack. When a metaclosure is
328 : evaluated, it evaluates the packaged metalambda with an argument stack
329 : constructed by pushing the head of the current argument stack onto the argument
330 : stack stored in the metaclosure. See \ref defer and \ref parent for examples.
331 :
332 :
333 : \subsection Examples
334 :
335 :
336 : \subsubsection evens
337 :
338 : \par
339 : Finds all numbers in a list that are even.
340 : \snippet Test_TMPLDocumentation.cpp metafunctions:evens
341 : \snippet Test_TMPLDocumentation.cpp metafunctions:evens:asserts
342 :
343 : \par
344 : The \ref filter "tmpl::filter" metafunction takes a metalambda as its second
345 : argument. The \ref integral_constant "tmpl::integral_constant"s have non-type
346 : template parameters, so they are treated as constant expressions. The \ref
347 : math_comparison "tmpl::equal_to" and \ref math_arithmetic "tmpl::modulo"
348 : metafunctions are lazy, despite not being in the `tmpl::lazy` namespace.
349 :
350 :
351 : \subsubsection maybe_first
352 :
353 : \par
354 : Returns the first element of a list, or \ref no_such_type_ "tmpl::no_such_type_"
355 : if the list is empty.
356 : \snippet Test_TMPLDocumentation.cpp metafunctions:maybe_first
357 : \snippet Test_TMPLDocumentation.cpp metafunctions:maybe_first:asserts
358 :
359 : \par
360 : In this example, the inner \ref apply "tmpl::apply" call evaluates the \ref if_
361 : "tmpl::if_" statement, returning either a \ref metalambda_metaclosure
362 : "metaclosure" or \ref no_such_type_ "tmpl::no_such_type_". The outer \ref
363 : apply "tmpl::apply" either evaluates the metaclosure, calling \ref front
364 : "tmpl::front", or evaluates \ref no_such_type_ "tmpl::no_such_type_", which is
365 : a constant and gives itself.
366 :
367 : \par
368 : The reason for creating a metaclosure is that all the arguments to \ref if_
369 : "tmpl::if_" are always evaluated (it is an ordinary metafunction with no
370 : special treatment during evaluation). This is a problem, because, in a naive
371 : attempt at this metafunction, if `L` is an empty list
372 : `tmpl::front<tmpl::list<>>` would be evaluated for the first branch. To avoid
373 : this we use \ref defer "tmpl::defer" to wrap the call to \ref front
374 : "tmpl::front" in a metaclosure, which we evaluate only if necessary.
375 :
376 : \par
377 : Note that this metaclosure does not capture anything. `L` is substituted
378 : according to normal C++ rules before any Brigand evaluation. This means that
379 : the contents of the `tmpl::defer` are, for the first call above,
380 : `tmpl::bind<tmpl::front, tmpl::pin<tmpl::list<Type1>>>`. Without the \ref pin
381 : "tmpl::pin", the list would be interpreted as a lazy metafunction, resulting in
382 : an error because it does not have a `type` type alias.
383 :
384 : \par
385 : The `L` in `tmpl::size<L>` does not need to be protected by a \ref pin
386 : "tmpl::pin" because \ref size "tmpl::size" is an eager metafunction, so that
387 : expression has been converted to a \ref integral_constant
388 : "tmpl::integral_constant" before the metalambda evaluation starts.
389 :
390 :
391 : \subsubsection factorial
392 :
393 : \par
394 : Calculates the factorial using a simple metalambda passed to a \ref fold
395 : "tmpl::fold".
396 : \snippet Test_TMPLDocumentation.cpp metafunctions:factorial
397 : \snippet Test_TMPLDocumentation.cpp metafunctions:factorial:asserts
398 :
399 : \par
400 : A nearly literal rewrite of this into runtime C++ is
401 : \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_cpp
402 :
403 : \par
404 : The equivalent of a range-based for loop is easier to express in functional
405 : programming (as a fold) than a standard counting for loop.
406 :
407 :
408 : \subsubsection make_subtracter
409 :
410 : \par
411 : Demonstrates the use of captures in metalambdas.
412 : \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter
413 : \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter:asserts
414 :
415 : \par
416 : This metafunction returns a \ref metalambda_metaclosure "metaclosure" that
417 : subtracts a given number from it's argument. That metaclosure uses both the
418 : argument passed to it (`tmpl::_1`, which is 5 in the example) and the value
419 : captured at it's creation (`tmpl::parent<tmpl::_1>`, which is 3 in the
420 : example).
421 :
422 : \par
423 : (This `make_subtracter` could be implemented more simply as
424 : \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter_simple
425 : but that doesn't demonstrate metaclosures.)
426 :
427 :
428 : \subsubsection multiplication_table
429 :
430 : \par
431 : Constructs a multiplication table.
432 : \snippet Test_TMPLDocumentation.cpp metafunctions:multiplication_table
433 : \snippet Test_TMPLDocumentation.cpp metafunctions:multiplication_table:asserts
434 :
435 : \par
436 : This demonstrates the use of \ref defer "tmpl::defer" to pass a closure as an
437 : argument to a metafunction (\ref transform "tmpl::lazy::transform"), while
438 : capturing an argument from the outer context (the metalambda evaluated for the
439 : outer \ref transform "tmpl::transform"). This is the use most similar to
440 : common uses of the C++ lambda.
441 :
442 : \par
443 : The outer (eager) \ref transform "tmpl::transform" evaluates its second
444 : argument as a metalambda. This first evaluates the arguments to the inner \ref
445 : transform "tmpl::lazy::transform". The first argument is a \ref list
446 : "tmpl::list" of \ref integral_constant "tmpl::integral_constant"s (because the
447 : \ref range "tmpl::range" is eager and has already been evaluated). This must
448 : be protected by a \ref pin "tmpl::pin" because it looks like a lazy
449 : metafunction. The second argument gives a metaclosure, capturing the value
450 : from the outer \ref transform "tmpl::transform" (available as
451 : `tmpl::parent<tmpl::_1>`). The \ref list "tmpl::list" (without the \ref pin
452 : "tmpl::pin", which has already been evaluated) and metaclosure are then passed
453 : to the inner \ref transform "tmpl::lazy::transform".
454 :
455 :
456 : \subsubsection column_with_zeros
457 :
458 : \par
459 : Extracts a column from a row-major matrix, extending any short rows with zeros.
460 : \snippet Test_TMPLDocumentation.cpp metafunctions:column_with_zeros
461 : \snippet Test_TMPLDocumentation.cpp metafunctions:column_with_zeros:asserts
462 :
463 : \par
464 : This example shows another use of \ref defer "tmpl::defer" to avoid evaluating
465 : an invalid expression, similar to \ref maybe_first. The use of an \ref args
466 : "argument" in the deferred branch makes this case more complicated: a \ref
467 : parent "tmpl::parent" expression is used to access arguments from where the
468 : \ref defer "tmpl::defer" occurs to avoid having to pass the argument explicitly
469 : using the \ref apply "tmpl::apply" call.
470 :
471 : \par
472 : This is the "apply-defer-parent" pattern for lazy evaluation. A \ref parent
473 : "tmpl::parent" is placed immediately inside a \ref defer "tmpl::defer" with a
474 : (not immediately) surrounding \ref apply "tmpl::apply". The \ref apply
475 : "tmpl::apply" and \ref defer "tmpl::defer" collectively add an (empty) element
476 : to the head of the argument stack, which is then popped off to restore the
477 : original value. This causes the interior metalambda to have the same result it
478 : would have had without the \ref defer "tmpl::defer".
479 :
480 :
481 : \subsubsection factorial_recursion
482 :
483 : \par
484 : Again calculates the factorial, but using a recursive algorithm.
485 : \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_recursion
486 : \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_recursion:asserts
487 :
488 : \par
489 : This is a direct translation of the common definition \f$f(N) = N f(N-1)\f$ for
490 : nonzero \f$N\f$, and \f$f(0) = 1\f$. The metalambda is passed a copy of itself
491 : as the first argument and the value to take the factorial of as the second.
492 :
493 : \par
494 : This again uses the "apply-defer-parent" pattern to prevent "speculative"
495 : evaluation of conditional branches. In this example, speculative evaluation of
496 : the branch is invalid because it would recurse infinitely.
497 :
498 :
499 : \subsubsection primes
500 :
501 : \par
502 : Generates a list of prime numbers less than `N` using the sieve of
503 : Eratosthenes. This example defines three helper metafunctions. Two, `zero`
504 : and `replace_at`, are defined only for clarity's sake and could be inlined.
505 : The third, `range_from_types`, is not easily inlinable, and works around
506 : Brigand's lack of sequence generating functions without non-type template
507 : parameters.
508 : \snippet Test_TMPLDocumentation.cpp metafunctions:primes
509 : \snippet Test_TMPLDocumentation.cpp metafunctions:primes:asserts
510 :
511 : \par
512 : This is roughly equivalent to the following C++ code with loops converted to
513 : fold expressions over ranges.
514 : \snippet Test_TMPLDocumentation.cpp metafunctions:primes_cpp
515 :
516 :
517 : \section metafunction_guidelines Guidelines for writing metafunctions
518 :
519 : \par
520 : This section covers a few general guidelines for writing metafunctions in
521 : SpECTRE. Some of the Brigand functions mentioned below have specific advice as
522 : well.
523 :
524 : 1. For general metafunctions, write both lazy and eager versions. Follow the
525 : STL convention of `foo` being lazy, `foo_t` being eager, and `foo_v` being a
526 : constexpr value (if applicable). This does not apply to internal-use or
527 : special-purpose metafunctions.
528 : \snippet Test_TMPLDocumentation.cpp guidelines:lazy_eager
529 :
530 : 2. Don't perform unnecessary return-type conversions. We often recommend using
531 : STL types over equivalent Brigand types, but if the implementation naturally
532 : produces a Brigand type do not do extra work to convert it.
533 :
534 :
535 : \section function_docs Brigand types and functions
536 :
537 : \par
538 : In this section, CamelCase identifiers indicate [type template
539 : parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Type_template_parameter)
540 : or, occasionally, [template template
541 : parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Template_template_parameter).
542 : Identifiers in all lowercase indicate [non-type template
543 : parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter).
544 : Identifiers in [brackets] are optional, and the default value will be
545 : identified in the prose description. Identifiers with ellipses... represent
546 : zero or more parameters.
547 :
548 : \par
549 : The *head* of a fully specialized class template is the class template itself
550 : (e.g., the head of `tmpl::list<T, U, V>` is `tmpl::list`). When taken as a
551 : metafunction parameter, these are template template parameters and are usually
552 : called `Head` below.
553 :
554 : \par
555 : An identifier called `Sequence` must be a full specialization of a class
556 : template with no non-type template parameters. Many functions do not make
557 : sense on sequences with a fixed length, and these require the head of their
558 : sequence arguments to take a variable number of template arguments. In
559 : practical applications, sequence arguments will usually be specializations of
560 : \ref list "tmpl::list".
561 :
562 : \par
563 : Parameters called `Predicate` must be unary metalambdas returning \ref
564 : integral_constant "tmpl::integral_constant"s of `bool` or compatible classes.
565 :
566 : \par
567 : Parameters called `Comparator` must be binary metalambdas returning \ref
568 : integral_constant "tmpl::integral_constant"s of `bool` or compatible classes.
569 : They must establish a [strict weak
570 : ordering](https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings) on
571 : the types they will be applied to in the same manner as runtime comparators
572 : from the STL.
573 :
574 : \par
575 : Metafunctions documented here are eager unless otherwise noted. In many cases,
576 : Brigand provides lazy versions of its metafunctions under the same name in the
577 : `tmpl::lazy` namespace. These cases are indicated by the presence of the
578 : `HAS_LAZY_VERSION` macro in the usage example.
579 :
580 :
581 : \subsection Containers
582 :
583 : \par
584 : Brigand provides container classes with the sole purpose of wrapping other
585 : things.
586 :
587 :
588 : \subsubsection integral_constant integral_constant<T, value>
589 :
590 : \par
591 : A compile-time value `value` of type `T`. Very similar to
592 : std::integral_constant, except that the `constexpr` specifiers on the member
593 : functions have been omitted.
594 : \snippet Test_TMPLDocumentation.cpp tmpl::integral_constant
595 :
596 : \par
597 : Brigand supplies type aliases for constants of some specific types:
598 : \snippet Test_TMPLDocumentation.cpp tmpl::integral_constant::abbreviations
599 :
600 : \par
601 : Most metafunctions that accept integral_constants will accept any type with a
602 : `value` static member variable.
603 :
604 : \par
605 : Because of the `type` type alias, integral_constants behave like lazy
606 : metafunctions returning themselves. Most lazy metafunctions producing an
607 : integral_constant will actually inherit from their result, so `value` will be
608 : directly available without needing to go through the `type` alias.
609 :
610 : \remark
611 : Prefer std::integral_constant, except for the convenience wrapper
612 : `tmpl::size_t` or when necessary for type equality comparison.
613 :
614 :
615 : \subsubsection list list<T...>
616 :
617 : \par
618 : An empty struct templated on a parameter pack, with no additional
619 : functionality.
620 : \snippet Test_TMPLDocumentation.cpp tmpl::list
621 :
622 : \par
623 : Most metafunctions that operate on lists will work on any struct template.
624 :
625 :
626 : \subsubsection map map<Pair...>
627 :
628 : \par
629 : A collection of key-value \ref pair "tmpl::pair"s with unique keys. See the
630 : section on \ref map_operations "operations on maps" for details.
631 : \snippet Test_TMPLDocumentation.cpp tmpl::map
632 :
633 : \par
634 : The actual type of a map is unspecified, but it has the same template
635 : parameters as a call to `map` that would produce it.
636 :
637 : \warning
638 : Equivalent maps may have different types, depending on the order their keys are
639 : stored in internally.
640 :
641 :
642 : \subsubsection pair pair<T1, T2>
643 :
644 : \par
645 : A pair of types, with easy access to each type in the pair.
646 : \snippet Test_TMPLDocumentation.cpp tmpl::pair
647 :
648 :
649 : \subsubsection set set<T...>
650 :
651 : \par
652 : An unordered collection of distinct types. Trying to create a `set` with
653 : duplicate entries is an error (but \ref set_insert "tmpl::insert" ignores
654 : duplicate entries). See the section on \ref set_operations
655 : "operations on sets" for details.
656 : \snippet Test_TMPLDocumentation.cpp tmpl::set
657 :
658 : \par
659 : The actual type of a set is unspecified, but it has the same template
660 : parameters as a call to `set` that would produce it.
661 :
662 : \warning
663 : Equivalent sets may have different types, depending on the order their elements
664 : are stored in internally.
665 :
666 :
667 : \subsubsection type_ type_<T>
668 :
669 : \par
670 : A struct containing a `type` alias to `T`.
671 : \snippet Test_TMPLDocumentation.cpp tmpl::type_
672 :
673 : \par
674 : When extracting the type, programmers are encouraged to use \ref type_from
675 : "tmpl::type_from" to make it clear that the \c \::type that would otherwise
676 : appear is not an evaluation of a lazy metafunction. See \ref always
677 : "tmpl::always" or \ref identity "tmpl::identity" for similar functionality that
678 : is intended for use as a metafunction.
679 :
680 :
681 : \subsection Constants
682 :
683 : \par
684 : Brigand defines a few concrete types and type aliases.
685 :
686 :
687 : \subsubsection empty_base
688 :
689 : \par
690 : An empty struct used by \ref inherit "tmpl::inherit" and \ref inherit_linearly
691 : "tmpl::inherit_linearly". Primarily for internal use.
692 : \snippet Test_TMPLDocumentation.cpp tmpl::empty_base
693 :
694 :
695 : \subsubsection empty_sequence
696 :
697 : \par
698 : An empty \ref list "tmpl::list".
699 : \snippet Test_TMPLDocumentation.cpp tmpl::empty_sequence
700 :
701 : \remark
702 : Prefer just writing `tmpl::list<>`.
703 :
704 :
705 : \subsubsection false_type
706 :
707 : \par
708 : A \ref integral_constant "tmpl::integral_constant" representing `false`.
709 : Similar to std::false_type.
710 : \snippet Test_TMPLDocumentation.cpp tmpl::false_type
711 :
712 : \remark
713 : Prefer std::false_type.
714 :
715 :
716 : \subsubsection no_such_type_
717 :
718 : \par
719 : An empty struct returned as the failure case for various searching operations.
720 : \snippet Test_TMPLDocumentation.cpp tmpl::no_such_type_
721 :
722 :
723 : \subsubsection true_type
724 :
725 : \par
726 : A \ref integral_constant "tmpl::integral_constant" representing `true`.
727 : Similar to std::true_type.
728 : \snippet Test_TMPLDocumentation.cpp tmpl::true_type
729 :
730 : \remark
731 : Prefer std::true_type.
732 :
733 :
734 : \subsection list_constructor Constructor-like functions for lists
735 :
736 : \par
737 : These functions produce \ref list "tmpl::list"s from non-list values. They are
738 : often similar to constructors in the STL.
739 :
740 :
741 : \subsubsection filled_list filled_list<Entry, n, [Head]>
742 :
743 : \par
744 : Creates a list containing `n` (passed as an `unsigned int`) of `Entry`. The
745 : head of the list defaults to \ref list "tmpl::list".
746 : \snippet Test_TMPLDocumentation.cpp tmpl::filled_list
747 :
748 :
749 : \subsubsection integral_list integral_list<T, n...>
750 :
751 : \par
752 : Shorthand for a \ref list "tmpl::list" of \ref integral_constant
753 : "tmpl::integral_constant"s of the type `T` with values `n...`.
754 : \snippet Test_TMPLDocumentation.cpp tmpl::integral_list
755 :
756 : \remark
757 : Prefer std::integer_sequence when used for pack expansion. Prefer
758 : `tmpl::integral_list` when the contents need to be manipulated for more
759 : complicated metaprogramming.
760 :
761 :
762 : \subsubsection make_sequence make_sequence<Start, n, [Next], [Head]>
763 :
764 : \par
765 : Produces a list with first element `Start` and length `n` (provided as an
766 : `unsigned int`). The remaining elements are obtained by repeated applications
767 : of the \ref metalambdas "metalambda" `Next`, defaulting to \ref next
768 : "tmpl::next". The head of the sequence can be specified, and defaults to \ref
769 : list "tmpl::list".
770 : \snippet Test_TMPLDocumentation.cpp tmpl::make_sequence
771 :
772 : \see \ref range "tmpl::range", \ref repeat "tmpl::repeat"
773 :
774 :
775 : \subsubsection range range<T, start, stop>
776 :
777 : \par
778 : Produces a \ref list "tmpl::list" of \ref integral_constant
779 : "tmpl::integral_constant"s of type `T` representing adjacent ascending integers
780 : from `start` to `stop`, including the starting value and excluding the ending
781 : value.
782 : \snippet Test_TMPLDocumentation.cpp tmpl::range
783 :
784 : \see \ref reverse_range "tmpl::reverse_range"
785 :
786 :
787 : \subsubsection reverse_range reverse_range<T, start, stop>
788 :
789 : \par
790 : Produces a \ref list "tmpl::list" of \ref integral_constant
791 : "tmpl::integral_constant"s of type `T` representing adjacent descending
792 : integers from `start` to `stop`, including the starting value and excluding the
793 : ending value.
794 : \snippet Test_TMPLDocumentation.cpp tmpl::reverse_range
795 :
796 : \see \ref range "tmpl::range"
797 :
798 :
799 : \subsection list_query Functions for querying lists
800 :
801 : \par
802 : These tend to be similar to const member functions in the STL and the
803 : non-modifying sequence operations in `<algorithm>`. They are most frequently
804 : used with \ref list "tmpl::list", but similar classes will also work.
805 :
806 :
807 : \subsubsection all all<Sequence, [Predicate]>
808 :
809 : \par
810 : Checks if `Predicate` is true for all elements of `Sequence`. The default
811 : predicate checks that the element's `value` is not equal to zero.
812 : \snippet Test_TMPLDocumentation.cpp tmpl::all
813 :
814 : \note
815 : The predicate must return the same true value for each element for `all` to
816 : return true.
817 : \snippet Test_TMPLDocumentation.cpp tmpl::all:inhomogeneous
818 :
819 : \see \ref any "tmpl::any", \ref none "tmpl::none"
820 :
821 :
822 : \subsubsection any any<Sequence, [Predicate]>
823 :
824 : \par
825 : Checks if `Predicate` is true for at least one element of `Sequence`. The
826 : default predicate checks that the element's `value` is not equal to zero.
827 : \snippet Test_TMPLDocumentation.cpp tmpl::any
828 :
829 : \remark
830 : The \ref any "tmpl::any" and \ref none "tmpl::none" metafunctions perform the
831 : same tasks as \ref found "tmpl::found" and \ref not_found "tmpl::not_found",
832 : but use different algorithms. In general, \ref any "tmpl::any" and \ref none
833 : "tmpl::none" are much faster, but \ref found "tmpl::found" and \ref not_found
834 : "tmpl::not_found" short-circuit, so they may be preferable with short lists and
835 : expensive predicates.
836 :
837 : \note
838 : The predicate must return the same false value for each element for `any` to
839 : return false.
840 : \snippet Test_TMPLDocumentation.cpp tmpl::any:inhomogeneous
841 :
842 : \see \ref all "tmpl::all", \ref found "tmpl::found", \ref none "tmpl::none"
843 :
844 :
845 : \subsubsection at at<Sequence, Index>
846 :
847 : \par
848 : Retrieves a given element of `Sequence`, similar to `operator[]` of the STL
849 : containers. The `Index` is supplied as a \ref integral_constant
850 : "tmpl::integral_constant" or similar type.
851 : \snippet Test_TMPLDocumentation.cpp tmpl::at
852 :
853 : \par
854 : This operator is \ref map_at "overloaded for maps".
855 :
856 : \see \ref at_c "tmpl::at_c"
857 :
858 :
859 : \subsubsection at_c at_c<Sequence, n>
860 :
861 : \par
862 : Retrieves a given element of `Sequence`, similar to `operator[]` of the STL
863 : containers. The index `n` is supplied as an `unsigned int`.
864 : \snippet Test_TMPLDocumentation.cpp tmpl::at_c
865 :
866 : \see \ref at "tmpl::at"
867 :
868 :
869 : \subsubsection back back<Sequence>
870 :
871 : \par
872 : Retrieves the last element of `Sequence`.
873 : \snippet Test_TMPLDocumentation.cpp tmpl::back
874 :
875 :
876 : \subsubsection count_if count_if<Sequence, Predicate>
877 :
878 : \par
879 : Returns the number of elements of `Sequence` satisfying `Predicate`.
880 : \snippet Test_TMPLDocumentation.cpp tmpl::count_if
881 :
882 :
883 : \subsubsection fold fold<Sequence, State, Functor>
884 :
885 : \par
886 : Performs a [left
887 : fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), i.e., given
888 : a list `Sequence`, initial state `State`, and \ref metalambdas "metalambda"
889 : `Functor`, updates the state by calling `Functor` on the state and the first
890 : element of `Sequence`, repeats with the second, and so on, returning the final
891 : state.
892 : \snippet Test_TMPLDocumentation.cpp tmpl::fold
893 :
894 : \par
895 : Brigand provides `tmpl::_state` and `tmpl::_element` aliases to the appropriate
896 : \ref args "arguments" for use in folds.
897 :
898 : \see \ref reverse_fold "tmpl::reverse_fold"
899 :
900 :
901 : \subsubsection found found<Sequence, [Predicate]>
902 :
903 : \par
904 : Returns, as a \ref integral_constant "tmpl::integral_constant" of `bool`,
905 : whether `Predicate` matches any element of `Sequence`. The default predicate
906 : checks that the element's `value` is not equal to zero.
907 : \snippet Test_TMPLDocumentation.cpp tmpl::found
908 :
909 : \remark
910 : This function performs the same operation as \ref any "tmpl::any". See \ref
911 : any "tmpl::any" for discussion.
912 :
913 : \see \ref any "tmpl::any", \ref find "tmpl::find", \ref not_found
914 : "tmpl::not_found"
915 :
916 :
917 : \subsubsection front front<Sequence>
918 :
919 : \par
920 : Retrieves the first element of `Sequence`.
921 : \snippet Test_TMPLDocumentation.cpp tmpl::front
922 :
923 :
924 : \subsubsection index_if<Sequence, Predicate, [NotFound]>
925 :
926 : \par
927 : Finds the index as a `size_t` \ref integral_constant "tmpl::integral_constant"
928 : of the first type in `Sequence` satisfying `Predicate`. Returns `NotFound`,
929 : defaulting to \ref no_such_type_ "tmpl::no_such_type_" if no elements match.
930 : \snippet Test_TMPLDocumentation.cpp tmpl::index_if
931 :
932 :
933 : \subsubsection index_of index_of<Sequence, T>
934 :
935 : \par
936 : Finds the index as a `size_t` \ref integral_constant "tmpl::integral_constant"
937 : of the first occurrence of `T` in `Sequence`. Returns \ref no_such_type_
938 : "tmpl::no_such_type_" if the type is not found.
939 : \snippet Test_TMPLDocumentation.cpp tmpl::index_of
940 :
941 :
942 : \subsubsection list_contains list_contains<Sequence, T>
943 :
944 : \par
945 : Checks whether `T` is contained in `Sequence`, returning a \ref
946 : integral_constant "tmpl::integral_constant" of `bool`.
947 : \snippet Test_TMPLDocumentation.cpp tmpl::list_contains
948 :
949 : \note
950 : This is not a Brigand metafunction. It is implemented in SpECTRE.
951 :
952 :
953 : \subsubsection none none<Sequence, [Predicate]>
954 :
955 : \par
956 : Checks if `Predicate` is false for all elements of `Sequence`. The default
957 : predicate checks that the element's `value` is not equal to zero.
958 : \snippet Test_TMPLDocumentation.cpp tmpl::none
959 :
960 : \remark
961 : This function performs the same operation as \ref not_found "tmpl::not_found".
962 : See \ref any "tmpl::any" for discussion.
963 :
964 : \note
965 : The predicate must return the same false value for each element for `none` to
966 : return true.
967 : \snippet Test_TMPLDocumentation.cpp tmpl::none:inhomogeneous
968 :
969 : \see \ref all "tmpl::all", \ref any "tmpl::any", \ref not_found
970 : "tmpl::not_found"
971 :
972 :
973 : \subsubsection not_found not_found<Sequence, [Predicate]>
974 :
975 : \par
976 : Returns, as a \ref integral_constant "tmpl::integral_constant" of `bool`,
977 : whether `Predicate` matches no elements of `Sequence`. The default predicate
978 : checks that the element's `value` is not equal to zero.
979 : \snippet Test_TMPLDocumentation.cpp tmpl::not_found
980 :
981 : \remark
982 : This function performs the same operation as \ref none "tmpl::none". See \ref
983 : any "tmpl::any" for discussion.
984 :
985 : \see \ref find "tmpl::find", \ref found "tmpl::found", \ref none "tmpl::none"
986 :
987 :
988 : \subsubsection size size<Sequence>
989 :
990 : \par
991 : Returns the number of elements in `Sequence` as a \ref integral_constant
992 : "tmpl::integral_constant" of type `unsigned int`.
993 : \snippet Test_TMPLDocumentation.cpp tmpl::size
994 :
995 : \see \ref count "tmpl::count"
996 :
997 :
998 : \subsection list_to_list Functions producing lists from other lists
999 :
1000 : \par
1001 : These tend to be similar to non-const member functions in the STL and the
1002 : mutating sequence operations in `<algorithm>`, but due to the nature of
1003 : metaprogramming all return a new list rather than modifying an argument. They
1004 : are most frequently used with \ref list "tmpl::list", but similar classes will
1005 : also work.
1006 :
1007 :
1008 : \subsubsection append append<Sequence...>
1009 :
1010 : \par
1011 : Concatenates all of its arguments, keeping the head of the first (or \ref list
1012 : "tmpl::list" if passed no arguments).
1013 : \snippet Test_TMPLDocumentation.cpp tmpl::append
1014 :
1015 : \see \ref join "tmpl::join"
1016 :
1017 :
1018 : \subsubsection clear clear<Sequence>
1019 :
1020 : \par
1021 : Produces a list with the same head as `Sequence` but no elements.
1022 : \snippet Test_TMPLDocumentation.cpp tmpl::clear
1023 :
1024 : \remark
1025 : If the head is known, prefer writing it explicitly. If the head is irrelevant,
1026 : write an empty \ref list "tmpl::list".
1027 :
1028 :
1029 : \subsubsection erase erase<Sequence, Index>
1030 :
1031 : \par
1032 : Produces a copy of `Sequence` with the element at index `Index` (passed as a
1033 : \ref integral_constant "tmpl::integral_constant" or similar type) removed.
1034 : \snippet Test_TMPLDocumentation.cpp tmpl::erase
1035 :
1036 : \par
1037 : This operator is overloaded \ref map_erase "for maps" and \ref set_erase
1038 : "for sets".
1039 :
1040 : \see \ref erase_c
1041 :
1042 :
1043 : \subsubsection erase_c erase_c<Sequence, n>
1044 :
1045 : \par
1046 : Produces a copy of `Sequence` with the element at index `n` (passed as an
1047 : `unsigned int`) removed.
1048 : \snippet Test_TMPLDocumentation.cpp tmpl::erase_c
1049 :
1050 :
1051 : \subsubsection filter filter<Sequence, Predicate>
1052 :
1053 : \par
1054 : Removes all types not matching `Predicate` from `Sequence`.
1055 : \snippet Test_TMPLDocumentation.cpp tmpl::filter
1056 :
1057 : \see \ref remove_if "tmpl::remove_if"
1058 :
1059 :
1060 : \subsubsection find find<Sequence, [Predicate]>
1061 :
1062 : \par
1063 : Returns a list containing the first element of `Sequence` for which `Predicate`
1064 : returns true and all subsequent elements. The default predicate checks that
1065 : the element's `value` is not equal to zero. Returns an empty list if the
1066 : predicate returns false for all elements.
1067 : \snippet Test_TMPLDocumentation.cpp tmpl::find
1068 :
1069 : \see \ref found "tmpl::found", \ref not_found "tmpl::not_found", \ref
1070 : reverse_find "tmpl::reverse_find"
1071 :
1072 :
1073 : \subsubsection flatten flatten<Sequence>
1074 :
1075 : \par
1076 : Recursively inlines the contents of elements of `Sequence` that are sequences
1077 : with the same head.
1078 : \snippet Test_TMPLDocumentation.cpp tmpl::flatten
1079 :
1080 : \see \ref join "tmpl::join"
1081 :
1082 :
1083 : \subsubsection join join<Sequence>
1084 :
1085 : \par
1086 : Combines lists in the same manner as \ref append "tmpl::append", but takes a
1087 : list of lists instead of multiple arguments.
1088 : \snippet Test_TMPLDocumentation.cpp tmpl::join
1089 :
1090 :
1091 : \subsubsection list_difference list_difference<Sequence1, Sequence2>
1092 :
1093 : \par
1094 : Remove all elements that occur in `Sequence2` from `Sequence1`.
1095 : \snippet Test_TMPLDocumentation.cpp tmpl::list_difference
1096 :
1097 : \note
1098 : This is not a Brigand metafunction. It is implemented in SpECTRE.
1099 :
1100 :
1101 : \subsubsection merge merge<Sequence1, Sequence2, [Comparator]>
1102 :
1103 : \par
1104 : Given two sorted lists, returns a sorted list containing the elements of both.
1105 : A comparator metalambda can be provided, defaulting to \ref math_comparison
1106 : "tmpl::less".
1107 : \snippet Test_TMPLDocumentation.cpp tmpl::merge
1108 :
1109 : \note
1110 : If there are equivalent elements, those from the second list are placed
1111 : earlier.
1112 : \snippet Test_TMPLDocumentation.cpp tmpl::merge:equiv
1113 :
1114 : \see std::merge
1115 :
1116 :
1117 : \subsubsection partition partition<Sequence, Predicate>
1118 :
1119 : \par
1120 : Returns a \ref pair "tmpl::pair" containing a list of the elements of
1121 : `Sequence` for which the `Predicate` returns true and a list of the elements of
1122 : `Sequence` for which the `Predicate` returns false.
1123 : \snippet Test_TMPLDocumentation.cpp tmpl::partition
1124 :
1125 : \see \ref filter "tmpl::filter", \ref remove_if "tmpl::remove_if"
1126 :
1127 :
1128 : \subsubsection pop_back pop_back<Sequence, [Count]>
1129 :
1130 : \par
1131 : Remove `Count` elements from the end of `Sequence`. The number of elements to
1132 : remove is supplied as a \ref integral_constant "tmpl::integral_constant" and
1133 : defaults to 1.
1134 : \snippet Test_TMPLDocumentation.cpp tmpl::pop_back
1135 :
1136 :
1137 : \subsubsection pop_front pop_front<Sequence, [Count]>
1138 :
1139 : \par
1140 : Remove `Count` elements from the beginning of `Sequence`. The number of
1141 : elements to remove is supplied as a \ref integral_constant
1142 : "tmpl::integral_constant" and defaults to 1.
1143 : \snippet Test_TMPLDocumentation.cpp tmpl::pop_front
1144 :
1145 :
1146 : \subsubsection push_back push_back<Sequence, T...>
1147 :
1148 : \par
1149 : Appends types `T...` to `Sequence`.
1150 : \snippet Test_TMPLDocumentation.cpp tmpl::push_back
1151 :
1152 :
1153 : \subsubsection push_front push_front<Sequence, T...>
1154 :
1155 : \par
1156 : Prepends types `T...` to `Sequence`. The order of the prepended items is
1157 : retained: they are pushed as a unit, not one-by-one.
1158 : \snippet Test_TMPLDocumentation.cpp tmpl::push_front
1159 :
1160 :
1161 : \subsubsection remove remove<Sequence, T>
1162 :
1163 : \par
1164 : Removes all occurrences of `T` from `Sequence`.
1165 : \snippet Test_TMPLDocumentation.cpp tmpl::remove
1166 :
1167 :
1168 : \subsubsection remove_duplicates remove_duplicates<Sequence>
1169 :
1170 : \par
1171 : Remove duplicates from `Sequence`. The first occurrence of each type is kept.
1172 : \snippet Test_TMPLDocumentation.cpp tmpl::remove_duplicates
1173 :
1174 : \note
1175 : This is not a Brigand metafunction. It is implemented in SpECTRE.
1176 :
1177 :
1178 : \subsubsection remove_if remove_if<Sequence, Predicate>
1179 :
1180 : \par
1181 : Removes all types matching `Predicate` from `Sequence`.
1182 : \snippet Test_TMPLDocumentation.cpp tmpl::remove_if
1183 :
1184 : \see \ref filter "tmpl::filter"
1185 :
1186 :
1187 : \subsubsection replace replace<Sequence, Old, New>
1188 :
1189 : \par
1190 : Replaces all occurrences of `Old` in `Sequence` with `New`.
1191 : \snippet Test_TMPLDocumentation.cpp tmpl::replace
1192 :
1193 :
1194 : \subsubsection replace_if replace_if<Sequence, Predicate, T>
1195 :
1196 : \par
1197 : Replaces all types in `Sequence` matching `Predicate` with `T`.
1198 : \snippet Test_TMPLDocumentation.cpp tmpl::replace_if
1199 :
1200 :
1201 : \subsubsection reverse reverse<Sequence>
1202 :
1203 : \par
1204 : Reverses the order of types in `Sequence`.
1205 : \snippet Test_TMPLDocumentation.cpp tmpl::reverse
1206 :
1207 :
1208 : \subsubsection reverse_find reverse_find<Sequence, [Predicate]>
1209 :
1210 : \par
1211 : Returns a list containing the last element of `Sequence` for which `Predicate`
1212 : returns true and all preceding elements. The default predicate checks that the
1213 : element's `value` is not equal to zero. Returns an empty list if the predicate
1214 : returns false for all elements.
1215 : \snippet Test_TMPLDocumentation.cpp tmpl::reverse_find
1216 :
1217 : \see \ref find "tmpl::find"
1218 :
1219 :
1220 : \subsubsection reverse_fold reverse_fold<Sequence, State, Functor>
1221 :
1222 : \par
1223 : Performs a [right
1224 : fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), i.e., given
1225 : a list `Sequence`, initial state `State`, and \ref metalambdas "metalambda"
1226 : `Functor`, updates the state by calling `Functor` on the state and the last
1227 : element of `Sequence`, repeats with the second to last, and so on, returning
1228 : the final state.
1229 : \snippet Test_TMPLDocumentation.cpp tmpl::reverse_fold
1230 :
1231 : \par
1232 : Brigand provides `tmpl::_state` and `tmpl::_element` aliases to the appropriate
1233 : \ref args "arguments" for use in folds.
1234 :
1235 : \see \ref fold "tmpl::fold"
1236 :
1237 :
1238 : \subsubsection sort sort<Sequence, [Comparator]>
1239 :
1240 : \par
1241 : Sorts `Sequence` according to `Comparator`, which defaults to \ref
1242 : math_comparison "tmpl::less".
1243 : \snippet Test_TMPLDocumentation.cpp tmpl::sort
1244 :
1245 : \note
1246 : The sort is not stable.
1247 : \snippet Test_TMPLDocumentation.cpp tmpl::sort:equiv
1248 :
1249 :
1250 : \subsubsection split split<Sequence, Delimiter>
1251 :
1252 : \par
1253 : Splits `Sequence` into parts separated by `Delimiter`, discarding empty parts.
1254 : \snippet Test_TMPLDocumentation.cpp tmpl::split
1255 :
1256 :
1257 : \subsubsection split_at split_at<Sequence, Index>
1258 :
1259 : \par
1260 : Returns a list of two of lists, the first containing the first `Index`
1261 : (supplied as a \ref integral_constant "tmpl::integral_constant") elements or
1262 : `Sequence`, and the second containing the remaining elements.
1263 : \snippet Test_TMPLDocumentation.cpp tmpl::split_at
1264 :
1265 :
1266 : \subsubsection transform transform<Sequence, Sequences..., Functor>
1267 :
1268 : \par
1269 : Calls a `Functor` on each element of `Sequence`, collecting the results in a
1270 : new list. If additional `Sequences...` are supplied, elements from those lists
1271 : are passed as additional arguments to `Functor`.
1272 : \snippet Test_TMPLDocumentation.cpp tmpl::transform
1273 :
1274 :
1275 : \subsection map_operations Operations on maps
1276 :
1277 : \par
1278 : Brigand's \ref map "tmpl::map" type can be manipulated by several
1279 : metafunctions.
1280 :
1281 : \par
1282 : Examples in this section use this map as an example:
1283 : \snippet Test_TMPLDocumentation.cpp example_map
1284 :
1285 :
1286 : \subsubsection map_at at<Map, Key>
1287 :
1288 : \par
1289 : Returns the value associated with `Key` in `Map`. Returns \ref
1290 : no_such_type_ "tmpl::no_such_type_" if `Key` is not in the map.
1291 : \snippet Test_TMPLDocumentation.cpp tmpl::at:map
1292 :
1293 : \par
1294 : This operator is \ref at "overloaded for lists". When called on a \ref map
1295 : "tmpl::map", this is the same as \ref lookup "tmpl::lookup".
1296 :
1297 :
1298 : \subsubsection map_erase erase<Map, Key>
1299 :
1300 : \par
1301 : Produces a copy of `Map` with the element with the key `Key` removed. If `Key`
1302 : is not in the map, returns `Map` unchanged.
1303 : \snippet Test_TMPLDocumentation.cpp tmpl::erase:map
1304 :
1305 : \par
1306 : This operator is overloaded \ref erase "for lists" and \ref set_erase
1307 : "for sets".
1308 :
1309 :
1310 : \subsubsection map_has_key has_key<Map, Key>
1311 :
1312 : \par
1313 : Returns a \ref integral_constant "tmpl::integral_constant" of `bool`
1314 : indicating whether `Map` contains the key `Key`.
1315 : \snippet Test_TMPLDocumentation.cpp tmpl::has_key:map
1316 :
1317 : \par
1318 : This operator is \ref set_has_key "overloaded for sets".
1319 :
1320 :
1321 : \subsubsection map_insert insert<Map, Pair>
1322 :
1323 : \par
1324 : Returns `Map` with `Pair` added. If the key of `Pair` is already in the map,
1325 : the map is returned unchanged.
1326 : \snippet Test_TMPLDocumentation.cpp tmpl::insert:map
1327 :
1328 : \par
1329 : This operator is \ref set_insert "overloaded for sets".
1330 :
1331 :
1332 : \subsubsection keys_as_sequence keys_as_sequence<Map, [Head]>
1333 :
1334 : \par
1335 : Returns the keys from `Map` as a sequence with head `Head`, defaulting to \ref
1336 : set "tmpl::set".
1337 : \snippet Test_TMPLDocumentation.cpp tmpl::keys_as_sequence
1338 :
1339 : \par
1340 : If the key-value pairs are required, they can be extracted directly from the
1341 : template arguments of the \ref map "tmpl::map".
1342 :
1343 : \see \ref values_as_sequence "tmpl::values_as_sequence"
1344 :
1345 :
1346 : \subsubsection lookup lookup<Map, Key>
1347 :
1348 : \par
1349 : Returns the value associated with `Key` in `Map`. Returns \ref no_such_type_
1350 : "tmpl::no_such_type_" if `Key` is not in the map.
1351 : \snippet Test_TMPLDocumentation.cpp tmpl::lookup
1352 :
1353 : \see \ref map_at "tmpl::at"
1354 :
1355 :
1356 : \subsubsection lookup_at lookup_at<Map, Key>
1357 :
1358 : \par
1359 : Returns the value associated with `Key` in `Map`, wrapped in a \ref type_
1360 : "tmpl::type_". Returns `type_<no_such_type_>` if `Key` is not in the map.
1361 : This function has no eager version, but is still in the `tmpl::lazy` namespace.
1362 : \snippet Test_TMPLDocumentation.cpp tmpl::lookup_at
1363 :
1364 : \see \ref lookup "tmpl::lookup"
1365 :
1366 :
1367 : \subsubsection values_as_sequence values_as_sequence<Map, [Head]>
1368 :
1369 : \par
1370 : Returns the values from `Map` as a sequence with head `Head`, defaulting to
1371 : \ref list "tmpl::list".
1372 : \snippet Test_TMPLDocumentation.cpp tmpl::values_as_sequence
1373 :
1374 : \par
1375 : If the key-value pairs are required, they can be extracted directly from the
1376 : template arguments of the \ref map "tmpl::map".
1377 :
1378 : \see \ref keys_as_sequence "tmpl::keys_as_sequence"
1379 :
1380 :
1381 : \subsection set_operations Operations on sets
1382 :
1383 : \par
1384 : Brigand's \ref set "tmpl::set" type can be manipulated by several
1385 : metafunctions.
1386 :
1387 :
1388 : \subsubsection contains contains<Set, T>
1389 :
1390 : \par
1391 : Returns a \ref integral_constant "tmpl::integral_constant" of `bool`
1392 : indicating whether `Set` contains `T`.
1393 : \snippet Test_TMPLDocumentation.cpp tmpl::contains
1394 :
1395 :
1396 : \subsubsection set_erase erase<Set, T>
1397 :
1398 : \par
1399 : Produces a copy of `Set` with the element `T` removed. If the element is not
1400 : in the set, returns the set unchanged.
1401 : \snippet Test_TMPLDocumentation.cpp tmpl::erase:set
1402 :
1403 : \par
1404 : This operator is overloaded \ref erase "for lists" and \ref map_erase
1405 : "for maps".
1406 :
1407 :
1408 : \subsubsection set_has_key has_key<Set, T>
1409 :
1410 : \par
1411 : Returns a \ref integral_constant "tmpl::integral_constant" of `bool`
1412 : indicating whether `Set` contains `T`.
1413 : \snippet Test_TMPLDocumentation.cpp tmpl::has_key:set
1414 :
1415 : \par
1416 : This operator is \ref map_has_key "overloaded for maps".
1417 :
1418 :
1419 : \subsubsection set_insert insert<Set, T>
1420 :
1421 : \par
1422 : Returns a copy of `Set` containing an additional element `T`. If `T` is
1423 : already in the set, the set is returned unchanged.
1424 : \snippet Test_TMPLDocumentation.cpp tmpl::insert:set
1425 :
1426 : \par
1427 : This operator is \ref map_insert "overloaded for maps".
1428 :
1429 :
1430 : \subsection math Mathematical functions
1431 :
1432 : \par
1433 : These perform the same operations at their language counterparts, but on \ref
1434 : integral_constant "tmpl::integral_constant"s (or anything else with a `value`
1435 : static member type of type `value_type`). The results inherit from \ref
1436 : integral_constant "tmpl::integral_constant"s of types noted below.
1437 :
1438 : \par
1439 : These are all lazy metafunctions.
1440 :
1441 :
1442 : \subsubsection math_arithmetic Arithmetic operators
1443 :
1444 : \par
1445 : These operations return classes inheriting from \ref integral_constant
1446 : "tmpl::integral_constant"s of the same type as the result of the language
1447 : operator on their arguments. The integral promotion and conversion rules are
1448 : applied. (Contrast the \ref math_bitwise "bitwise operators".)
1449 : \snippet Test_TMPLDocumentation.cpp math_arithmetic
1450 :
1451 : \par
1452 : The standard library runtime functors have the same names for std::plus,
1453 : std::minus, std::divides, and std::negate, but the other two are
1454 : std::multiplies and std::modulus.
1455 :
1456 :
1457 : \subsubsection math_bitwise Bitwise operators
1458 :
1459 : \par
1460 : These operations return classes inheriting from \ref integral_constant
1461 : "tmpl::integral_constant"s of the same type as their first argument's `value`.
1462 : This is *not* generally the same type as the language operator, even when the
1463 : types of the values of both arguments are the same. (The integer promotion and
1464 : conversion rules are not applied.)
1465 : \snippet Test_TMPLDocumentation.cpp math_bitwise
1466 :
1467 : \par
1468 : The standard library runtime functors are called std::bit_not, std::bit_and,
1469 : std::bit_or, and std::bit_xor.
1470 :
1471 :
1472 : \subsubsection math_comparison Comparison operators
1473 :
1474 : \par
1475 : These operations return classes inheriting from \ref integral_constant
1476 : "tmpl::integral_constant"s of `bool`.
1477 : \snippet Test_TMPLDocumentation.cpp math_comparison
1478 :
1479 : \par
1480 : The standard library runtime functors have the same names, such as
1481 : std::equal_to.
1482 :
1483 :
1484 : \subsubsection math_logical Logical operators
1485 :
1486 : \par
1487 : These operations return classes inheriting from \ref integral_constant
1488 : "tmpl::integral_constant"s of `bool`. They should only be used on types
1489 : wrapping `bool`s. The `and_` and `or_` structs can take any number of
1490 : arguments.
1491 : \snippet Test_TMPLDocumentation.cpp math_logical
1492 :
1493 : \par
1494 : The standard library runtime functors are called std::logical_and,
1495 : std::logical_or, and std::logical_not. The xor operation is equivalent to \ref
1496 : math_comparison "tmpl::not_equal_to".
1497 :
1498 :
1499 : \subsubsection identity identity<T>
1500 :
1501 : \par
1502 : The identity function. Unlike most math functions, this returns the same type
1503 : as its argument, even if that is not a \ref integral_constant
1504 : "tmpl::integral_constant".
1505 : \snippet Test_TMPLDocumentation.cpp tmpl::identity
1506 :
1507 : \see \ref always "tmpl::always"
1508 :
1509 :
1510 : \subsubsection max max<T1, T2>
1511 :
1512 : \par
1513 : Computes the larger of `T1` and `T2`, returning a \ref integral_constant
1514 : "tmpl::integral_constant" of the common type of its arguments.
1515 : \snippet Test_TMPLDocumentation.cpp tmpl::max
1516 :
1517 :
1518 : \subsubsection min min<T1, T2>
1519 :
1520 : \par
1521 : Computes the smaller of `T1` and `T2`, returning a \ref integral_constant
1522 : "tmpl::integral_constant" of the common type of its arguments.
1523 : \snippet Test_TMPLDocumentation.cpp tmpl::min
1524 :
1525 :
1526 : \subsubsection next next<T>
1527 :
1528 : \par
1529 : Computes `T` plus one, returning a \ref integral_constant
1530 : "tmpl::integral_constant" of the same type as its argument.
1531 : \snippet Test_TMPLDocumentation.cpp tmpl::next
1532 :
1533 :
1534 : \subsubsection prev prev<T>
1535 :
1536 : \par
1537 : Computes `T` minus one, returning a \ref integral_constant
1538 : "tmpl::integral_constant" of the same type as its argument.
1539 : \snippet Test_TMPLDocumentation.cpp tmpl::prev
1540 :
1541 :
1542 : \subsection misc Miscellaneous functions
1543 :
1544 : \par
1545 : Functions that don't fit into any of the other sections.
1546 :
1547 :
1548 : \subsubsection always always<T>
1549 :
1550 : \par
1551 : A lazy identity function.
1552 : \snippet Test_TMPLDocumentation.cpp tmpl::always
1553 :
1554 : \see \ref identity "tmpl::identity"
1555 :
1556 :
1557 : \subsubsection apply apply<Lambda, [Arguments...]>
1558 :
1559 : \par
1560 : Calls a \ref metalambdas "metalambda" `Lambda` with arguments `Arguments...`.
1561 : \snippet Test_TMPLDocumentation.cpp tmpl::apply
1562 :
1563 :
1564 : \subsubsection count count<T...>
1565 :
1566 : \par
1567 : Returns the number of template parameters provided as a \ref integral_constant
1568 : "tmpl::integral_constant" of `unsigned int`.
1569 : \snippet Test_TMPLDocumentation.cpp tmpl::count
1570 :
1571 :
1572 : \subsubsection conditional_t conditional_t<b, TrueResult, FalseResult>
1573 :
1574 : \par
1575 : Returns `TrueResult` if the `bool` `b` is true, otherwise `FalseResult`. An
1576 : optimized version of std::conditional_t.
1577 : \snippet Test_TMPLDocumentation.cpp tmpl::conditional_t
1578 :
1579 : \note
1580 : This is not a Brigand metafunction. It is implemented in SpECTRE.
1581 :
1582 :
1583 : \subsubsection eval_if eval_if<Condition, TrueFunction, FalseFunction>
1584 :
1585 : \par
1586 : A lazy metafunction that, if `Condition` has a true `value`, evaluates and
1587 : returns the result of the lazy metafunction (*not* metalambda) `TrueFunction`,
1588 : otherwise, evaluates and returns the result of the lazy metafunction
1589 : `FalseFunction`.
1590 : \snippet Test_TMPLDocumentation.cpp tmpl::eval_if
1591 :
1592 : \par
1593 : This performs lazy evaluation of conditional branches outside of a metalambda.
1594 :
1595 :
1596 : \subsubsection eval_if_c eval_if_c<b, TrueFunction, FalseFunction>
1597 :
1598 : \par
1599 : The same as \ref eval_if "tmpl::eval_if", but takes its first argument as a
1600 : `bool` instead of a type.
1601 : \snippet Test_TMPLDocumentation.cpp tmpl::eval_if_c
1602 :
1603 :
1604 : \subsubsection has_type has_type<Ignored, [T]>
1605 :
1606 : \par
1607 : A lazy metafunction that returns `T` (defaulting to `void`), ignoring its first
1608 : argument.
1609 : \snippet Test_TMPLDocumentation.cpp tmpl::has_type
1610 :
1611 : \par
1612 : This can be used to expand a parameter pack to repetitions of the same type.
1613 : \snippet Test_TMPLDocumentation.cpp tmpl::has_type:pack_expansion
1614 : \snippet Test_TMPLDocumentation.cpp tmpl::has_type:pack_expansion:asserts
1615 :
1616 :
1617 : \subsubsection if_ if_<Condition, TrueResult, FalseResult>
1618 :
1619 : \par
1620 : A lazy metafunction that returns `TrueResult` if the `value` static member
1621 : value of `Condition` is true, and otherwise `FalseResult`.
1622 : \snippet Test_TMPLDocumentation.cpp tmpl::if_
1623 :
1624 : \warning
1625 : The second and third arguments are both evaluated, independent of which is
1626 : returned. Use \ref defer "tmpl::defer" or \ref eval_if "tmpl::eval_if" if this
1627 : is undesirable.
1628 :
1629 :
1630 : \subsubsection if_c if_c<Condition, TrueResult, FalseResult>
1631 :
1632 : \par
1633 : The same as std::conditional.
1634 : \snippet Test_TMPLDocumentation.cpp tmpl::if_c
1635 :
1636 :
1637 : \subsubsection inherit inherit<T...>
1638 :
1639 : \par
1640 : A lazy metafunction that produces a type with all of its template arguments as
1641 : base classes. All the arguments must be unique.
1642 : \snippet Test_TMPLDocumentation.cpp tmpl::inherit
1643 :
1644 : \remark
1645 : This task can be performed more simply than the algorithm used by Brigand by
1646 : directly using pack expansions:
1647 : \snippet Test_TMPLDocumentation.cpp tmpl::inherit:pack:definitions
1648 : \snippet Test_TMPLDocumentation.cpp tmpl::inherit:pack:asserts
1649 :
1650 : \note
1651 : The \ref empty_base "tmpl::empty_base" type is used internally as a sentinel.
1652 : The result may or may not inherit from \ref empty_base "tmpl::empty_base",
1653 : independently of whether it is supplied as an argument.
1654 :
1655 :
1656 : \subsubsection inherit_linearly inherit_linearly<Sequence, NodePattern, [Root]>
1657 :
1658 : \par
1659 : Transforms `Sequence` into a linked list. The `NodePattern` must be a class
1660 : template (*not* a lazy metafunction) instantiated with metalambdas. The
1661 : function performs a [left
1662 : fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), with the
1663 : `Root` (defaulting to \ref empty_base "tmpl::empty_base") as the initial state
1664 : and the transform function evaluating the arguments to the node pattern.
1665 : \snippet Test_TMPLDocumentation.cpp tmpl::inherit_linearly
1666 :
1667 : \remark
1668 : This function handles its function-like argument differently from any other
1669 : function in Brigand. Prefer \ref fold "tmpl::fold", which can perform the same
1670 : task and has a more standard interface.
1671 :
1672 :
1673 : \subsubsection is_set is_set<T...>
1674 :
1675 : \par
1676 : Tests if all of its arguments are distinct, producing a \ref integral_constant
1677 : "tmpl::integral_constant" of `bool`.
1678 : \snippet Test_TMPLDocumentation.cpp tmpl::is_set
1679 :
1680 : \note
1681 : This is unrelated to the Brigand \ref set "tmpl::set" type.
1682 :
1683 :
1684 : \subsubsection real_ real_<RealType, IntType, value>
1685 :
1686 : \par
1687 : Represents a floating point number of type `RealType` at compile time via its
1688 : internal memory representation. The value is stored as a \ref
1689 : integral_constant "tmpl::integral_constant" of type `IntType` with value
1690 : `value` (which must be the same size as `RealType`) and can be extracted at
1691 : runtime using the conversion operator. Brigand provides the aliases
1692 : `single_<value>` and `double_<value>` with `RealType` and `IntType` set to
1693 : appropriate values.
1694 : \snippet Test_TMPLDocumentation.cpp tmpl::real_
1695 :
1696 : \par
1697 : There are no compile-time mathematical functions provided for floating point
1698 : types. They are opaque (or sometimes treated as integers) until runtime.
1699 :
1700 : \remark
1701 : Consider whether you really need to represent floating point values at compile
1702 : time.
1703 :
1704 : \see std::ratio
1705 :
1706 :
1707 : \subsubsection repeat repeat<Function, Count, Initial>
1708 :
1709 : \par
1710 : Calls a unary eager metafunction `Function` on `Initial`, then on the result of
1711 : that, then on the result of that, and so on, up to `Count` calls.
1712 : \snippet Test_TMPLDocumentation.cpp tmpl::repeat
1713 :
1714 : \note
1715 : This function has a lazy version, but it cannot be used in a metalambda because
1716 : the template template parameter prevents manipulation of the parameter list.
1717 : \snippet Test_TMPLDocumentation.cpp tmpl::repeat:lazy
1718 :
1719 : \see \ref make_sequence "tmpl::make_sequence"
1720 :
1721 :
1722 : \subsubsection sizeof_ sizeof_<T>
1723 :
1724 : \par
1725 : A lazy metafunction that computes `sizeof` its argument as an `unsigned int`
1726 : \ref integral_constant "tmpl::integral_constant".
1727 : \snippet Test_TMPLDocumentation.cpp tmpl::sizeof_
1728 :
1729 :
1730 : \subsubsection substitute substitute<Pattern, ArgumentList>
1731 :
1732 : \par
1733 : Substitutes values from `ArgumentList` for appearances of \ref args
1734 : "tmpl::args" (but *not* `tmpl::_1` or `tmpl::_2`) appearing in `Pattern`.
1735 : \snippet Test_TMPLDocumentation.cpp tmpl::substitute
1736 :
1737 :
1738 : \subsubsection type_from type_from<T>
1739 :
1740 : \par
1741 : Extracts the `type` from `T`.
1742 : \snippet Test_TMPLDocumentation.cpp tmpl::type_from
1743 :
1744 : \remark
1745 : This function will work on any class with a `type` type alias, but, when used
1746 : outside of a metafunction, it should only be used with \ref type_ "tmpl::type_"
1747 : for clarity.
1748 :
1749 :
1750 : \subsubsection wrap wrap<Sequence, Head>
1751 :
1752 : \par
1753 : Replaces the head of `Sequence` with `Head`.
1754 : \snippet Test_TMPLDocumentation.cpp tmpl::wrap
1755 :
1756 : \note
1757 : This function has a lazy version, but it cannot be used in a metalambda because
1758 : the template template parameter prevents manipulation of the parameter list.
1759 : \snippet Test_TMPLDocumentation.cpp tmpl::wrap:lazy
1760 :
1761 :
1762 : \subsection runtime Runtime functionality
1763 :
1764 : \par
1765 : Brigand provides a few C++ functions that execute at runtime.
1766 :
1767 : \par
1768 : The examples in this section use the following definition:
1769 : \snippet Test_TMPLDocumentation.cpp runtime_declarations
1770 :
1771 :
1772 : \subsubsection for_each_args for_each_args(functor, arguments...)
1773 :
1774 : \par
1775 : Calls `functor` on each of `arguments...`, in order. Returns `functor`.
1776 : \snippet Test_TMPLDocumentation.cpp tmpl::for_each_args:defs
1777 : \snippet Test_TMPLDocumentation.cpp tmpl::for_each_args
1778 :
1779 : \par
1780 :
1781 : \note
1782 : This uses a std::reference_wrapper internally, but I don't see a reason for
1783 : that. If it were removed then this function could be constexpr starting in
1784 : C++14.
1785 :
1786 :
1787 : \subsubsection for_each for_each<Sequence>(functor)
1788 :
1789 : \par
1790 : Calls `functor` on \ref type_ "tmpl::type_" objects wrapping each type in
1791 : `Sequence`, in order. Returns `functor`.
1792 : \snippet Test_TMPLDocumentation.cpp tmpl::for_each:defs
1793 : \snippet Test_TMPLDocumentation.cpp tmpl::for_each
1794 :
1795 : \see \ref type_from "tmpl::type_from"
1796 :
1797 :
1798 : \subsubsection select select<Condition>(true_result, false_result)
1799 :
1800 : \par
1801 : Returns `true_result` if `Condition`'s `value` member is true,
1802 : and `false_result` if it is false.
1803 : \snippet Test_TMPLDocumentation.cpp tmpl::select
1804 :
1805 :
1806 : \subsection external External integration
1807 :
1808 : \par
1809 : Brigand provides metafunctions for interfacing with some types from the
1810 : standard library and Boost. They usually come in pairs, with `as_X` taking a
1811 : list and `X_wrapper` taking a parameter pack. This makes `X_wrapper`
1812 : equivalent to the wrapped class.
1813 :
1814 : \remark
1815 : Avoid the `*_wrapper` functions in favor of using the class directly.
1816 :
1817 :
1818 : \subsubsection boost_integration Boost
1819 :
1820 : \par
1821 : Brigand provides functions to produce the `boost::fusion` types `deque`,
1822 : `list`, `set`, and `vector`, as well as `boost::variant`.
1823 : \snippet Test_TMPLDocumentation.cpp boost_integration
1824 :
1825 : \note
1826 : These functions are unavailable if `BRIGAND_NO_BOOST_SUPPORT` is defined, as is
1827 : the case in SpECTRE.
1828 :
1829 :
1830 : \subsubsection stl_integration STL
1831 :
1832 : \par
1833 : Brigand provides functions to produce the STL types std::pair and std::tuple.
1834 : In addition to the usual functions, Brigand provides `pair_wrapper_`, which is
1835 : a lazy form of `pair_wrapper`. The pair functions all assert that they have
1836 : received two types.
1837 : \snippet Test_TMPLDocumentation.cpp stl_integration
1838 :
1839 :
1840 : \subsubsection make_integral integral_constant
1841 :
1842 : \par
1843 : Brigand provides two functions for converting from std::integral_constant (or a
1844 : similar class with a `value_type` and a `value`) to \ref integral_constant
1845 : "tmpl::integral_constant". The lazy metafunction `make_integral` performs this
1846 : conversion. The `as_integral_list` eager metafunction performs this operation
1847 : on all elements of a list.
1848 : \snippet Test_TMPLDocumentation.cpp tmpl::make_integral
1849 :
1850 : \warning
1851 : The standard library std::integer_sequence is not a list of types, and so
1852 : cannot be used as input to `as_integral_list`.
1853 :
1854 :
1855 : \subsubsection as_list list
1856 :
1857 : \par
1858 : Brigand provides two metafunctions for converting types to Brigand sequences.
1859 : The more general function, `as_sequence`, is equivalent to \ref wrap
1860 : "tmpl::wrap". The specialized version, `tmpl::as_list`, produces a \ref list
1861 : "tmpl::list".
1862 : \snippet Test_TMPLDocumentation.cpp tmpl::as_list
1863 :
1864 : \remark
1865 : Using `as_list` is often not necessary because most metafunctions operate on
1866 : arbitrary template classes.
1867 :
1868 :
1869 : \subsubsection as_set set
1870 :
1871 : \par
1872 : Brigand provides the standard two metafunctions for converting types to Brigand
1873 : \ref set "tmpl::set"s.
1874 : \snippet Test_TMPLDocumentation.cpp tmpl::as_set
1875 :
1876 :
1877 : \section oddities Bugs/Oddities
1878 :
1879 : * \ref push_front and \ref pop_front have lazy versions, but \ref push_back,
1880 : and \ref pop_back do not.
1881 :
1882 : * \ref reverse_range validates its arguments, but \ref range does not.
1883 : (Probably because the former is called incorrectly more often.)
1884 :
1885 : * Brigand inconsistently uses `unsigned int` and `size_t` for size-related
1886 : things. (Most blatantly, the result of \ref sizeof_ is represented as an
1887 : `unsigned int`.)
1888 :
1889 : * Brigand has a file containing operator overloads for \ref integral_constant
1890 : ""s, but it is not included by the main brigand header. They work poorly,
1891 : mostly because it inexplicably puts them all in namespace std where the
1892 : compiler can't find them.
|