num_list.qbk 4.8 KB

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