Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2007 Joel de Guzman Chris@16: Copyright (c) 2004 Daniel Wallin Chris@16: Copyright (c) 2011 Thomas Heller Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #ifndef PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP Chris@16: #define PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #define BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM(z, n, data) \ Chris@16: typename T##n = unused Chris@16: Chris@16: #define BOOST_PHOENIX_MAP_LOCAL_DISPATCH(z, n, data) \ Chris@16: typedef char(&result##n)[n+2]; \ Chris@16: static result##n get(T##n*); Chris@16: Chris@16: namespace boost { namespace phoenix Chris@16: { Chris@16: template Chris@16: struct scoped_environment; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct local Chris@16: { Chris@16: typedef Key key_type; Chris@16: }; Chris@16: Chris@16: namespace result_of Chris@16: { Chris@16: template Chris@16: struct initialize_locals; Chris@16: Chris@16: template Chris@16: struct initialize_locals, Context> Chris@16: { Chris@16: typedef vector0<> type; Chris@16: }; Chris@16: Chris@16: #define M1(Z, N, D) \ Chris@16: typename boost::phoenix::result_of::eval< \ Chris@16: BOOST_PP_CAT(A, N) \ Chris@16: , Context \ Chris@16: >::type \ Chris@16: /**/ Chris@16: Chris@16: #define M0(Z, N, D) \ Chris@16: template \ Chris@16: struct initialize_locals< \ Chris@16: BOOST_PP_CAT(vector, N)< \ Chris@16: BOOST_PHOENIX_A(N) \ Chris@16: > \ Chris@16: , Context \ Chris@16: > \ Chris@16: { \ Chris@16: typedef \ Chris@16: BOOST_PP_CAT(vector, N)< \ Chris@16: BOOST_PP_ENUM(N, M1, _) \ Chris@16: > \ Chris@16: type; \ Chris@16: }; \ Chris@16: /**/ Chris@16: BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _) Chris@16: #undef M0 Chris@16: } Chris@16: Chris@16: template Chris@16: vector0<> Chris@16: initialize_locals(vector0<> const &, Context const &) Chris@16: { Chris@16: vector0<> vars; Chris@16: return vars; Chris@16: } Chris@16: #define M2(Z, N, D) \ Chris@16: eval(locals. BOOST_PP_CAT(a, N), ctx) \ Chris@16: /**/ Chris@16: Chris@16: #define M0(Z, N, D) \ Chris@16: template \ Chris@16: BOOST_PP_CAT(vector, N) \ Chris@16: initialize_locals( \ Chris@16: BOOST_PP_CAT(vector, N) const & locals \ Chris@16: , Context const & ctx \ Chris@16: ) \ Chris@16: { \ Chris@16: BOOST_PP_CAT(vector, N) vars \ Chris@16: = {BOOST_PP_ENUM(N, M2, _)}; \ Chris@16: return vars; \ Chris@16: } \ Chris@16: /**/ Chris@16: BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _) Chris@16: #undef M0 Chris@16: #undef M1 Chris@16: #undef M2 Chris@16: Chris@16: template Chris@16: struct unused; Chris@16: Chris@16: template < Chris@16: BOOST_PP_ENUM( Chris@16: BOOST_PHOENIX_LOCAL_LIMIT Chris@16: , BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM Chris@16: , _ Chris@16: ) Chris@16: > Chris@16: struct map_local_index_to_tuple Chris@16: { Chris@16: typedef char(¬_found)[1]; Chris@16: static not_found get(...); Chris@16: Chris@16: BOOST_PP_REPEAT(BOOST_PHOENIX_LOCAL_LIMIT, BOOST_PHOENIX_MAP_LOCAL_DISPATCH, _) Chris@16: }; Chris@16: Chris@16: template Chris@16: T* generate_pointer(); Chris@16: Chris@16: template Chris@16: struct get_index Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(int, Chris@16: value = ( Chris@16: static_cast((sizeof(Map::get(generate_pointer()))) / sizeof(char)) - 2 Chris@16: )); Chris@16: Chris@16: // if value == -1, Tag is not found Chris@16: typedef mpl::int_ type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct apply_local; Chris@16: Chris@16: template Chris@16: struct outer_local Chris@16: { Chris@16: typedef typename Chris@16: apply_local::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct get_local_or_void Chris@16: { Chris@16: typedef typename Chris@16: mpl::eval_if_c< Chris@16: Index < Locals::size_value Chris@16: , fusion::result_of::at_c Chris@16: , mpl::identity Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct get_local_from_index Chris@16: { Chris@16: typedef typename Chris@16: mpl::eval_if_c< Chris@16: Index == -1 Chris@16: , outer_local Chris@16: , get_local_or_void Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct get_local Chris@16: { Chris@16: static const int index_value = get_index::value; Chris@16: Chris@16: typedef typename Chris@16: get_local_from_index::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct apply_local Chris@16: { Chris@16: // $$$ TODO: static assert that Env is a scoped_environment $$$ Chris@16: typedef typename get_local::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct eval_local Chris@16: { Chris@16: template Chris@16: static RT Chris@16: get(Env const& env, mpl::false_) Chris@16: { Chris@16: return RT(fusion::at_c(env.locals)); Chris@16: } Chris@16: Chris@16: template Chris@16: static RT Chris@16: get(Env const& env, mpl::true_) Chris@16: { Chris@16: static const int index_value = get_index >::value; Chris@16: Chris@16: return get( Chris@16: env.outer_env Chris@16: , mpl::bool_()); Chris@16: } Chris@16: Chris@16: template Chris@16: static RT Chris@16: get(Env const& env) Chris@16: { Chris@16: return get( Chris@16: env Chris@16: , mpl::bool_()); Chris@16: } Chris@16: }; Chris@16: } Chris@16: }} Chris@16: Chris@16: #undef BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM Chris@16: #undef BOOST_PHOENIX_MAP_LOCAL_DISPATCH Chris@16: Chris@16: #endif