Ticket #5780: test_boost_fusion_adaption_with_karma.cpp

File test_boost_fusion_adaption_with_karma.cpp, 3.7 KB (added by Torsten Maehne <Torsten.Maehne@…>, 11 years ago)

Test case

Line 
1/*
2 * bufilt -- A Boost.Units C++ compiler messages filter
3 *
4 * Copyright (C) 2008--2011 Torsten Maehne
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or copy at
8 * http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11/*!
12 * \file test_boost_fusion_adaption_with_karma.cpp
13 *
14 * \brief Test of Boost.Fusion adapted ADTs and structs in Boost.Spirit.Karma rules.
15 *
16 * \author Torsten Maehne
17 * \date 2011-08-12
18 * \version $Id$
19 */
20#define BOOST_TEST_MODULE test_boost_rational_adaption
21#include <boost/test/included/unit_test.hpp>
22#include <boost/test/output_test_stream.hpp>
23#include <boost/rational.hpp>
24#include <boost/version.hpp>
25#if BOOST_VERSION < 104500
26// Until Boost 1.44 use BOOST_FUSION_ADAPT_CLASS
27#include <boost/fusion/include/adapt_class.hpp>
28#else
29// Since Boost 1.45 BOOST_FUSION_ADAPT_CLASS is named BOOST_FUSION_ADAPT_ADT
30#include <boost/fusion/include/adapt_adt.hpp>
31#endif
32
33#include <boost/fusion/include/adapt_struct.hpp>
34// Include only the strictly necessary parts of Boost.Spirit.Karma to reduce compile time.
35#include <boost/spirit/include/karma_char.hpp>
36#include <boost/spirit/include/karma_nonterminal.hpp>
37#include <boost/spirit/include/karma_numeric.hpp>
38#include <boost/spirit/include/karma_operator.hpp>
39#include <boost/spirit/include/karma_generate.hpp>
40
41namespace {
42
43typedef boost::rational<long> rational_adt;
44
45struct rational_struct {
46 long numerator, denominator;
47
48 explicit rational_struct(long num = 0l, long den = 1l)
49 : numerator(num), denominator(den)
50 {}
51};
52
53} // namespace bufilt
54
55
56#if BOOST_VERSION < 104500
57// Adapt class boost::rational<long> to a Fusion sequence.
58BOOST_FUSION_ADAPT_CLASS(
59 ::rational_adt,
60 (long, long, obj.numerator(), obj.numerator(val))
61 (long, long, obj.denominator(), obj.denominator(val))
62)
63#else
64// Adapt ADT boost::rational<long> to a Fusion sequence.
65BOOST_FUSION_ADAPT_ADT(
66 ::rational_adt,
67 (long, long, obj.numerator(), obj.numerator(val))
68 (long, long, obj.denominator(), obj.denominator(val))
69)
70#endif
71
72
73// Adapt struct ::rational_struct to a Fusion sequence.
74BOOST_FUSION_ADAPT_STRUCT(
75 ::rational_struct,
76 (long, numerator)
77 (long, denominator)
78)
79
80
81//! \test Test the usage of the adapted ADT and struct in Karma rules.
82BOOST_AUTO_TEST_CASE(test_boost_fusion_adaption_with_karma)
83{
84 // Namespace alias for Boost Spirit Karma.
85 namespace karma = boost::spirit::karma;
86 // Namespace alias for Boost Spirit Phoenix.
87 namespace phx = boost::phoenix;
88
89 using karma::long_;
90
91 using boost::spirit::karma::generate;
92
93 using boost::test_tools::output_test_stream;
94 output_test_stream tout;
95 typedef std::ostream_iterator<char> tout_iter_type;
96
97 // Output iterator type used as sink for the Boost.Spirit.Karma generator to the output test stream.
98 tout_iter_type tout_iter(tout);
99
100 // Karma rules with adapted ADT does not compile against Boost >= 1.45
101 // Output generation rule for ::rational_adt.
102 karma::rule<tout_iter_type, rational_adt()> rational_adt_;
103 rational_adt_.name("rational_adt_");
104 rational_adt_ = long_ << '/' << long_;
105
106 // The Karma rule with an equivalent adapted struct compiles against Boost >= 1.45
107 // Output generation rule for ::rational_struct.
108 karma::rule<tout_iter_type, rational_struct()> rational_struct_;
109 rational_struct_.name("rational_struct_");
110 rational_struct_ = long_ << '/' << long_;
111
112 // Check the Karma generator rules.
113
114 // Karma rules with adapted ADT does not compile against Boost >= 1.45
115 rational_adt rat1(1, 2);
116 BOOST_CHECK(generate(tout_iter, rational_adt_, rat1));
117 BOOST_CHECK(tout.is_equal("1/2"));
118
119 rational_struct rat2(1, 3);
120 BOOST_CHECK(generate(tout_iter, rational_struct_, rat2));
121 BOOST_CHECK(tout.is_equal("1/3"));
122}