annotate DEPENDENCIES/generic/include/boost/spirit/home/support/action_dispatch.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 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 4 http://spirit.sourceforge.net/
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM)
Chris@16 10 #define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
Chris@16 11
Chris@16 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include<boost/config.hpp>
Chris@16 17
Chris@16 18 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
Chris@16 19 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
Chris@16 20 #include <utility>
Chris@16 21 #include <type_traits>
Chris@16 22 #endif
Chris@16 23
Chris@16 24
Chris@16 25 #include <boost/spirit/include/phoenix_core.hpp>
Chris@16 26 #include <boost/spirit/home/support/attributes.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace spirit { namespace traits
Chris@16 29 {
Chris@16 30 template <typename Component>
Chris@16 31 struct action_dispatch
Chris@16 32 {
Chris@16 33 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
Chris@16 34 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
Chris@16 35 // omit function parameters without specializing for each possible
Chris@16 36 // type of callable entity
Chris@16 37 // many thanks to Eelis/##iso-c++ for this contribution
Chris@16 38
Chris@16 39 private:
Chris@16 40 // this will be used to pass around POD types which are safe
Chris@16 41 // to go through the ellipsis operator (if ever used)
Chris@16 42 template <typename>
Chris@16 43 struct fwd_tag {};
Chris@16 44
Chris@16 45 // the first parameter is a placeholder to obtain SFINAE when
Chris@16 46 // doing overload resolution, the second one is the actual
Chris@16 47 // forwarder, where we can apply our implementation
Chris@16 48 template <typename, typename T>
Chris@16 49 struct fwd_storage { typedef T type; };
Chris@16 50
Chris@16 51 // gcc should accept fake<T>() but it prints a sorry, needs
Chris@16 52 // a check once the bug is sorted out, use a FAKE_CALL macro for now
Chris@16 53 template <typename T>
Chris@16 54 T fake_call();
Chris@16 55
Chris@16 56 #define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0)
Chris@16 57
Chris@16 58 // the forwarders, here we could tweak the implementation of
Chris@16 59 // how parameters are passed to the functions, if needed
Chris@16 60 struct fwd_none
Chris@16 61 {
Chris@16 62 template<typename F, typename... Rest>
Chris@16 63 auto operator()(F && f, Rest&&...) -> decltype(f())
Chris@16 64 {
Chris@16 65 return f();
Chris@16 66 }
Chris@16 67 };
Chris@16 68
Chris@16 69 struct fwd_attrib
Chris@16 70 {
Chris@16 71 template<typename F, typename A, typename... Rest>
Chris@16 72 auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a))
Chris@16 73 {
Chris@16 74 return f(a);
Chris@16 75 }
Chris@16 76 };
Chris@16 77
Chris@16 78 struct fwd_attrib_context
Chris@16 79 {
Chris@16 80 template<typename F, typename A, typename B, typename... Rest>
Chris@16 81 auto operator()(F && f, A && a, B && b, Rest&&...)
Chris@16 82 -> decltype(f(a, b))
Chris@16 83 {
Chris@16 84 return f(a, b);
Chris@16 85 }
Chris@16 86 };
Chris@16 87
Chris@16 88 struct fwd_attrib_context_pass
Chris@16 89 {
Chris@16 90 template<typename F, typename A, typename B, typename C
Chris@16 91 , typename... Rest>
Chris@16 92 auto operator()(F && f, A && a, B && b, C && c, Rest&&...)
Chris@16 93 -> decltype(f(a, b, c))
Chris@16 94 {
Chris@16 95 return f(a, b, c);
Chris@16 96 }
Chris@16 97 };
Chris@16 98
Chris@16 99 // SFINAE for our calling syntax, the forwarders are stored based
Chris@16 100 // on what function call gives a proper result
Chris@16 101 // this code can probably be more generic once implementations are
Chris@16 102 // steady
Chris@16 103 template <typename F>
Chris@16 104 static auto do_call(F && f, ...)
Chris@16 105 -> typename fwd_storage<decltype(f()), fwd_none>::type
Chris@16 106 {
Chris@16 107 return {};
Chris@16 108 }
Chris@16 109
Chris@16 110 template <typename F, typename A>
Chris@16 111 static auto do_call(F && f, fwd_tag<A>, ...)
Chris@16 112 -> typename fwd_storage<decltype(f(BOOST_SPIRIT_FAKE_CALL(A)))
Chris@16 113 , fwd_attrib>::type
Chris@16 114 {
Chris@16 115 return {};
Chris@16 116 }
Chris@16 117
Chris@16 118 template <typename F, typename A, typename B>
Chris@16 119 static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, ...)
Chris@16 120 -> typename fwd_storage<
Chris@16 121 decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)))
Chris@16 122 , fwd_attrib_context>::type
Chris@16 123 {
Chris@16 124 return {};
Chris@16 125 }
Chris@16 126
Chris@16 127 template <typename F, typename A, typename B, typename C>
Chris@16 128 static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, fwd_tag<C>, ...)
Chris@16 129 -> typename fwd_storage<
Chris@16 130 decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)
Chris@16 131 , BOOST_SPIRIT_FAKE_CALL(C)))
Chris@16 132 , fwd_attrib_context_pass>::type
Chris@16 133 {
Chris@16 134 return {};
Chris@16 135 }
Chris@16 136
Chris@16 137 // this function calls the forwarder and is responsible for
Chris@16 138 // stripping the tail of the parameters
Chris@16 139 template <typename F, typename... A>
Chris@16 140 static void caller(F && f, A && ... a)
Chris@16 141 {
Chris@16 142 do_call(f, fwd_tag<typename std::remove_reference<A>::type>()...)
Chris@16 143 (std::forward<F>(f), std::forward<A>(a)...);
Chris@16 144 }
Chris@16 145
Chris@16 146 #undef BOOST_SPIRIT_FAKE_CALL
Chris@16 147
Chris@16 148 public:
Chris@16 149 template <typename F, typename Attribute, typename Context>
Chris@16 150 bool operator()(F const& f, Attribute& attr, Context& context)
Chris@16 151 {
Chris@16 152 bool pass = true;
Chris@16 153 caller(f, attr, context, pass);
Chris@16 154 return pass;
Chris@16 155 }
Chris@16 156 #else
Chris@16 157 // general handler for everything not explicitly specialized below
Chris@16 158 template <typename F, typename Attribute, typename Context>
Chris@16 159 bool operator()(F const& f, Attribute& attr, Context& context)
Chris@16 160 {
Chris@16 161 bool pass = true;
Chris@16 162 f(attr, context, pass);
Chris@16 163 return pass;
Chris@16 164 }
Chris@16 165 #endif
Chris@16 166
Chris@16 167 // handler for phoenix actors
Chris@16 168
Chris@16 169 // If the component this action has to be invoked for is a tuple, we
Chris@16 170 // wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
Chris@16 171 // and pass through any fusion tuple.
Chris@16 172 template <typename Eval, typename Attribute, typename Context>
Chris@16 173 bool operator()(phoenix::actor<Eval> const& f
Chris@16 174 , Attribute& attr, Context& context)
Chris@16 175 {
Chris@16 176 bool pass = true;
Chris@16 177 typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
Chris@16 178 f(attr_wrap, context, pass);
Chris@16 179 return pass;
Chris@16 180 }
Chris@16 181
Chris@16 182 // specializations for plain function pointers taking different number of
Chris@16 183 // arguments
Chris@16 184 template <typename RT, typename A0, typename A1, typename A2
Chris@16 185 , typename Attribute, typename Context>
Chris@16 186 bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
Chris@16 187 {
Chris@16 188 bool pass = true;
Chris@16 189 f(attr, context, pass);
Chris@16 190 return pass;
Chris@16 191 }
Chris@16 192
Chris@16 193 template <typename RT, typename A0, typename A1
Chris@16 194 , typename Attribute, typename Context>
Chris@16 195 bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
Chris@16 196 {
Chris@16 197 f(attr, context);
Chris@16 198 return true;
Chris@16 199 }
Chris@16 200
Chris@16 201 template <typename RT, typename A0, typename Attribute, typename Context>
Chris@16 202 bool operator()(RT(*f)(A0), Attribute& attr, Context&)
Chris@16 203 {
Chris@16 204 f(attr);
Chris@16 205 return true;
Chris@16 206 }
Chris@16 207
Chris@16 208 template <typename RT, typename Attribute, typename Context>
Chris@16 209 bool operator()(RT(*f)(), Attribute&, Context&)
Chris@16 210 {
Chris@16 211 f();
Chris@16 212 return true;
Chris@16 213 }
Chris@16 214 };
Chris@16 215 }}}
Chris@16 216
Chris@16 217 #endif