]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | [/////////////////////////////////////////////////////////////////////////////] | |
10 | [section:num_list Number List - Printing Numbers From a std::vector] | |
11 | ||
12 | [heading Using the List Operator] | |
13 | ||
14 | The C++ Standard library lacks an important feature, namely the support for | |
15 | any formatted output of containers. Sure, it's fairly easy to write a custom | |
16 | routine to output a specific container, but doing so over and over again is | |
17 | tedious at best. In this section we will demonstrate some more of the | |
18 | capabilities of __karma__ for generating output from arbitrary STL containers. | |
19 | We will build on the example presented in an earlier section (see | |
20 | [link spirit.karma.tutorials.warming_up Warming Up]). | |
21 | ||
22 | The full source code of the example shown in this section can be found here: | |
23 | [@../../example/karma/num_list2.cpp num_list2.cpp]. | |
24 | ||
25 | [import ../../example/karma/num_list2.cpp] | |
26 | ||
27 | This time we take advantage of Karma's __karma_list__ operator. The semantics | |
28 | of the list operator are fully equivalent to the semantics of the sequence | |
29 | we used before. The generator expression | |
30 | ||
31 | double_ << *(',' << double_) | |
32 | ||
33 | is semantically equivalent to the generator expression | |
34 | ||
35 | double_ % ',' | |
36 | ||
37 | simplifying the overall code. The list operator's attribute is compatible with | |
38 | any STL container as well. For a change we use a `std::vector<double>` | |
39 | instead of the `std::list<double>` we used before. Additionally, the routine | |
40 | `generate_numbers` takes the container as a template parameter, so it will now | |
41 | work with any STL container holding `double` numbers. | |
42 | ||
43 | [tutorial_karma_numlist2] | |
44 | ||
45 | [note Despite the container being a template parameter, the __karma__ | |
46 | formatting expression (`double_ % ','`) does not depend on the actual | |
47 | type of the passed container. The only precondition to be met here is | |
48 | that the elements stored in the container have to be convertible to | |
49 | `double`.] | |
50 | ||
51 | [heading Generate Output from Arbitrary Data] | |
52 | ||
53 | The output routine developed above is still not generically usable for all types | |
54 | of STL containers and for arbitrary elements stored in them. In order to be | |
55 | usable the items stored in the container still need to be convertible to a | |
56 | `double`. Fortunately __karma__ is capable to output arbitrary | |
57 | data types while using the same format description expression. It implements | |
58 | the [karma_stream `stream`] generators which are able to consume any attribute | |
59 | type as long as a matching standard streaming operator is defined. I.e. | |
60 | for any attribute type `Attrib` a function: | |
61 | ||
62 | std::ostream& operator<< (std::ostream&, Attrib const&); | |
63 | ||
64 | needs to be available. The [karma_stream `stream`] generator will use the | |
65 | standard streaming operator to generate the output. | |
66 | ||
67 | The following example modifies the code shown above to utilize the | |
68 | [karma_stream `stream`] operator, which makes it compatible with almost any | |
69 | data type. We implement a custom data type `complex` to demonstrate this. The | |
70 | example shows how it is possible to integrate this (or any other) custom data | |
71 | type into the __karma__ generator framework. | |
72 | ||
73 | [import ../../example/karma/num_list3.cpp] | |
74 | ||
75 | This is the custom data structure together with the required standard streaming | |
76 | operator: | |
77 | ||
78 | [tutorial_karma_numlist3_complex] | |
79 | ||
80 | And this is the actual call to generate the output from a vector of those. This | |
81 | time we interleave the generated output with newline breaks (see | |
82 | __karma_eol__), putting each complex number onto a separate line: | |
83 | ||
84 | [tutorial_karma_numlist3] | |
85 | ||
86 | The code shown is fully generic and can be used with any STL container as long | |
87 | as the data items stored in that container implement the standard streaming | |
88 | operator. | |
89 | ||
90 | The full source code of the example presented in this section can be found here: | |
91 | [@../../example/karma/num_list3.cpp num_list3.cpp]. | |
92 | ||
93 | [endsect] | |
94 | ||
95 | [/////////////////////////////////////////////////////////////////////////////] | |
96 | [section:num_matrix Matrix of Numbers - Printing Numbers From a Matrix] | |
97 | ||
98 | In this section we will discuss the possibilities of __karma__ when it comes to | |
99 | generating output from more complex - but still regular - data structures. | |
100 | For simplicity we will use a `std::vector<std::vector<int> >` as a poor | |
101 | man's matrix representation. But even if the data structure seems to be very | |
102 | simple, the presented principles are applicable to more complex, or custom | |
103 | data structures as well. The full source code of the example discussed in this | |
104 | section can be found here: [@../../example/karma/num_matrix.cpp num_matrix.cpp]. | |
105 | ||
106 | [import ../../example/karma/num_matrix.cpp] | |
107 | ||
108 | [endsect] |