1 /*=============================================================================
2 Copyright (c) 2001-2013 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 #include <boost/detail/lightweight_test.hpp>
8 #include <boost/spirit/home/x3.hpp>
9 #include <boost/fusion/include/make_map.hpp>
10 #include <boost/fusion/adapted/struct.hpp>
16 struct AdaptedStruct {
24 BOOST_FUSION_ADAPT_ASSOC_STRUCT(
26 (std::string, key1, class key1_attr)
27 (std::string, key2, class key2_attr)
30 template <class Parser, class Attribute>
31 bool test_attr(const std::string in,Parser const& p, Attribute& attr) {
33 return boost::spirit::x3::parse(it,in.end(), p, attr);
36 // force tratis::move_to to overwrite destination, insteadof appending
37 namespace boost { namespace spirit { namespace x3 { namespace traits {
39 struct build_container<char> : mpl::identity<std::string> {};
45 using spirit_test::test;
46 using boost::spirit::x3::lit;
47 using boost::spirit::x3::attr;
48 using boost::spirit::x3::char_;
49 using boost::spirit::x3::eps;
50 namespace fusion = boost::fusion;
51 { // parsing sequence directly into fusion map
52 auto const key1 = lit("key1") >> attr(key1_attr());
53 auto const kv1 = key1 >> lit("=") >> +char_;
56 auto attr_ = fusion::make_map<key1_attr>(std::string());
57 BOOST_TEST(test_attr("key1=ABC", kv1, attr_));
58 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
62 BOOST_TEST(test_attr("key1=ABC", kv1, attr_));
63 BOOST_TEST(attr_.key1 == "ABC");
64 BOOST_TEST(attr_.key2 == "");
67 { // case when parser handling fusion assoc sequence
68 // is on one side of another sequence
69 auto const key1 = lit("key1") >> attr(key1_attr());
70 auto const kv1 = key1 >> lit("=") >> +~char_(';');
73 BOOST_TEST(test_attr("key1=ABC", eps >> (kv1 % ';') , attr_));
74 BOOST_TEST(attr_.key1 == "ABC");
75 BOOST_TEST(attr_.key2 == "");
77 { // parsing repeated sequence directly into fusion map (overwrite)
78 auto const key1 = lit("key1") >> attr(key1_attr());
79 auto const kv1 = key1 >> lit("=") >> +~char_(';');
82 auto attr_ = fusion::make_map<key1_attr>(std::string());
83 BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_));
84 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "XYZ");
88 BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_));
89 BOOST_TEST(attr_.key1 == "XYZ");
93 { // parsing repeated sequence directly into fusion map (append)
95 auto const key1 = lit("key1") >> attr(key1_attr());
96 auto const kv1 = key1 >> lit("=") >> +char_;
97 auto attr_ = fusion::make_map<key1_attr>(std::vector<std::string>());
99 BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ";", attr_));
100 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == {"ABC","XYZ"});
104 { // alternative over key-value pairs
105 auto const key1 = lit("key1") >> attr(key1_attr());
106 auto const key2 = lit("key2") >> attr(key2_attr());
107 auto const kv1 = key1 >> lit("=") >> +~char_(';');
108 auto const kv2 = key2 >> lit("=") >> +~char_(';');
110 auto attr_ = fusion::make_map<key1_attr, key2_attr>(std::string(),std::string());
111 BOOST_TEST(test_attr("key2=XYZ;key1=ABC", (kv1|kv2) % ';', attr_));
112 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
113 BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
116 { // parsing sequence where key is a variant
117 namespace x3 = boost::spirit::x3;
118 auto key1 = lit("key1") >> attr(key1_attr());
119 auto key2 = lit("key2") >> attr(key2_attr());
120 auto keys = key1 | key2;
121 auto pair = keys >> lit("=") >> +~char_(';');
124 auto attr_ = fusion::make_map<key1_attr,key2_attr>(std::string(),std::string());
125 BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_));
126 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
127 BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
131 BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_));
132 BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
133 BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
137 return boost::report_errors();