File indexing completed on 2025-01-18 09:53:51
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/ref.hpp>
0017 #include <boost/mpl/if.hpp>
0018 #include <boost/mpl/or.hpp>
0019 #include <boost/mpl/plus.hpp>
0020 #include <boost/mpl/times.hpp>
0021 #include <boost/mpl/assert.hpp>
0022 #include <boost/mpl/size_t.hpp>
0023 #include <boost/mpl/equal_to.hpp>
0024 #include <boost/type_traits/is_same.hpp>
0025 #include <boost/xpressive/detail/detail_fwd.hpp>
0026 #include <boost/xpressive/detail/static/type_traits.hpp>
0027 #include <boost/proto/traits.hpp>
0028
0029 namespace boost { namespace xpressive { namespace detail
0030 {
0031 template<typename Expr, typename Char, typename Tag = typename Expr::proto_tag>
0032 struct width_of;
0033
0034
0035
0036
0037 template<std::size_t N, std::size_t M>
0038 struct add_widths
0039 : mpl::size_t<N + M>
0040 {};
0041
0042 template<std::size_t M>
0043 struct add_widths<unknown_width::value, M>
0044 : unknown_width
0045 {};
0046
0047 template<std::size_t N>
0048 struct add_widths<N, unknown_width::value>
0049 : unknown_width
0050 {};
0051
0052 template<>
0053 struct add_widths<unknown_width::value, unknown_width::value>
0054 : unknown_width
0055 {};
0056
0057
0058
0059
0060 template<std::size_t N, std::size_t M>
0061 struct or_widths
0062 : unknown_width
0063 {};
0064
0065 template<std::size_t N>
0066 struct or_widths<N, N>
0067 : mpl::size_t<N>
0068 {};
0069
0070
0071
0072
0073 template<typename Expr, typename Char, bool IsXpr = is_xpr<Expr>::value>
0074 struct width_of_terminal
0075 : mpl::size_t<Expr::width>
0076 {};
0077
0078 template<typename Expr, typename Char>
0079 struct width_of_terminal<Expr, Char, false>
0080 : unknown_width
0081 {};
0082
0083 template<typename Char>
0084 struct width_of_terminal<Char, Char, false>
0085 : mpl::size_t<1>
0086 {};
0087
0088 template<typename Char>
0089 struct width_of_terminal<char, Char, false>
0090 : mpl::size_t<1>
0091 {};
0092
0093 template<>
0094 struct width_of_terminal<char, char, false>
0095 : mpl::size_t<1>
0096 {};
0097
0098 template<typename Elem, std::size_t N, typename Char>
0099 struct width_of_terminal<Elem (&) [N], Char, false>
0100 : mpl::size_t<N-is_char<Elem>::value>
0101 {};
0102
0103 template<typename Elem, std::size_t N, typename Char>
0104 struct width_of_terminal<Elem const (&) [N], Char, false>
0105 : mpl::size_t<N-is_char<Elem>::value>
0106 {};
0107
0108
0109
0110
0111 template<typename Expr, typename Char, typename Tag>
0112 struct width_of
0113 {};
0114
0115 template<typename Expr, typename Char>
0116 struct width_of<Expr, Char, proto::tag::terminal>
0117 : width_of_terminal<typename proto::result_of::value<Expr>::type, Char>
0118 {};
0119
0120 template<typename Expr, typename Char>
0121 struct width_of<Expr, Char, proto::tag::shift_right>
0122 : add_widths<
0123 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>::value
0124 , width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value
0125 >
0126 {};
0127
0128 template<typename Expr, typename Char>
0129 struct width_of<Expr, Char, proto::tag::bitwise_or>
0130 : or_widths<
0131 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>::value
0132 , width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value
0133 >
0134 {};
0135
0136 template<typename Expr, typename Char, typename Left>
0137 struct width_of_assign
0138 {};
0139
0140 template<typename Expr, typename Char>
0141 struct width_of_assign<Expr, Char, mark_placeholder>
0142 : width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
0143 {};
0144
0145 template<typename Expr, typename Char>
0146 struct width_of_assign<Expr, Char, set_initializer>
0147 : mpl::size_t<1>
0148 {};
0149
0150 template<typename Expr, typename Char, typename Nbr>
0151 struct width_of_assign<Expr, Char, attribute_placeholder<Nbr> >
0152 : unknown_width
0153 {};
0154
0155
0156 template<typename Expr, typename Char>
0157 struct width_of<Expr, Char, proto::tag::assign>
0158 : width_of_assign<
0159 Expr
0160 , Char
0161 , typename proto::result_of::value<
0162 typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr
0163 >::type
0164 >
0165 {};
0166
0167 template<typename Expr, typename Char>
0168 struct width_of<Expr, Char, modifier_tag>
0169 : width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>
0170 {};
0171
0172 template<typename Expr, typename Char>
0173 struct width_of<Expr, Char, lookahead_tag>
0174 : mpl::size_t<0>
0175 {};
0176
0177 template<typename Expr, typename Char>
0178 struct width_of<Expr, Char, lookbehind_tag>
0179 : mpl::size_t<0>
0180 {};
0181
0182
0183
0184 template<typename Expr, typename Char>
0185 struct width_of<Expr, Char, keeper_tag>
0186 : unknown_width
0187 {
0188
0189
0190
0191
0192 };
0193
0194 template<typename Expr, typename Char>
0195 struct width_of<Expr, Char, proto::tag::unary_plus>
0196 : unknown_width
0197 {};
0198
0199 template<typename Expr, typename Char>
0200 struct width_of<Expr, Char, proto::tag::dereference>
0201 : unknown_width
0202 {};
0203
0204 template<typename Expr, typename Char>
0205 struct width_of<Expr, Char, proto::tag::logical_not>
0206 : unknown_width
0207 {};
0208
0209 template<typename Expr, typename Char, uint_t Min, uint_t Max>
0210 struct width_of<Expr, Char, generic_quant_tag<Min, Max> >
0211 : unknown_width
0212 {};
0213
0214 template<typename Expr, typename Char, uint_t Count>
0215 struct width_of<Expr, Char, generic_quant_tag<Count, Count> >
0216 : mpl::if_c<
0217 mpl::equal_to<unknown_width, width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char> >::value
0218 , unknown_width
0219 , mpl::times<
0220 width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
0221 , mpl::size_t<Count>
0222 >
0223 >::type
0224 {};
0225
0226 template<typename Expr, typename Char>
0227 struct width_of<Expr, Char, proto::tag::negate>
0228 : width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
0229 {};
0230
0231
0232 template<typename Expr, typename Char>
0233 struct width_of<Expr, Char, proto::tag::complement>
0234 : width_of<typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr, Char>
0235 {};
0236
0237
0238 template<typename Expr, typename Char>
0239 struct width_of<Expr, Char, proto::tag::comma>
0240 : mpl::size_t<1>
0241 {};
0242
0243
0244
0245 template<typename Expr, typename Char, typename Left>
0246 struct width_of_subscript
0247 : width_of<Left, Char>
0248 {};
0249
0250 template<typename Expr, typename Char>
0251 struct width_of_subscript<Expr, Char, set_initializer_type>
0252 : mpl::size_t<1>
0253 {
0254
0255 BOOST_MPL_ASSERT_RELATION(
0256 1
0257 , ==
0258 , (width_of<typename remove_reference<typename Expr::proto_child1>::type::proto_base_expr, Char>::value));
0259 };
0260
0261 template<typename Expr, typename Char>
0262 struct width_of<Expr, Char, proto::tag::subscript>
0263 : width_of_subscript<Expr, Char, typename remove_reference<typename Expr::proto_child0>::type::proto_base_expr>
0264 {};
0265
0266 }}}
0267
0268 #undef UNREF
0269
0270 #endif