]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/xpressive/include/boost/xpressive/detail/static/width_of.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / xpressive / include / boost / xpressive / detail / static / width_of.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////////////////////
2// width_of.hpp
3//
4// Copyright 2008 Eric Niebler. Distributed under the Boost
5// Software License, Version 1.0. (See accompanying file
6// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
9#define BOOST_XPRESSIVE_DETAIL_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
10
11// MS compatible compilers support #pragma once
12#if defined(_MSC_VER)
13# pragma once
14#endif
15
16#include <boost/ref.hpp>
17#include <boost/mpl/if.hpp>
18#include <boost/mpl/or.hpp>
19#include <boost/mpl/plus.hpp>
20#include <boost/mpl/times.hpp>
21#include <boost/mpl/assert.hpp>
22#include <boost/mpl/size_t.hpp>
23#include <boost/mpl/equal_to.hpp>
24#include <boost/type_traits/is_same.hpp>
25#include <boost/xpressive/detail/detail_fwd.hpp>
26#include <boost/xpressive/detail/static/type_traits.hpp>
27#include <boost/proto/traits.hpp>
28
29namespace boost { namespace xpressive { namespace detail
30{
31 template<typename Expr, typename Char, typename Tag = typename Expr::proto_tag>
32 struct width_of;
33
34 ///////////////////////////////////////////////////////////////////////////////
35 // add_widths
36 //
37 template<std::size_t N, std::size_t M>
38 struct add_widths
39 : mpl::size_t<N + M>
40 {};
41
42 template<std::size_t M>
43 struct add_widths<unknown_width::value, M>
44 : unknown_width
45 {};
46
47 template<std::size_t N>
48 struct add_widths<N, unknown_width::value>
49 : unknown_width
50 {};
51
52 template<>
53 struct add_widths<unknown_width::value, unknown_width::value>
54 : unknown_width
55 {};
56
57 ///////////////////////////////////////////////////////////////////////////////
58 // or_widths
59 //
60 template<std::size_t N, std::size_t M>
61 struct or_widths
62 : unknown_width
63 {};
64
65 template<std::size_t N>
66 struct or_widths<N, N>
67 : mpl::size_t<N>
68 {};
69
70 ///////////////////////////////////////////////////////////////////////////////
71 // width_of_terminal
72 //
73 template<typename Expr, typename Char, bool IsXpr = is_xpr<Expr>::value>
74 struct width_of_terminal
75 : mpl::size_t<Expr::width> // xpressive literals
76 {};
77
78 template<typename Expr, typename Char>
79 struct width_of_terminal<Expr, Char, false>
80 : unknown_width // unknown literals (eg, basic_string, basic_regex, etc.)
81 {};
82
83 template<typename Char>
84 struct width_of_terminal<Char, Char, false>
85 : mpl::size_t<1> // char literals
86 {};
87
88 template<typename Char>
89 struct width_of_terminal<char, Char, false>
90 : mpl::size_t<1> // char literals
91 {};
92
93 template<>
94 struct width_of_terminal<char, char, false>
95 : mpl::size_t<1> // char literals
96 {};
97
98 template<typename Elem, std::size_t N, typename Char>
99 struct width_of_terminal<Elem (&) [N], Char, false>
100 : mpl::size_t<N-is_char<Elem>::value> // string literals
101 {};
102
103 template<typename Elem, std::size_t N, typename Char>
104 struct width_of_terminal<Elem const (&) [N], Char, false>
105 : mpl::size_t<N-is_char<Elem>::value> // string literals
106 {};
107
108 ///////////////////////////////////////////////////////////////////////////////
109 // width_of
110 //
111 template<typename Expr, typename Char, typename Tag>
112 struct width_of
113 {};
114
115 template<typename Expr, typename Char>
116 struct width_of<Expr, Char, proto::tag::terminal>
117 : width_of_terminal<typename proto::result_of::value<Expr>::type, Char>
118 {};
119
120 template<typename Expr, typename Char>
121 struct width_of<Expr, Char, proto::tag::shift_right>
122 : add_widths<
123 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>::value
124 , width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value
125 >
126 {};
127
128 template<typename Expr, typename Char>
129 struct width_of<Expr, Char, proto::tag::bitwise_or>
130 : or_widths<
131 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>::value
132 , width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value
133 >
134 {};
135
136 template<typename Expr, typename Char, typename Left>
137 struct width_of_assign
138 {};
139
140 template<typename Expr, typename Char>
141 struct width_of_assign<Expr, Char, mark_placeholder>
142 : width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
143 {};
144
145 template<typename Expr, typename Char>
146 struct width_of_assign<Expr, Char, set_initializer>
147 : mpl::size_t<1>
148 {};
149
150 template<typename Expr, typename Char, typename Nbr>
151 struct width_of_assign<Expr, Char, attribute_placeholder<Nbr> >
152 : unknown_width
153 {};
154
155 // either (s1 = ...) or (a1 = ...) or (set = ...)
156 template<typename Expr, typename Char>
157 struct width_of<Expr, Char, proto::tag::assign>
158 : width_of_assign<
159 Expr
160 , Char
161 , typename proto::result_of::value<
162 typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr
163 >::type
164 >
165 {};
166
167 template<typename Expr, typename Char>
168 struct width_of<Expr, Char, modifier_tag>
169 : width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
170 {};
171
172 template<typename Expr, typename Char>
173 struct width_of<Expr, Char, lookahead_tag>
174 : mpl::size_t<0>
175 {};
176
177 template<typename Expr, typename Char>
178 struct width_of<Expr, Char, lookbehind_tag>
179 : mpl::size_t<0>
180 {};
181
182 // keep() is used to turn off backtracking, so they should only be used
183 // for things that are variable-width (eg. quantified)
184 template<typename Expr, typename Char>
185 struct width_of<Expr, Char, keeper_tag>
186 : unknown_width
187 {
188 // TODO: keep() now has a second meaning: execute actions immediately.
189 // In that sense, it is perfectly reasonable to put a fixed-width
190 // sub-expression in a keep. Can fixed-width keep() sub-expressions
191 // use the simple_repeat_matcher?
192 };
193
194 template<typename Expr, typename Char>
195 struct width_of<Expr, Char, proto::tag::unary_plus>
196 : unknown_width
197 {};
198
199 template<typename Expr, typename Char>
200 struct width_of<Expr, Char, proto::tag::dereference>
201 : unknown_width
202 {};
203
204 template<typename Expr, typename Char>
205 struct width_of<Expr, Char, proto::tag::logical_not>
206 : unknown_width
207 {};
208
209 template<typename Expr, typename Char, uint_t Min, uint_t Max>
210 struct width_of<Expr, Char, generic_quant_tag<Min, Max> >
211 : unknown_width
212 {};
213
214 template<typename Expr, typename Char, uint_t Count>
215 struct width_of<Expr, Char, generic_quant_tag<Count, Count> >
216 : mpl::if_c<
217 mpl::equal_to<unknown_width, width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char> >::value
218 , unknown_width
219 , mpl::times<
220 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
221 , mpl::size_t<Count>
222 >
223 >::type
224 {};
225
226 template<typename Expr, typename Char>
227 struct width_of<Expr, Char, proto::tag::negate>
228 : width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
229 {};
230
231 // when complementing a set or an assertion, the width is that of the set (1) or the assertion (0)
232 template<typename Expr, typename Char>
233 struct width_of<Expr, Char, proto::tag::complement>
234 : width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
235 {};
236
237 // The comma is used in list-initialized sets, and the width of sets are 1
238 template<typename Expr, typename Char>
239 struct width_of<Expr, Char, proto::tag::comma>
240 : mpl::size_t<1>
241 {};
242
243 // The subscript operator[] is used for sets, as in set['a' | range('b','h')],
244 // or for actions as in (any >> expr)[ action ]
245 template<typename Expr, typename Char, typename Left>
246 struct width_of_subscript
247 : width_of<Left, Char>
248 {};
249
250 template<typename Expr, typename Char>
251 struct width_of_subscript<Expr, Char, set_initializer_type>
252 : mpl::size_t<1>
253 {
254 // If Left is "set" then make sure that Right has a width_of 1
255 BOOST_MPL_ASSERT_RELATION(
256 1
257 , ==
258 , (width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value));
259 };
260
261 template<typename Expr, typename Char>
262 struct width_of<Expr, Char, proto::tag::subscript>
263 : width_of_subscript<Expr, Char, typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr>
264 {};
265
266}}} // namespace boost::xpressive::detail
267
268#undef UNREF
269
270#endif