annotate DEPENDENCIES/generic/include/boost/spirit/home/support/meta_compiler.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Joel de Guzman
Chris@16 3 http://spirit.sourceforge.net/
Chris@16 4
Chris@16 5 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 =============================================================================*/
Chris@16 8 #ifndef BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_1258PM
Chris@16 9 #define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_1258PM
Chris@16 10
Chris@16 11 #if defined(_MSC_VER)
Chris@16 12 #pragma once
Chris@16 13 #endif
Chris@16 14
Chris@16 15 #include <boost/config.hpp>
Chris@16 16 #include <boost/spirit/include/phoenix_limits.hpp>
Chris@16 17 #include <boost/detail/workaround.hpp>
Chris@16 18 #include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
Chris@16 19 #include <boost/proto/proto.hpp>
Chris@16 20 #include <boost/spirit/home/support/make_component.hpp>
Chris@16 21 #include <boost/spirit/home/support/modify.hpp>
Chris@16 22 #include <boost/spirit/home/support/detail/make_cons.hpp>
Chris@16 23 #include <boost/spirit/home/support/unused.hpp>
Chris@16 24 #include <boost/spirit/home/support/assert_msg.hpp>
Chris@16 25 #include <boost/utility/enable_if.hpp>
Chris@16 26 #include <boost/type_traits/remove_reference.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace spirit
Chris@16 29 {
Chris@16 30 // Some defaults...
Chris@16 31
Chris@16 32 template <typename Domain, typename Tag, typename Enable = void>
Chris@16 33 struct use_operator : mpl::false_ {};
Chris@16 34
Chris@16 35 template <typename Domain, typename T, typename Enable = void>
Chris@16 36 struct use_function : mpl::false_ {};
Chris@16 37
Chris@16 38 template <typename Domain, typename T, typename Enable = void>
Chris@16 39 struct use_directive : mpl::false_ {};
Chris@16 40
Chris@16 41 template <typename Domain, typename T, typename Enable /* = void */>
Chris@16 42 struct is_modifier_directive : mpl::false_ {};
Chris@16 43
Chris@16 44 template <typename Domain, typename T, typename Enable = void>
Chris@16 45 struct use_terminal : mpl::false_ {};
Chris@16 46
Chris@16 47 template <typename Domain, typename T, typename Enable /*= void*/>
Chris@16 48 struct flatten_tree : mpl::false_ {};
Chris@16 49
Chris@16 50 // Our meta-compiler. This is the main engine that hooks Spirit
Chris@16 51 // to the proto expression template engine.
Chris@16 52
Chris@16 53 template <typename Domain>
Chris@16 54 struct meta_compiler
Chris@16 55 {
Chris@16 56 struct meta_grammar;
Chris@16 57
Chris@16 58 BOOST_SPIRIT_ASSERT_MSG((
Chris@16 59 !use_operator<Domain, proto::tag::subscript>::value
Chris@16 60 ), error_proto_tag_subscript_cannot_be_used, ());
Chris@16 61
Chris@16 62 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
Chris@16 63 // this is the non-broken part for compilers properly supporting
Chris@16 64 // partial template specialization (VC7.1 does not)
Chris@16 65 struct cases
Chris@16 66 {
Chris@16 67 template <typename Tag, typename Enable = void>
Chris@16 68 struct case_
Chris@16 69 : proto::not_<proto::_>
Chris@16 70 {};
Chris@16 71
Chris@16 72 ///////////////////////////////////////////////////////////////////
Chris@16 73 // terminals
Chris@16 74 ///////////////////////////////////////////////////////////////////
Chris@16 75 template <typename Enable>
Chris@16 76 struct case_<proto::tag::terminal, Enable>
Chris@16 77 : proto::when<
Chris@16 78 proto::if_<use_terminal<Domain, proto::_value>()>,
Chris@16 79 detail::make_terminal<Domain>
Chris@16 80 >
Chris@16 81 {};
Chris@16 82
Chris@16 83 template <typename Tag>
Chris@16 84 struct case_<Tag, typename enable_if<use_operator<Domain, Tag> >::type>
Chris@16 85 : proto::or_<
Chris@16 86 ///////////////////////////////////////////////////////////////////
Chris@16 87 // binary operators
Chris@16 88 ///////////////////////////////////////////////////////////////////
Chris@16 89 proto::when<proto::binary_expr<Tag, meta_grammar, meta_grammar>,
Chris@16 90 detail::make_binary<Domain, Tag, meta_grammar>
Chris@16 91 >,
Chris@16 92 ///////////////////////////////////////////////////////////////////
Chris@16 93 // unary operators
Chris@16 94 ///////////////////////////////////////////////////////////////////
Chris@16 95 proto::when<proto::unary_expr<Tag, meta_grammar>,
Chris@16 96 detail::make_unary<Domain, Tag, meta_grammar>
Chris@16 97 >
Chris@16 98 >
Chris@16 99 {};
Chris@16 100
Chris@16 101 template <typename Enable>
Chris@16 102 struct case_<proto::tag::subscript, Enable>
Chris@16 103 : proto::or_<
Chris@16 104 ///////////////////////////////////////////////////////////////////
Chris@16 105 // directives
Chris@16 106 ///////////////////////////////////////////////////////////////////
Chris@16 107 proto::when<proto::binary_expr<proto::tag::subscript
Chris@16 108 , proto::and_<
Chris@16 109 proto::terminal<proto::_>
Chris@16 110 , proto::if_<use_directive<Domain, proto::_value >()> >
Chris@16 111 , meta_grammar>,
Chris@16 112 detail::make_directive<Domain, meta_grammar>
Chris@16 113 >,
Chris@16 114 ///////////////////////////////////////////////////////////////////
Chris@16 115 // semantic actions
Chris@16 116 ///////////////////////////////////////////////////////////////////
Chris@16 117 proto::when<proto::binary_expr<proto::tag::subscript
Chris@16 118 , meta_grammar, proto::_>,
Chris@16 119 detail::make_action<Domain, meta_grammar>
Chris@16 120 >
Chris@16 121 >
Chris@16 122 {};
Chris@16 123 };
Chris@16 124 #else
Chris@16 125 // this part actually constitutes invalid C++ code, but it allows us to
Chris@16 126 // convince VC7.1 to do what we want
Chris@16 127 struct cases
Chris@16 128 {
Chris@16 129 template <typename Tag, typename Enable = void>
Chris@16 130 struct case_
Chris@16 131 : proto::not_<proto::_>
Chris@16 132 {};
Chris@16 133
Chris@16 134 ///////////////////////////////////////////////////////////////////
Chris@16 135 // terminals
Chris@16 136 ///////////////////////////////////////////////////////////////////
Chris@16 137 template <>
Chris@16 138 struct case_<proto::tag::terminal>
Chris@16 139 : proto::when<
Chris@16 140 proto::if_<use_terminal<Domain, proto::_value>()>,
Chris@16 141 detail::make_terminal<Domain>
Chris@16 142 >
Chris@16 143 {};
Chris@16 144
Chris@16 145 template <typename Tag>
Chris@16 146 struct case_<Tag>
Chris@16 147 : proto::or_<
Chris@16 148 ///////////////////////////////////////////////////////////////////
Chris@16 149 // binary operators
Chris@16 150 ///////////////////////////////////////////////////////////////////
Chris@16 151 proto::when<proto::binary_expr<
Chris@16 152 typename enable_if<use_operator<Domain, Tag>, Tag>::type
Chris@16 153 , meta_grammar, meta_grammar>
Chris@16 154 , detail::make_binary<Domain, Tag, meta_grammar>
Chris@16 155 >,
Chris@16 156 ///////////////////////////////////////////////////////////////////
Chris@16 157 // unary operators
Chris@16 158 ///////////////////////////////////////////////////////////////////
Chris@16 159 proto::when<proto::unary_expr<
Chris@16 160 typename enable_if<use_operator<Domain, Tag>, Tag>::type
Chris@16 161 , meta_grammar>
Chris@16 162 , detail::make_unary<Domain, Tag, meta_grammar>
Chris@16 163 >
Chris@16 164 >
Chris@16 165 {};
Chris@16 166
Chris@16 167 template <>
Chris@16 168 struct case_<proto::tag::subscript>
Chris@16 169 : proto::or_<
Chris@16 170 ///////////////////////////////////////////////////////////////////
Chris@16 171 // directives
Chris@16 172 ///////////////////////////////////////////////////////////////////
Chris@16 173 proto::when<proto::binary_expr<proto::tag::subscript
Chris@16 174 , proto::and_<
Chris@16 175 proto::terminal<proto::_>
Chris@16 176 , proto::if_<use_directive<Domain, proto::_value >()> >
Chris@16 177 , meta_grammar>,
Chris@16 178 detail::make_directive<Domain, meta_grammar>
Chris@16 179 >,
Chris@16 180 ///////////////////////////////////////////////////////////////////
Chris@16 181 // semantic actions
Chris@16 182 ///////////////////////////////////////////////////////////////////
Chris@16 183 proto::when<proto::binary_expr<proto::tag::subscript
Chris@16 184 , meta_grammar, proto::_>,
Chris@16 185 detail::make_action<Domain, meta_grammar>
Chris@16 186 >
Chris@16 187 >
Chris@16 188 {};
Chris@16 189 };
Chris@16 190 #endif
Chris@16 191
Chris@16 192 struct meta_grammar
Chris@16 193 : proto::switch_<cases>
Chris@16 194 {};
Chris@16 195 };
Chris@16 196
Chris@16 197 namespace result_of
Chris@16 198 {
Chris@16 199 // Default case
Chris@16 200 template <typename Domain, typename Expr
Chris@16 201 , typename Modifiers = unused_type, typename Enable = void>
Chris@16 202 struct compile
Chris@16 203 {
Chris@16 204 typedef typename meta_compiler<Domain>::meta_grammar meta_grammar;
Chris@16 205 typedef typename meta_grammar::
Chris@16 206 template result<meta_grammar(Expr, mpl::void_, Modifiers)>::type
Chris@16 207 type;
Chris@16 208 };
Chris@16 209
Chris@16 210 // If Expr is not a proto expression, make it a terminal
Chris@16 211 template <typename Domain, typename Expr, typename Modifiers>
Chris@16 212 struct compile<Domain, Expr, Modifiers,
Chris@16 213 typename disable_if<proto::is_expr<Expr> >::type>
Chris@16 214 : compile<Domain, typename proto::terminal<Expr>::type, Modifiers> {};
Chris@16 215 }
Chris@16 216
Chris@16 217 namespace traits
Chris@16 218 {
Chris@16 219 // Check if Expr matches the domain's grammar
Chris@16 220 template <typename Domain, typename Expr>
Chris@16 221 struct matches :
Chris@16 222 proto::matches<
Chris@16 223 typename proto::result_of::as_expr<
Chris@16 224 typename remove_reference<Expr>::type>::type,
Chris@16 225 typename meta_compiler<Domain>::meta_grammar
Chris@16 226 >
Chris@16 227 {
Chris@16 228 };
Chris@16 229 }
Chris@16 230
Chris@16 231 namespace detail
Chris@16 232 {
Chris@16 233 template <typename Domain>
Chris@16 234 struct compiler
Chris@16 235 {
Chris@16 236 // Default case
Chris@16 237 template <typename Expr, typename Modifiers>
Chris@16 238 static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type
Chris@16 239 compile(Expr const& expr, Modifiers modifiers, mpl::true_)
Chris@16 240 {
Chris@16 241 typename meta_compiler<Domain>::meta_grammar compiler;
Chris@16 242 return compiler(expr, mpl::void_(), modifiers);
Chris@16 243 }
Chris@16 244
Chris@16 245 // If Expr is not a proto expression, make it a terminal
Chris@16 246 template <typename Expr, typename Modifiers>
Chris@16 247 static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type
Chris@16 248 compile(Expr const& expr, Modifiers modifiers, mpl::false_)
Chris@16 249 {
Chris@16 250 typename meta_compiler<Domain>::meta_grammar compiler;
Chris@16 251 typedef typename detail::as_meta_element<Expr>::type expr_;
Chris@16 252 typename proto::terminal<expr_>::type term = {expr};
Chris@16 253 return compiler(term, mpl::void_(), modifiers);
Chris@16 254 }
Chris@16 255 };
Chris@16 256 }
Chris@16 257
Chris@16 258 template <typename Domain, typename Expr>
Chris@16 259 inline typename result_of::compile<Domain, Expr, unused_type>::type
Chris@16 260 compile(Expr const& expr)
Chris@16 261 {
Chris@16 262 typedef typename proto::is_expr<Expr>::type is_expr;
Chris@16 263 return detail::compiler<Domain>::compile(expr, unused, is_expr());
Chris@16 264 }
Chris@16 265
Chris@16 266 template <typename Domain, typename Expr, typename Modifiers>
Chris@16 267 inline typename result_of::compile<Domain, Expr, Modifiers>::type
Chris@16 268 compile(Expr const& expr, Modifiers modifiers)
Chris@16 269 {
Chris@16 270 typedef typename proto::is_expr<Expr>::type is_expr;
Chris@16 271 return detail::compiler<Domain>::compile(expr, modifiers, is_expr());
Chris@16 272 }
Chris@16 273
Chris@16 274 ///////////////////////////////////////////////////////////////////////////
Chris@16 275 template <typename Elements, template <typename Subject> class generator>
Chris@16 276 struct make_unary_composite
Chris@16 277 {
Chris@16 278 typedef typename
Chris@16 279 fusion::result_of::value_at_c<Elements, 0>::type
Chris@16 280 element_type;
Chris@16 281 typedef generator<element_type> result_type;
Chris@16 282 result_type operator()(Elements const& elements, unused_type) const
Chris@16 283 {
Chris@16 284 return result_type(fusion::at_c<0>(elements));
Chris@16 285 }
Chris@16 286 };
Chris@16 287
Chris@16 288 template <typename Elements, template <typename Left, typename Right> class generator>
Chris@16 289 struct make_binary_composite
Chris@16 290 {
Chris@16 291 typedef typename
Chris@16 292 fusion::result_of::value_at_c<Elements, 0>::type
Chris@16 293 left_type;
Chris@16 294 typedef typename
Chris@16 295 fusion::result_of::value_at_c<Elements, 1>::type
Chris@16 296 right_type;
Chris@16 297 typedef generator<left_type, right_type> result_type;
Chris@16 298
Chris@16 299 result_type operator()(Elements const& elements, unused_type) const
Chris@16 300 {
Chris@16 301 return result_type(
Chris@16 302 fusion::at_c<0>(elements)
Chris@16 303 , fusion::at_c<1>(elements)
Chris@16 304 );
Chris@16 305 }
Chris@16 306 };
Chris@16 307
Chris@16 308 template <typename Elements, template <typename Elements_> class generator>
Chris@16 309 struct make_nary_composite
Chris@16 310 {
Chris@16 311 typedef generator<Elements> result_type;
Chris@16 312 result_type operator()(Elements const& elements, unused_type) const
Chris@16 313 {
Chris@16 314 return result_type(elements);
Chris@16 315 }
Chris@16 316 };
Chris@16 317
Chris@16 318 }}
Chris@16 319
Chris@16 320 #endif