| 1 | /*============================================================================= |
| 2 | Copyright (c) 2013 Carl Barron |
| 3 | Copyright (c) 2015 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 | #define BOOST_SPIRIT_X3_DEBUG |
| 10 | #include <boost/spirit/home/x3.hpp> |
| 11 | #include <boost/spirit/home/support/char_encoding/unicode.hpp> |
| 12 | #include <boost/fusion/include/at.hpp> |
| 13 | #include <boost/fusion/include/vector.hpp> |
| 14 | #include <boost/fusion/include/adapt_struct.hpp> |
| 15 | #include <boost/mpl/int.hpp> |
| 16 | #include <boost/optional.hpp> |
| 17 | |
| 18 | #include <iostream> |
| 19 | #include <numeric> |
| 20 | #include <vector> |
| 21 | #include "test.hpp" |
| 22 | |
| 23 | struct roman |
| 24 | { |
| 25 | boost::optional<int> a; |
| 26 | boost::optional<int> b; |
| 27 | boost::optional<int> c; |
| 28 | }; |
| 29 | |
| 30 | BOOST_FUSION_ADAPT_STRUCT(roman, |
| 31 | a, b, c |
| 32 | ) |
| 33 | |
| 34 | int eval(roman const & c) |
| 35 | { |
| 36 | return c.a.get_value_or(v: 0) + c.b.get_value_or(v: 0) + c.c.get_value_or(v: 0); |
| 37 | } |
| 38 | |
| 39 | int |
| 40 | main() |
| 41 | { |
| 42 | using spirit_test::test; |
| 43 | using spirit_test::test_attr; |
| 44 | using boost::spirit::x3::symbols; |
| 45 | |
| 46 | { // construction from initializer-list |
| 47 | symbols<int> const ones = |
| 48 | { |
| 49 | {"I" , 1}, {"II" , 2}, {"III" , 3}, {"IV" , 4}, |
| 50 | {"V" , 5}, {"VI" , 6}, {"VII" , 7}, {"VIII" , 8}, |
| 51 | {"IX" , 9} |
| 52 | }; |
| 53 | symbols<int> const tens = |
| 54 | { |
| 55 | {"X" , 10}, {"XX" , 20}, {"XXX" , 30}, {"XL" , 40}, |
| 56 | {"L" , 50}, {"LX" , 60}, {"LXX" , 70}, {"LXXX" , 80}, |
| 57 | {"XC" , 90} |
| 58 | }; |
| 59 | symbols<int> const hundreds |
| 60 | { |
| 61 | {"C" , 100}, {"CC" , 200}, {"CCC" , 300}, {"CD" , 400}, |
| 62 | {"D" , 500}, {"DC" , 600}, {"DCC" , 700}, {"DCCC" , 800}, |
| 63 | {"CM" , 900} |
| 64 | }; |
| 65 | |
| 66 | auto number = -hundreds >> -tens >> -ones; |
| 67 | |
| 68 | roman r; |
| 69 | BOOST_TEST((test_attr("CDXLII" , number, r))); |
| 70 | BOOST_TEST(eval(r) == 442); |
| 71 | } |
| 72 | |
| 73 | { // construction from initializer-list without attribute |
| 74 | symbols<> foo = {"a1" , "a2" , "a3" }; |
| 75 | |
| 76 | BOOST_TEST((test("a3" , foo))); |
| 77 | } |
| 78 | |
| 79 | { // assignment from initializer-list |
| 80 | symbols<> foo; |
| 81 | foo = {"a1" , "a2" , "a3" }; |
| 82 | |
| 83 | BOOST_TEST((test("a3" , foo))); |
| 84 | } |
| 85 | |
| 86 | { // unicode | construction from initializer-list |
| 87 | using namespace boost::spirit; |
| 88 | x3::symbols_parser<char_encoding::unicode, int> foo = {{U"a1" , 1}, {U"a2" , 2}, {U"a3" , 3}}; |
| 89 | |
| 90 | int r; |
| 91 | BOOST_TEST((test_attr(U"a3" , foo, r))); |
| 92 | BOOST_TEST(r == 3); |
| 93 | } |
| 94 | |
| 95 | return boost::report_errors(); |
| 96 | } |
| 97 | |