Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / spirit / test / x3 / fusion_map.cpp
1 /*=============================================================================
2   Copyright (c) 2001-2013 Joel de Guzman
3
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>
11
12 #include <string>
13 #include <iostream>
14 #include "test.hpp"
15
16 struct AdaptedStruct {
17     std::string key1;
18     std::string key2;
19 };
20
21 class key1_attr {};
22 class key2_attr {};
23
24 BOOST_FUSION_ADAPT_ASSOC_STRUCT(
25     AdaptedStruct,
26     (std::string, key1, class key1_attr)
27     (std::string, key2, class key2_attr)
28     )
29
30 template <class Parser, class Attribute>
31 bool test_attr(const std::string in,Parser const& p, Attribute& attr) {
32     auto it = in.begin();
33     return boost::spirit::x3::parse(it,in.end(), p, attr);
34 }
35
36 // force tratis::move_to to overwrite destination, insteadof appending
37 namespace boost { namespace spirit { namespace x3 { namespace traits {
38 template <>
39 struct build_container<char> : mpl::identity<std::string> {};
40 }}}}
41
42 int
43 main()
44 {
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_;
54
55         {
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");
59         }
60         {
61             AdaptedStruct attr_;
62             BOOST_TEST(test_attr("key1=ABC", kv1, attr_));
63             BOOST_TEST(attr_.key1 == "ABC");
64             BOOST_TEST(attr_.key2 == "");
65         }
66     }
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_(';');
71
72         AdaptedStruct attr_;
73         BOOST_TEST(test_attr("key1=ABC", eps >>  (kv1 % ';') , attr_));
74         BOOST_TEST(attr_.key1 == "ABC");
75         BOOST_TEST(attr_.key2 == "");
76     }
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_(';');
80
81         {
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");
85         }
86         {
87             AdaptedStruct attr_;
88             BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_));
89             BOOST_TEST(attr_.key1 == "XYZ");
90         }
91     }
92
93     { // parsing repeated sequence directly into fusion map (append)
94         /* NOT IMPLEMENTED
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>());
98
99         BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ";", attr_));
100         BOOST_TEST(fusion::at_key<key1_attr>(attr_) == {"ABC","XYZ"});
101         */
102     }
103
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_(';');
109
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");
114     }
115
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_(';');
122
123         {
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");
128         }
129         {
130             AdaptedStruct attr_;
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");
134         }
135     }
136
137     return boost::report_errors();
138 }