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