]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2005 Jordan DeLong | |
3 | http://spirit.sourceforge.net/ | |
4 | ||
5 | Use, modification and distribution is subject to the Boost Software | |
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | http://www.boost.org/LICENSE_1_0.txt) | |
8 | =============================================================================*/ | |
9 | ||
10 | // Some tests of parsing on value_t's that aren't char or wchar_t. | |
11 | // | |
12 | // Part of what this is testing is that BOOST_SPIRIT_DEBUG doesn't | |
13 | // break when the scanner::value_t is some sort of non-char. | |
14 | #define SPIRIT_DEBUG_NODE | |
15 | ||
16 | #include <boost/spirit/include/classic_core.hpp> | |
17 | #include <boost/static_assert.hpp> | |
18 | #include <boost/type_traits/is_same.hpp> | |
19 | #include <deque> | |
20 | #include <iostream> | |
21 | ||
22 | namespace sp = BOOST_SPIRIT_CLASSIC_NS; | |
23 | ||
24 | namespace { | |
25 | ||
26 | struct grammar : sp::grammar<grammar> { | |
27 | template<class Scanner> | |
28 | struct definition { | |
29 | definition(grammar const&) | |
30 | { | |
31 | foo | |
32 | = sp::alpha_p | |
33 | | sp::alnum_p | |
34 | | sp::cntrl_p | |
35 | | sp::print_p | |
36 | | sp::blank_p | |
37 | | sp::digit_p | |
38 | | sp::graph_p | |
39 | | sp::lower_p | |
40 | | sp::upper_p | |
41 | | sp::xdigit_p | |
42 | | sp::punct_p | |
43 | ; | |
44 | } | |
45 | ||
46 | sp::rule<Scanner> foo; | |
47 | sp::rule<Scanner> const& | |
48 | start() const | |
49 | { | |
50 | return foo; | |
51 | } | |
52 | }; | |
53 | }; | |
54 | ||
55 | struct non_pod { | |
56 | non_pod() : value('1') {} | |
57 | char value; | |
58 | bool operator==(non_pod const& o) const { return value == o.value; } | |
59 | }; | |
60 | ||
11fdf7f2 | 61 | BOOST_ATTRIBUTE_UNUSED |
7c673cae FG |
62 | std::ostream& |
63 | operator<<(std::ostream& out, non_pod const& x) | |
64 | { | |
65 | out << x.value; | |
66 | return out; | |
67 | } | |
68 | ||
69 | template<class T> | |
70 | struct convertable_non_pod : non_pod { | |
71 | operator T() { return value; } | |
72 | }; | |
73 | ||
74 | struct nonpod_gram : sp::grammar<nonpod_gram> { | |
75 | template<class Scanner> | |
76 | struct definition { | |
77 | definition(nonpod_gram const&) | |
78 | { | |
79 | foo = sp::ch_p(typename Scanner::value_t()); | |
80 | } | |
81 | ||
82 | sp::rule<Scanner> foo; | |
83 | sp::rule<Scanner> const& | |
84 | start() const | |
85 | { | |
86 | return foo; | |
87 | } | |
88 | }; | |
89 | }; | |
90 | ||
91 | template<class Grammar, class ValueType> | |
92 | void | |
93 | test_type() | |
94 | { | |
95 | typedef std::deque<ValueType> container; | |
96 | typedef typename container::iterator iterator; | |
97 | typedef sp::scanner<iterator> scanner; | |
98 | ||
99 | container blah; | |
100 | blah.push_back(typename container::value_type()); | |
101 | blah.push_back(typename container::value_type()); | |
102 | ||
103 | iterator first = blah.begin(); | |
104 | iterator last = blah.end(); | |
105 | ||
106 | scanner scan(first, last); | |
107 | ||
108 | // Make sure this actually tries what we think it tries. | |
109 | BOOST_STATIC_ASSERT(( | |
110 | boost::is_same<typename scanner::value_t, ValueType>::value | |
111 | )); | |
112 | ||
113 | Grammar().parse(scan); | |
114 | } | |
115 | ||
116 | } | |
117 | ||
118 | int | |
119 | main() | |
120 | { | |
121 | // Make sure isfoo() style functions work for integral types. | |
122 | test_type<grammar, char>(); | |
123 | test_type<grammar, unsigned char>(); | |
124 | test_type<grammar, wchar_t>(); | |
125 | test_type<grammar, int>(); | |
126 | test_type<grammar, long>(); | |
127 | test_type<grammar, short>(); | |
128 | test_type<grammar, bool>(); | |
129 | ||
130 | // Non-POD's should work with things like alpha_p as long as we | |
131 | // can turn them into a type that can do isalpha(). | |
132 | test_type<grammar, convertable_non_pod<char> >(); | |
133 | test_type<grammar, convertable_non_pod<wchar_t> >(); | |
134 | test_type<grammar, convertable_non_pod<int> >(); | |
135 | ||
136 | // BOOST_SPIRIT_DEBUG should work with grammars that parse | |
137 | // non-POD's even if they can't do things like isalpha(). | |
138 | test_type<nonpod_gram, non_pod>(); | |
139 | } |