]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/test/x3/attribute_type_check.cpp
1 #include <boost/spirit/home/x3.hpp>
3 #include <boost/core/lightweight_test.hpp>
4 #include <boost/fusion/include/vector.hpp>
5 #include <boost/fusion/include/make_vector.hpp>
6 #include <boost/fusion/include/equal_to.hpp>
7 #include <boost/type_traits/is_same.hpp>
8 #include <boost/optional.hpp>
11 namespace x3
= boost::spirit::x3
;
13 // just an `attr` with added type checker
14 template <typename Value
, typename Expected
>
15 struct checked_attr_parser
: x3::attr_parser
<Value
>
17 using base_t
= x3::attr_parser
<Value
>;
19 checked_attr_parser(Value
const& value
) : base_t(value
) {}
20 checked_attr_parser(Value
&& value
) : base_t(std::move(value
)) {}
22 template <typename Iterator
, typename Context
23 , typename RuleContext
, typename Attribute
>
24 bool parse(Iterator
& first
, Iterator
const& last
25 , Context
const& ctx
, RuleContext
& rctx
, Attribute
& attr_
) const
27 static_assert(boost::is_same
<Expected
, Attribute
>::value
,
28 "attribute type check failed");
29 return base_t::parse(first
, last
, ctx
, rctx
, attr_
);
33 template <typename Expected
, typename Value
>
34 static inline checked_attr_parser
<boost::decay_t
<Value
>, Expected
>
35 checked_attr(Value
&& value
) { return { std::forward
<Value
>(value
) }; }
37 // instantiate our type checker
38 // (checks attribute value just to be sure we are ok)
39 template <typename Value
, typename Expr
>
40 static void test_expr(Value
const& v
, Expr
&& expr
)
44 BOOST_TEST((x3::parse(it
, it
, std::forward
<Expr
>(expr
), r
)));
48 template <typename Expr
, typename Attribute
>
49 static void gen_sequence(Attribute
const& attribute
, Expr
&& expr
)
51 test_expr(attribute
, expr
);
52 test_expr(attribute
, expr
>> x3::eps
);
55 template <typename Expected
, typename
... ExpectedTail
, typename Attribute
, typename Expr
, typename Value
, typename
... Tail
>
56 static void gen_sequence(Attribute
const& attribute
, Expr
&& expr
, Value
const& v
, Tail
const&... tail
)
58 gen_sequence
<ExpectedTail
...>(attribute
, expr
>> checked_attr
<Expected
>(v
), tail
...);
59 gen_sequence
<ExpectedTail
...>(attribute
, expr
>> x3::eps
>> checked_attr
<Expected
>(v
), tail
...);
60 gen_sequence
<ExpectedTail
...>(attribute
, expr
>> (x3::eps
>> checked_attr
<Expected
>(v
)), tail
...);
63 template <typename Expected
, typename
... ExpectedTail
, typename Attribute
, typename Value
, typename
... Tail
>
64 static void gen_sequence_tests(Attribute
const& attribute
, Value
const& v
, Tail
const&... tail
)
66 gen_sequence
<ExpectedTail
...>(attribute
, checked_attr
<Expected
>(v
), tail
...);
67 gen_sequence
<ExpectedTail
...>(attribute
, x3::eps
>> checked_attr
<Expected
>(v
), tail
...);
70 template <typename Expected
, typename Value
>
71 static void gen_single_item_tests(Value
const& v
)
73 Expected
attribute(v
);
74 gen_sequence(attribute
, checked_attr
<Expected
>(v
));
75 gen_sequence(attribute
, x3::eps
>> checked_attr
<Expected
>(v
));
78 template <typename Expected
, typename
... ExpectedTail
, typename Value
, typename
... Tail
>
79 static void gen_single_item_tests(Value
const& v
, Tail
const&... tail
)
81 gen_single_item_tests
<Expected
>(v
);
82 gen_single_item_tests
<ExpectedTail
...>(tail
...);
85 template <typename
... Expected
, typename
... Values
>
86 static void gen_tests(Values
const&... values
)
88 gen_single_item_tests
<Expected
...>(values
...);
90 boost::fusion::vector
<Expected
...> attribute
= boost::fusion::make_vector(values
...);
91 gen_sequence_tests
<Expected
...>(attribute
, values
...);
94 template <typename
... Attributes
>
95 void make_test(Attributes
const&... attrs
)
97 // I would like to place all of this in a single call
98 // but it requires tremendous amount of heap to compile
99 gen_tests
<Attributes
...>(attrs
...);
101 boost::optional
<Attributes
>...
102 , boost::fusion::vector
<Attributes
>...
103 >(attrs
..., attrs
...);
105 boost::optional
<boost::fusion::vector
<Attributes
>>...
106 , boost::fusion::vector
<boost::optional
<Attributes
>>...
107 >(boost::fusion::vector
<Attributes
>(attrs
)..., attrs
...);
112 make_test
<int, std::string
>(123, "hello");
113 return boost::report_errors();