]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/doc/karma/operator.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / doc / karma / operator.qbk
1 [/==============================================================================
2 Copyright (C) 2001-2011 Hartmut Kaiser
3 Copyright (C) 2001-2011 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ===============================================================================/]
8
9 [section:operator Generator Operators]
10
11 Operators are used as a means for object composition and embedding.
12 Simple generators may be composed to form composites through operator
13 overloading, crafted to approximate the syntax of __peg__ (PEG). An
14 expression such as:
15
16 a | b
17
18 yields a new generator type which is a composite of its operands, `a` and
19 `b`.
20
21 This module includes different generators which get instantiated if one of the
22 overloaded operators is used with more primitive generator constructs. It
23 includes sequences (`a << b`), alternatives (`a | b`), Kleene star (unary `*`),
24 plus (unary `+`), optional (unary `-`), lists (`a % b`), and the two predicates, the
25 /and/ predicate (unary `&`) and the /not/ predicate (unary `!`).
26
27 [heading Module Header]
28
29 // forwards to <boost/spirit/home/karma/operator.hpp>
30 #include <boost/spirit/include/karma_operator.hpp>
31
32 Also, see __include_structure__.
33
34 [/////////////////////////////////////////////////////////////////////////////]
35 [section:sequence Sequence Generator (`a << b`)]
36
37 [heading Description]
38
39 Generator sequences are used to consecutively combine different, more primitive
40 generators. All generators in a sequence are invoked from left to right as long
41 as they succeed.
42
43 [heading Header]
44
45 // forwards to <boost/spirit/home/karma/operator/sequence.hpp>
46 #include <boost/spirit/include/karma_sequence.hpp>
47
48 Also, see __include_structure__.
49
50 [heading Model of]
51
52 [:__nary_generator_concept__]
53
54 [heading Expression Semantics]
55
56 Semantics of an expression is defined only where it differs from, or is not
57 defined in __nary_generator_concept__.
58
59 [table
60 [[Expression] [Semantics]]
61 [[`a << b`] [The generators `a` and `b` are executed sequentially
62 from left to right and as long as they succeed. A
63 failed generator stops the execution of the entire
64 sequence and makes the sequence fail as well.]]
65 ]
66
67 It is important to note, that sequences don't perform any buffering of the
68 output generated by its elements. That means that any failing sequence might
69 have already generated some output, which is /not/ rolled back.
70
71 [tip The simplest way to force a sequence to behave as if it did buffering
72 is to wrap it into a buffering directive (see __karma_buffer__):
73
74 ``buffer[a << b << c]``
75
76 which will /not/ generate any output in case of a failing sequence.]
77
78 [heading Attributes]
79
80 See __karma_comp_attr_notation__.
81
82 [table
83 [[Expression] [Attribute]]
84 [[`a << b` (sequence)]
85 [``a: A, b: B --> (a << b): tuple<A, B>
86 a: A, b: Unused --> (a << b): A
87 a: Unused, b: B --> (a << b): B
88 a: Unused, b: Unused --> (a << b): Unused
89
90 a: A, b: A --> (a << b): vector<A>
91 a: vector<A>, b: A --> (a << b): vector<A>
92 a: A, b: vector<A> --> (a << b): vector<A>
93 a: vector<A>, b: vector<A> --> (a << b): vector<A>``]]
94 ]
95
96 [important The table above uses `tuple<A, B>` and `vector<A>` as placeholders
97 only.
98
99 The notation `tuple<A, B>` stands for /any fusion sequence of two
100 elements/, where `A` is the type of its first element and `B` is the
101 type of its second element.
102
103 The notation of `vector<A>` stands for /any STL container/ holding
104 elements of type `A`.]
105
106 The attribute composition and propagation rules as shown in the table above make
107 sequences somewhat special as they can operate in two modes if all elements have
108 the same attribute type: consuming fusion sequences and consuming STL
109 containers. The selected mode depends on the type of the attribute supplied.
110
111 [heading Complexity]
112
113 [:The overall complexity of the sequence generator is defined by the sum of the
114 complexities of its elements. The complexity of the sequence itself is O(N),
115 where N is the number of elements in the sequence.]
116
117 [heading Example]
118
119 [note The test harness for the example(s) below is presented in the
120 __karma_basics_examples__ section.]
121
122 Some includes:
123
124 [reference_karma_includes]
125
126 Some using declarations:
127
128 [reference_karma_using_declarations_sequence]
129
130 Basic usage of a sequence:
131
132 [reference_karma_sequence]
133
134 [endsect]
135
136 [/////////////////////////////////////////////////////////////////////////////]
137 [section:alternative Alternative Generator (`a | b`)]
138
139 [heading Description]
140
141 Generator alternatives are used to combine different, more primitive generators
142 into alternatives. All generators in an alternative are invoked from left to
143 right until one of them succeeds.
144
145 [heading Header]
146
147 // forwards to <boost/spirit/home/karma/operator/alternative.hpp>
148 #include <boost/spirit/include/karma_alternative.hpp>
149
150 Also, see __include_structure__.
151
152 [heading Model of]
153
154 [:__nary_generator_concept__]
155
156 [heading Expression Semantics]
157
158 Semantics of an expression is defined only where it differs from, or is not
159 defined in __nary_generator_concept__.
160
161 [table
162 [[Expression] [Semantics]]
163 [[`a | b`] [The generators `a` and `b` are executed sequentially
164 from left to right until one of them succeeds. A
165 failed generator forces the alternative generator to
166 try the next one. The alternative fails as a whole
167 only if all elements of the alternative fail. Each
168 element of the alternative gets passed the whole
169 attribute of the alternative.]]
170 ]
171
172 Alternatives intercept and buffer the output of the currently executed element.
173 This allows to avoid partial outputs from failing elements as the buffered
174 content will be forwarded to the actual output only after an element succeeded.
175
176 [heading Attributes]
177
178 See __karma_comp_attr_notation__.
179
180 [table
181 [[Expression] [Attribute]]
182 [[`a | b` (alternative)]
183 [``a: A, b: B --> (a | b): variant<A, B>
184 a: A, b: Unused --> (a | b): A
185 a: Unused, b: B --> (a | b): B
186 a: Unused, b: Unused --> (a | b): Unused
187 a: A, b: A --> (a | b): A``]]
188 ]
189
190 [important The table above uses `variant<A, B>` as a placeholder only. The
191 notation `variant<A, B>` stands for the type `boost::variant<A, B>`.
192 ]
193
194 The attribute handling of Alternatives is special as their behavior is
195 not completely defined at compile time. First of all the selected alternative
196 element depends on the actual type of the attribute supplied to the alternative
197 generator (i.e. what is stored in the variant). The attribute type supplied at
198 /runtime/ narrows the set of considered alternatives to those being compatible
199 attribute wise. The remaining alternatives are tried sequentially until the
200 first of them succeeds. See below for an example of this behavior.
201
202 [heading Complexity]
203
204 [:The overall complexity of the alternative generator is defined by the sum of
205 the complexities of its elements. The complexity of the alternative itself is
206 O(N), where N is the number of elements in the alternative.]
207
208 [heading Example]
209
210 [note The test harness for the example(s) below is presented in the
211 __karma_basics_examples__ section.]
212
213 Some includes:
214
215 [reference_karma_includes]
216
217 Some using declarations:
218
219 [reference_karma_using_declarations_alternative]
220
221 Basic usage of an alternative. While being only the second alternative, the
222 `double_` generator is chosen for output formatting because the supplied
223 attribute type is not compatible (i.e. not convertible) to the attribute type
224 of the `string` alternative.
225
226 [reference_karma_alternative1]
227
228 The same formatting rules may be used to output a string. This time we supply
229 the string `"example"`, resulting in the first alternative to be chosen for the
230 generated output.
231
232 [reference_karma_alternative2]
233
234 [endsect]
235
236 [/////////////////////////////////////////////////////////////////////////////]
237 [section:kleene Kleene Star Generator (`*a`)]
238
239 [heading Description]
240
241 Kleene star generators are used to repeat the execution of an embedded generator
242 zero or more times. Regardless of the success of the embedded generator, the
243 Kleene star generator always succeeds.
244
245 [heading Header]
246
247 // forwards to <boost/spirit/home/karma/operator/kleene.hpp>
248 #include <boost/spirit/include/karma_kleene.hpp>
249
250 Also, see __include_structure__.
251
252 [heading Model of]
253
254 [:__unary_generator_concept__]
255
256 [heading Expression Semantics]
257
258 Semantics of an expression is defined only where it differs from, or is not
259 defined in __unary_generator_concept__.
260
261 [table
262 [[Expression] [Semantics]]
263 [[`*a`] [The generator `a` is executed zero or more times
264 depending on the availability of an attribute. The
265 execution of `a` stops after the attribute values
266 passed to the Kleene star generator are exhausted.
267 The Kleene star always succeeds (unless the
268 underlying output stream reports an error).]]
269 ]
270
271 [note All failing iterations of the embedded generator will consume one element
272 from the supplied attribute.]
273
274 [heading Attributes]
275
276 See __karma_comp_attr_notation__.
277
278 [table
279 [[Expression] [Attribute]]
280 [[`*a` (Kleene star, unary `*`)]
281 [``a: A --> *a: vector<A>
282 a: Unused --> *a: Unused``]]
283 ]
284
285 [important The table above uses `vector<A>` as a placeholder only. The notation
286 of `vector<A>` stands for /any STL container/ holding elements of
287 type `A`.]
288
289 The Kleene star generator will execute its embedded generator once for each
290 element in the provided container attribute as long as the embedded
291 generator succeeds. On each iteration it will pass the next consecutive element
292 from the container attribute to the embedded generator. Therefore the number of
293 iterations will not be larger than the number of elements in the container
294 passed as its attribute. An empty container will make the Kleene star
295 generate no output at all.
296
297 It is important to note, that the Kleene star does not perform any buffering
298 of the output generated by its embedded elements. That means that any failing
299 element generator might have already generated some output, which is /not/
300 rolled back.
301
302 [tip The simplest way to force a Kleene star to behave as if it did
303 buffering is to wrap it into a buffering directive (see
304 __karma_buffer__):
305
306 ``buffer[*a]``
307
308 which will /not/ generate any output in case of a failing generator `*a`.
309 The expression:
310
311 ``*(buffer[a])``
312
313 will not generate any partial output from a generator `a` if it fails
314 generating in the middle of its output. The overall expression will
315 still generate the output as produced by all successful invocations of
316 the generator `a`.]
317
318 [heading Complexity]
319
320 [:The overall complexity of the Kleene star generator is defined by the
321 complexity of its embedded generator multiplied by the number of executed
322 iterations. The complexity of the Kleene star itself is O(N), where N is the
323 number of elements in the container passed as its attribute.]
324
325 [heading Example]
326
327 [note The test harness for the example(s) below is presented in the
328 __karma_basics_examples__ section.]
329
330 Some includes:
331
332 [reference_karma_includes]
333
334 Some using declarations:
335
336 [reference_karma_using_declarations_kleene]
337
338 Basic usage of a Kleene star generator:
339
340 [reference_karma_kleene]
341
342 [endsect]
343
344 [/////////////////////////////////////////////////////////////////////////////]
345 [section:plus Plus Generator (`+a`)]
346
347 [heading Description]
348
349 The Plus generator is used to repeat the execution of an embedded generator
350 one or more times. It succeeds if the embedded generator has been successfully
351 executed at least once.
352
353 [heading Header]
354
355 // forwards to <boost/spirit/home/karma/operator/plus.hpp>
356 #include <boost/spirit/include/karma_plus.hpp>
357
358 Also, see __include_structure__.
359
360 [heading Model of]
361
362 [:__unary_generator_concept__]
363
364 [heading Expression Semantics]
365
366 Semantics of an expression is defined only where it differs from, or is not
367 defined in __unary_generator_concept__.
368
369 [table
370 [[Expression] [Semantics]]
371 [[`+a`] [The generator `a` is executed one or more times
372 depending on the availability of an attribute. The
373 execution of `a` stops after the attribute values
374 passed to the plus generator are exhausted.
375 The plus generator succeeds as long as its embedded
376 generator has been successfully executed at least once
377 (unless the underlying output stream reports an
378 error).]]
379 ]
380
381 [note All failing iterations of the embedded generator will consume one element
382 from the supplied attribute. The overall `+a` will succeed as long as at
383 least one invocation of the embedded generator will succeed (unless the
384 underlying output stream reports an error).]
385
386 [heading Attributes]
387
388 See __karma_comp_attr_notation__.
389
390 [table
391 [[Expression] [Attribute]]
392 [[`+a` (unary `+`)]
393 [``a: A --> +a: vector<A>
394 a: Unused --> +a: Unused``]]
395 ]
396
397 [important The table above uses `vector<A>` as a placeholder only. The notation
398 of `vector<A>` stands for /any STL container/ holding elements of
399 type `A`.]
400
401 The Plus generator will execute its embedded generator once for each
402 element in the provided container attribute as long as the embedded
403 generator succeeds. On each iteration it will pass the next consecutive element
404 from the container attribute to the embedded generator. Therefore the number of
405 iterations will not be larger than the number of elements in the container
406 passed as its attribute. An empty container will make the plus generator fail.
407
408 It is important to note, that the plus generator does not perform any buffering
409 of the output generated by its embedded elements. That means that any failing
410 element generator might have already generated some output, which is /not/
411 rolled back.
412
413 [tip The simplest way to force a plus generator to behave as if it did
414 buffering is to wrap it into a buffering directive (see
415 __karma_buffer__):
416
417 ``buffer[+a]``
418
419 which will /not/ generate any output in case of a failing generator `+a`.
420 The expression:
421
422 ``+(buffer[a])``
423
424 will not generate any partial output from a generator `a` if it fails
425 generating in the middle of its output. The overall expression will
426 still generate the output as produced by all successful invocations of
427 the generator `a`.]
428
429 [heading Complexity]
430
431 [:The overall complexity of the plus generator is defined by the
432 complexity of its embedded generator multiplied by the number of executed
433 iterations. The complexity of the plus generator itself is O(N), where N is
434 the number of elements in the container passed as its attribute.]
435
436 [heading Example]
437
438 [note The test harness for the example(s) below is presented in the
439 __karma_basics_examples__ section.]
440
441 Some includes:
442
443 [reference_karma_includes]
444
445 Some using declarations:
446
447 [reference_karma_using_declarations_plus]
448
449 Basic usage of a plus generator:
450
451 [reference_karma_plus1]
452
453 A more sophisticated use case showing how to leverage the fact that plus is
454 failing for empty containers passed as its attribute:
455
456 [reference_karma_plus2]
457
458 [endsect]
459
460 [/////////////////////////////////////////////////////////////////////////////]
461 [section:list List Generator (`a % b`)]
462
463 [heading Description]
464
465 The list generator is used to repeat the execution of an embedded generator
466 and intersperse it with the output of another generator one or more times.
467 It succeeds if the embedded generator has been successfully executed at least
468 once.
469
470 [heading Header]
471
472 // forwards to <boost/spirit/home/karma/operator/list.hpp>
473 #include <boost/spirit/include/karma_list.hpp>
474
475 Also, see __include_structure__.
476
477 [heading Model of]
478
479 [:__binary_generator_concept__]
480
481 [heading Expression Semantics]
482
483 Semantics of an expression is defined only where it differs from, or is not
484 defined in __binary_generator_concept__.
485
486 [table
487 [[Expression] [Semantics]]
488 [[`a % b`] [The generator `a` is executed one or more times
489 depending on the availability of an attribute. The
490 output generated by `a` is interspersed with the output
491 generated by `b`. The list generator succeeds if
492 its first embedded generator has been
493 successfully executed at least once (unless the
494 underlying output stream reports an error).]]
495 ]
496
497 The list expression `a % b` is a shortcut for `a << *(b << a)`. It is almost
498 semantically equivalent, except for the attribute of `b`, which gets ignored
499 in the case of the list generator.
500
501 [note All failing iterations of the embedded generator will consume one element
502 from the supplied attribute. The overall `a % b` will succeed as long as at
503 least one invocation of the embedded generator, `a`, will succeed (unless
504 the underlying output stream reports an error).]
505
506 [heading Attributes]
507
508 See __karma_comp_attr_notation__.
509
510 [table
511 [[Expression] [Attribute]]
512 [[`a % b` (list)]
513 [``a: A, b: B --> (a % b): vector<A>
514 a: Unused, b: B --> (a % b): Unused``]]
515 ]
516
517 [important The table above uses `vector<A>` as a placeholder only. The notation
518 of `vector<A>` stands for /any STL container/ holding elements of
519 type `A`.]
520
521 The list generator will execute its embedded generator once for each
522 element in the provided container attribute and as long as the embedded
523 generator succeeds. The output generated by its first generator will be
524 interspersed by the output generated by the second generator. On each iteration
525 it will pass the next consecutive element from the container attribute to the
526 first embedded generator. The second embedded generator does not get passed
527 any attributes (it gets invoked using an `unused_type` as its attribute).
528 Therefore the number of iterations will not be larger than the number of
529 elements in the container passed as its attribute. An empty container will make
530 the list generator fail.
531
532 [tip If you want to use the list generator and still allow for an empty
533 attribute, you can use the optional operator (see __karma_optional__):
534
535 ``-(a % b)``
536
537 which will succeed even if the provided container attribute does not
538 contain any elements.
539 ]
540
541 [heading Complexity]
542
543 [:The overall complexity of the list generator is defined by the
544 complexity of its embedded generators multiplied by the number of executed
545 iterations. The complexity of the list generator itself is O(N), where N is
546 the number of elements in the container passed as its attribute.]
547
548 [heading Example]
549
550 [note The test harness for the example(s) below is presented in the
551 __karma_basics_examples__ section.]
552
553 Some includes:
554
555 [reference_karma_includes]
556
557 Some using declarations:
558
559 [reference_karma_using_declarations_list]
560
561 Basic usage of a list generator:
562
563 [reference_karma_list]
564
565 [endsect]
566
567 [/////////////////////////////////////////////////////////////////////////////]
568 [section:optional Optional Generator (`-a`)]
569
570 [heading Description]
571
572 The optional generator is used to conditionally execute an embedded generator.
573 It succeeds always.
574
575 [heading Header]
576
577 // forwards to <boost/spirit/home/karma/operator/optional.hpp>
578 #include <boost/spirit/include/karma_optional.hpp>
579
580 Also, see __include_structure__.
581
582 [heading Model of]
583
584 [:__unary_generator_concept__]
585
586 [heading Expression Semantics]
587
588 Semantics of an expression is defined only where it differs from, or is not
589 defined in __unary_generator_concept__.
590
591 [table
592 [[Expression] [Semantics]]
593 [[`-a`] [The generator `a` is executed depending on the
594 availability of an attribute. The optional generator
595 succeeds if its embedded generator succeeds
596 (unless the underlying output stream reports an
597 error).]]
598 ]
599
600 [heading Attributes]
601
602 See __karma_comp_attr_notation__.
603
604 [table
605 [[Expression] [Attribute]]
606 [[`-a` (optional, unary `-`)]
607 [``a: A --> -a: optional<A>
608 a: Unused --> -a: Unused``]]
609 ]
610
611 [important The table above uses `optional<A>` as a placeholder only. The
612 notation of `optional<A>` stands for the data type
613 `boost::optional<A>`.]
614
615 The optional generator will execute its embedded generator once if the provided
616 attribute holds a valid value. It forwards the value held in its attribute
617 to the embedded generator.
618
619 It is important to note, that the optional generator does not perform any
620 buffering of the output generated by its embedded elements. That means that any
621 failing element might have already generated some output, which is /not/
622 rolled back.
623
624 [tip The simplest way to force a optional generator to behave as if it did
625 buffering is to wrap it into a buffering directive (see
626 __karma_buffer__):
627
628 ``buffer[-a]``
629
630 which will /not/ generate any output in case of a failing generator `-a`.
631 ]
632
633 [heading Complexity]
634
635 [:The overall complexity of the optional generator is defined by the
636 complexity of its embedded generator. The complexity of the optional
637 generator itself is O(1).]
638
639 [heading Example]
640
641 [note The test harness for the example(s) below is presented in the
642 __karma_basics_examples__ section.]
643
644 Some includes:
645
646 [reference_karma_includes]
647
648 Some using declarations:
649
650 [reference_karma_using_declarations_optional]
651
652 Basic usage of an optional generator:
653
654 [reference_karma_optional1]
655
656 Usage and result of an empty optional generator:
657
658 [reference_karma_optional2]
659
660 [endsect]
661
662 [/////////////////////////////////////////////////////////////////////////////]
663 [section:and_predicate And-Predicate Generator (`&a`)]
664
665 [heading Description]
666
667 The and-predicate generator is used to test, whether the embedded generator
668 succeeds without generating any output. It succeeds if the embedded generator
669 succeeds.
670
671 [heading Header]
672
673 // forwards to <boost/spirit/home/karma/operator/and_predicate.hpp>
674 #include <boost/spirit/include/karma_and_predicate.hpp>
675
676 Also, see __include_structure__.
677
678 [heading Model of]
679
680 [:__unary_generator_concept__]
681
682 [heading Expression Semantics]
683
684 Semantics of an expression is defined only where it differs from, or is not
685 defined in __unary_generator_concept__.
686
687 [table
688 [[Expression] [Semantics]]
689 [[`&a`] [The generator `a` is executed for the sole purpose of
690 testing whether it succeeds. The and-predicate
691 generator succeeds if its embedded generator
692 succeeds (unless the underlying output stream
693 reports an error). The and-predicate never produces
694 any output.]]
695 ]
696
697 The and generator is implemented by redirecting all output produced by its
698 embedded generator into a discarding device.
699
700 [heading Attributes]
701
702 See __karma_comp_attr_notation__.
703
704 [table
705 [[Expression] [Attribute]]
706 [[`&a` (and-predicate, unary `&`)] [`a: A --> &a: A`]]
707 ]
708
709 [note The attribute of the and-predicate is not always `unused_type`, which is
710 different from Qi's and-predicate. This is necessary as the generator the
711 and predicate is attached to most of the time needs an attribute.
712 ]
713
714 [heading Complexity]
715
716 [:The overall complexity of the and-predicate generator is defined by the
717 complexity of its embedded generator. The complexity of the and-predicate
718 generator itself is O(1).]
719
720 [heading Example]
721
722 [note The test harness for the example(s) below is presented in the
723 __karma_basics_examples__ section.]
724
725 Some includes:
726
727 [reference_karma_includes]
728
729 Some using declarations:
730
731 [reference_karma_using_declarations_and_predicate]
732
733 Basic usage of an and predicate generator:
734
735 [reference_karma_and_predicate]
736
737 [endsect]
738
739 [/////////////////////////////////////////////////////////////////////////////]
740 [section:not_predicate Not-Predicate Generator (`!a`)]
741
742 [heading Description]
743
744 The not-predicate generator is used to test, whether the embedded generator
745 fails, without generating any output. It succeeds if the embedded generator
746 fails.
747
748 [heading Header]
749
750 // forwards to <boost/spirit/home/karma/operator/not_predicate.hpp>
751 #include <boost/spirit/include/karma_not_predicate.hpp>
752
753 Also, see __include_structure__.
754
755 [heading Model of]
756
757 [:__unary_generator_concept__]
758
759 [heading Expression Semantics]
760
761 Semantics of an expression is defined only where it differs from, or is not
762 defined in __unary_generator_concept__.
763
764 [table
765 [[Expression] [Semantics]]
766 [[`!a`] [The generator `a` is executed for the sole purpose of
767 testing whether it succeeds. The not-predicate
768 generator succeeds if its embedded generator
769 fails (unless the underlying output stream
770 reports an error). The not-predicate never produces
771 any output.]]
772 ]
773
774 The not generator is implemented by redirecting all output produced by its
775 embedded generator into a discarding device.
776
777 [heading Attributes]
778
779 See __karma_comp_attr_notation__.
780
781 [table
782 [[Expression] [Attribute]]
783 [[`!a` (not-predicate, unary `!`)] [`a: A --> !a: A`]]
784 ]
785
786 [note The attribute of the not-predicate is not always `unused_type`, which is
787 different from Qi's not-predicate. This is necessary as the generator the
788 and-predicate is attached to most of the time needs an attribute.
789 ]
790
791 [heading Complexity]
792
793 [:The overall complexity of the not-predicate generator is defined by the
794 complexity of its embedded generator. The complexity of the not-predicate
795 generator itself is O(1).]
796
797 [heading Example]
798
799 [note The test harness for the example(s) below is presented in the
800 __karma_basics_examples__ section.]
801
802 Some includes:
803
804 [reference_karma_includes]
805
806 Some using declarations:
807
808 [reference_karma_using_declarations_not_predicate]
809
810 Basic usage of a not predicate generator:
811
812 [reference_karma_not_predicate]
813
814 [endsect]
815
816 [endsect]