1 /*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
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 #if !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP)
10 #define BOOST_SPIRIT_FUNDAMENTAL_IPP
12 #include <boost/mpl/int.hpp>
14 namespace boost { namespace spirit {
16 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
18 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
19 BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER2(count_wrapper, count);
20 #endif // defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
24 ///////////////////////////////////////////////////////////////////////////
26 // Helper template for counting the number of nodes contained in a
28 // All parser_category type parsers are counted as nodes.
30 ///////////////////////////////////////////////////////////////////////////
31 template <typename CategoryT>
35 struct nodes<plain_parser_category> {
37 template <typename ParserT, typename LeafCountT>
40 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
41 enum { value = (LeafCountT::value + 1) };
45 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
48 struct nodes<unary_parser_category> {
50 template <typename ParserT, typename LeafCountT>
53 typedef typename ParserT::subject_t subject_t;
54 typedef typename subject_t::parser_category_t subject_category_t;
56 typedef nodes<subject_category_t> nodes_t;
57 typedef typename count_wrapper<nodes_t>
58 ::template result_<subject_t, LeafCountT> count_t;
60 BOOST_STATIC_CONSTANT(int, value = count_t::value + 1);
65 struct nodes<action_parser_category> {
67 template <typename ParserT, typename LeafCountT>
70 typedef typename ParserT::subject_t subject_t;
71 typedef typename subject_t::parser_category_t subject_category_t;
73 typedef nodes<subject_category_t> nodes_t;
74 typedef typename count_wrapper<nodes_t>
75 ::template result_<subject_t, LeafCountT> count_t;
77 BOOST_STATIC_CONSTANT(int, value = count_t::value + 1);
82 struct nodes<binary_parser_category> {
84 template <typename ParserT, typename LeafCountT>
87 typedef typename ParserT::left_t left_t;
88 typedef typename ParserT::right_t right_t;
89 typedef typename left_t::parser_category_t left_category_t;
90 typedef typename right_t::parser_category_t right_category_t;
92 typedef nodes<left_category_t> left_nodes_t;
93 typedef typename count_wrapper<left_nodes_t>
94 ::template result_<left_t, LeafCountT> left_count_t;
96 typedef nodes<right_category_t> right_nodes_t;
97 typedef typename count_wrapper<right_nodes_t>
98 ::template result_<right_t, LeafCountT> right_count_t;
100 BOOST_STATIC_CONSTANT(int,
101 value = (left_count_t::value + right_count_t::value + 1));
108 struct nodes<unary_parser_category> {
110 template <typename ParserT, typename LeafCountT>
113 typedef typename ParserT::subject_t subject_t;
114 typedef typename subject_t::parser_category_t subject_category_t;
116 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
117 enum { value = (nodes<subject_category_t>
118 ::template count<subject_t, LeafCountT>::value + 1) };
123 struct nodes<action_parser_category> {
125 template <typename ParserT, typename LeafCountT>
128 typedef typename ParserT::subject_t subject_t;
129 typedef typename subject_t::parser_category_t subject_category_t;
131 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
132 enum { value = (nodes<subject_category_t>
133 ::template count<subject_t, LeafCountT>::value + 1) };
138 struct nodes<binary_parser_category> {
140 template <typename ParserT, typename LeafCountT>
143 typedef typename ParserT::left_t left_t;
144 typedef typename ParserT::right_t right_t;
145 typedef typename left_t::parser_category_t left_category_t;
146 typedef typename right_t::parser_category_t right_category_t;
148 typedef count self_t;
150 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
152 leftcount = (nodes<left_category_t>
153 ::template count<left_t, LeafCountT>::value),
154 rightcount = (nodes<right_category_t>
155 ::template count<right_t, LeafCountT>::value),
156 value = ((self_t::leftcount) + (self_t::rightcount) + 1)
163 ///////////////////////////////////////////////////////////////////////////
165 // Helper template for counting the number of leaf nodes contained in a
166 // given parser type.
167 // Only plain_parser_category type parsers are counted as leaf nodes.
169 ///////////////////////////////////////////////////////////////////////////
170 template <typename CategoryT>
174 struct leafs<plain_parser_category> {
176 template <typename ParserT, typename LeafCountT>
179 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
180 enum { value = (LeafCountT::value + 1) };
184 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
187 struct leafs<unary_parser_category> {
189 template <typename ParserT, typename LeafCountT>
192 typedef typename ParserT::subject_t subject_t;
193 typedef typename subject_t::parser_category_t subject_category_t;
195 typedef leafs<subject_category_t> nodes_t;
196 typedef typename count_wrapper<nodes_t>
197 ::template result_<subject_t, LeafCountT> count_t;
199 BOOST_STATIC_CONSTANT(int, value = count_t::value);
204 struct leafs<action_parser_category> {
206 template <typename ParserT, typename LeafCountT>
209 typedef typename ParserT::subject_t subject_t;
210 typedef typename subject_t::parser_category_t subject_category_t;
212 typedef leafs<subject_category_t> nodes_t;
213 typedef typename count_wrapper<nodes_t>
214 ::template result_<subject_t, LeafCountT> count_t;
216 BOOST_STATIC_CONSTANT(int, value = count_t::value);
221 struct leafs<binary_parser_category> {
223 template <typename ParserT, typename LeafCountT>
226 typedef typename ParserT::left_t left_t;
227 typedef typename ParserT::right_t right_t;
228 typedef typename left_t::parser_category_t left_category_t;
229 typedef typename right_t::parser_category_t right_category_t;
231 typedef leafs<left_category_t> left_nodes_t;
232 typedef typename count_wrapper<left_nodes_t>
233 ::template result_<left_t, LeafCountT> left_count_t;
235 typedef leafs<right_category_t> right_nodes_t;
236 typedef typename count_wrapper<right_nodes_t>
237 ::template result_<right_t, LeafCountT> right_count_t;
239 BOOST_STATIC_CONSTANT(int,
240 value = (left_count_t::value + right_count_t::value));
247 struct leafs<unary_parser_category> {
249 template <typename ParserT, typename LeafCountT>
252 typedef typename ParserT::subject_t subject_t;
253 typedef typename subject_t::parser_category_t subject_category_t;
255 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
256 enum { value = (leafs<subject_category_t>
257 ::template count<subject_t, LeafCountT>::value) };
262 struct leafs<action_parser_category> {
264 template <typename ParserT, typename LeafCountT>
267 typedef typename ParserT::subject_t subject_t;
268 typedef typename subject_t::parser_category_t subject_category_t;
270 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
271 enum { value = (leafs<subject_category_t>
272 ::template count<subject_t, LeafCountT>::value) };
277 struct leafs<binary_parser_category> {
279 template <typename ParserT, typename LeafCountT>
282 typedef typename ParserT::left_t left_t;
283 typedef typename ParserT::right_t right_t;
284 typedef typename left_t::parser_category_t left_category_t;
285 typedef typename right_t::parser_category_t right_category_t;
287 typedef count self_t;
289 // __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
291 leftcount = (leafs<left_category_t>
292 ::template count<left_t, LeafCountT>::value),
293 rightcount = (leafs<right_category_t>
294 ::template count<right_t, LeafCountT>::value),
295 value = (self_t::leftcount + self_t::rightcount)
304 ///////////////////////////////////////////////////////////////////////////////
305 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
307 }} // namespace boost::spirit
309 #endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP)