forked from boostorg/fusion
https://svn.boost.org/svn/boost/trunk ........ r40862 | dave | 2007-11-06 15:39:09 -0800 (Tue, 06 Nov 2007) | 2 lines Added missing copyright/license ........ r40863 | djowel | 2007-11-06 18:12:28 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40864 | aaron_windsor | 2007-11-06 18:30:38 -0800 (Tue, 06 Nov 2007) | 1 line Shortening file name of a graph test to < 32 characters ........ r40865 | djowel | 2007-11-06 18:34:18 -0800 (Tue, 06 Nov 2007) | 1 line added license info in copyright notice at the footer ........ r40866 | djowel | 2007-11-06 19:06:23 -0800 (Tue, 06 Nov 2007) | 1 line added license info in copyright notice at the footer ........ r40867 | djowel | 2007-11-06 19:23:31 -0800 (Tue, 06 Nov 2007) | 1 line added license info in copyright notice at the footer ........ r40868 | djowel | 2007-11-06 19:25:59 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40869 | djowel | 2007-11-06 19:27:38 -0800 (Tue, 06 Nov 2007) | 1 line added license info in copyright notice at the footer ........ r40870 | djowel | 2007-11-06 19:30:01 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40871 | djowel | 2007-11-06 19:35:49 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40872 | djowel | 2007-11-06 19:37:51 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40873 | djowel | 2007-11-06 19:46:23 -0800 (Tue, 06 Nov 2007) | 1 line added copyright and license info for each page. ........ r40874 | chris_kohlhoff | 2007-11-06 22:49:36 -0800 (Tue, 06 Nov 2007) | 2 lines Add copyright notice. ........ r40875 | chris_kohlhoff | 2007-11-06 22:53:17 -0800 (Tue, 06 Nov 2007) | 2 lines Add myself as asio maintainer. ........ r40876 | chris_kohlhoff | 2007-11-06 23:23:53 -0800 (Tue, 06 Nov 2007) | 2 lines Add asio. ........ r40877 | joaquin | 2007-11-07 00:45:27 -0800 (Wed, 07 Nov 2007) | 1 line reapplied change at rev 40284 ........ r40878 | johnmaddock | 2007-11-07 02:07:08 -0800 (Wed, 07 Nov 2007) | 1 line Ooops, got the pp-logic wrong and disable long double support for all Unix platforms, instead of just Intel on Linux prior to version 10. ........ r40879 | johnmaddock | 2007-11-07 02:09:50 -0800 (Wed, 07 Nov 2007) | 1 line Fix calls to fpclassify so they don't trigger macro expansion when fpclassify is a macro. ........ r40880 | t_schwinger | 2007-11-07 02:14:42 -0800 (Wed, 07 Nov 2007) | 3 lines adds FunctionTypes ........ r40881 | johnmaddock | 2007-11-07 03:50:02 -0800 (Wed, 07 Nov 2007) | 1 line Change test (again) so that the range of values tested matches original test: last change started testing more extreme input values, which caused regressions on Mac OS X. ........ r40882 | johnmaddock | 2007-11-07 03:59:39 -0800 (Wed, 07 Nov 2007) | 3 lines Disabled use of long double when BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS is defined. Disabled special-double precision error rates when BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS is defined. ........ r40883 | johnmaddock | 2007-11-07 04:04:01 -0800 (Wed, 07 Nov 2007) | 1 line Oops get the name of test right! ........ r40884 | anthonyw | 2007-11-07 04:10:17 -0800 (Wed, 07 Nov 2007) | 1 line Added missing licence and copyright ........ r40885 | garcia | 2007-11-07 04:25:16 -0800 (Wed, 07 Nov 2007) | 2 lines added logging library. ........ r40886 | garcia | 2007-11-07 05:38:53 -0800 (Wed, 07 Nov 2007) | 2 lines Exception was accepted. ........ r40887 | fcacciola | 2007-11-07 06:12:15 -0800 (Wed, 07 Nov 2007) | 1 line Added explicit failures for newly discovered GCC const ref binding bug (see Ticket #1301) ........ [SVN r40891]
169 lines
5.9 KiB
Plaintext
169 lines
5.9 KiB
Plaintext
[/==============================================================================
|
|
Copyright (C) 2001-2007 Joel de Guzman, Dan Marsden, Tobias Schwinger
|
|
|
|
Use, modification and distribution is subject to the Boost Software
|
|
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
===============================================================================/]
|
|
[section Quick Start]
|
|
|
|
I assume the reader is already familiar with tuples (__tuple__) and its
|
|
ancestor `std::pair`. The tuple is a generalization of `std::pair` for
|
|
multiple heterogeneous elements (triples, quadruples, etc.). The tuple is
|
|
more or less a synonym for fusion's `__vector__`.
|
|
|
|
For starters, we shall include all of Fusion's __sequence__(s) [footnote There
|
|
are finer grained header files available if you wish to have more control
|
|
over which components to include (see section __organization__ for
|
|
details).]:
|
|
|
|
#include <boost/fusion/sequence.hpp>
|
|
#include <boost/fusion/include/sequence.hpp>
|
|
|
|
Let's begin with a `__vector__` [footnote Unless otherwise noted, components are
|
|
in namespace `boost::fusion`. For the sake of simplicity, code in this
|
|
quick start implies `using` directives for the fusion components we will be
|
|
using.]:
|
|
|
|
__vector__<int, char, std::string> stuff(1, 'x', "howdy");
|
|
int i = __at_c__<0>(stuff);
|
|
char ch = __at_c__<1>(stuff);
|
|
std::string s = __at_c__<2>(stuff);
|
|
|
|
Just replace `tuple` for `__vector__` and `get` for `__at_c__` and this is exactly
|
|
like __tuple__. Actually, either names can be used interchangeably. Yet,
|
|
the similarity ends there. You can do a lot more with Fusion `__vector__` or
|
|
`tuple`. Let's see some examples.
|
|
|
|
[heading Print the vector as XML]
|
|
|
|
First, let's include the algorithms:
|
|
|
|
#include <boost/fusion/algorithm.hpp>
|
|
#include <boost/fusion/include/algorithm.hpp>
|
|
|
|
Now, let's write a function object that prints XML of the form <type>data</type>
|
|
for each member in the tuple.
|
|
|
|
struct print_xml
|
|
{
|
|
template <typename T>
|
|
void operator()(T const& x) const
|
|
{
|
|
std::cout
|
|
<< '<' << typeid(x).name() << '>'
|
|
<< x
|
|
<< "</" << typeid(x).name() << '>'
|
|
;
|
|
}
|
|
};
|
|
|
|
Now, finally:
|
|
|
|
__for_each__(stuff, print_xml());
|
|
|
|
That's it! `__for_each__` is a fusion algorithm. It is a generic algorithm
|
|
similar to __stl__'s. It iterates over the sequence and calls a user
|
|
supplied function. In our case, it calls `print_xml`'s `operator()` for
|
|
each element in `stuff`.
|
|
|
|
[caution The result of `typeid(x).name()` is platform specific. The code
|
|
here is just for exposition. Of course you already know that :-)]
|
|
|
|
`__for_each__` is generic. With `print_xml`, you can use it to print just about
|
|
any Fusion __sequence__.
|
|
|
|
[heading Print only pointers]
|
|
|
|
Let's get a little cleverer. Say we wish to write a /generic/ function
|
|
that takes in an arbitrary sequence and XML prints only those elements
|
|
which are pointers. Ah, easy. First, let's include the `is_pointer` boost
|
|
type trait:
|
|
|
|
#include <boost/type_traits/is_pointer.hpp>
|
|
|
|
Then, simply:
|
|
|
|
template <typename Sequence>
|
|
void xml_print_pointers(Sequence const& seq)
|
|
{
|
|
__for_each__(__filter_if__<boost::is_pointer<_> >(seq), print_xml());
|
|
}
|
|
|
|
`__filter_if__` is another Fusion algorithm. It returns a __filter_view__,
|
|
a conforming Fusion sequence. This view reflects only those elements that
|
|
pass the given predicate. In this case, the predicate is
|
|
`boost::is_pointer<_>`. This "filtered view" is then passed to the
|
|
__for_each__ algorithm, which then prints the "filtered view" as XML.
|
|
|
|
Easy, right?
|
|
|
|
[heading Associative tuples]
|
|
|
|
Ok, moving on...
|
|
|
|
Apart from `__vector__`, fusion has a couple of other sequence types to choose
|
|
from. Each sequence has its own characteristics. We have `__list__`, `__set__`,
|
|
`__map__`, plus a multitude of `views` that provide various ways to present the
|
|
sequences.
|
|
|
|
Fusion's `__map__` associate types with elements. It can be used as a cleverer
|
|
replacement of the `struct`. Example:
|
|
|
|
namespace fields
|
|
{
|
|
struct name;
|
|
struct age;
|
|
}
|
|
|
|
typedef __map__<
|
|
__fusion_pair__<fields::name, std::string>
|
|
, __fusion_pair__<fields::age, int> >
|
|
person;
|
|
|
|
`__map__` is an associative sequence. Its elements are Fusion pairs which differ
|
|
somewhat from `std::pair`. Fusion pairs only contain one member, with the type of
|
|
their second template parameter. The first type parameter of the pair is used as an
|
|
index to the associated element in the sequence. For example, given a `a_person`
|
|
of type, `person`, you can do:
|
|
|
|
using namespace fields;
|
|
std::string person_name = __at_key__<name>(a_person);
|
|
int person_age = __at_key__<age>(a_person);
|
|
|
|
Why go through all this trouble, you say? Well, for one, unlike the
|
|
`struct`, we are dealing with a generic data structure. There are a
|
|
multitude of facilities available at your disposal provided out of the box
|
|
with fusion or written by others. With these facilities, introspection
|
|
comes for free, for example. We can write one serialization function (well,
|
|
two, if you consider loading and saving) that will work for all your fusion
|
|
`__map__`s. Example:
|
|
|
|
struct saver
|
|
{
|
|
template <typename Pair>
|
|
void operator()(Pair const& data) const
|
|
{
|
|
some_archive << data.second;
|
|
}
|
|
};
|
|
|
|
template <typename Stuff>
|
|
void save(Stuff const& stuff)
|
|
{
|
|
__for_each__(stuff, saver());
|
|
}
|
|
|
|
The `save` function is generic and will work for all types of `stuff`
|
|
regardless if it is a `person`, a `dog` or a whole `alternate_universe`.
|
|
|
|
[heading Tip of the Iceberg]
|
|
|
|
And... we've barely scratched the surface! You can compose and expand the
|
|
data structures, remove elements from the structures, find specific data
|
|
types, query the elements, filter out types for inspection, transform data
|
|
structures, etc. What you've seen is just the tip of the iceberg.
|
|
|
|
[endsect]
|
|
|