123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*=============================================================================
- 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 <boost/mpl/int.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/fusion/include/at.hpp>
- #include <boost/fusion/include/value_at.hpp>
- #include <boost/preprocessor/enum.hpp>
- #include <boost/preprocessor/repeat.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #include <boost/type_traits/is_reference.hpp>
- #define BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM(z, n, data) \
- typename T##n = unused<n>
- #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 <typename Env, typename OuterEnv, typename Locals, typename Map>
- struct scoped_environment;
- namespace detail
- {
- template <typename Key>
- struct local
- {
- typedef Key key_type;
- };
- namespace result_of
- {
- template <typename Locals, typename Context>
- struct initialize_locals;
-
- template <typename Context>
- struct initialize_locals<vector0<>, 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 <BOOST_PHOENIX_typename_A(N), typename Context> \
- 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 <typename Context>
- 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_PHOENIX_typename_A(N), typename Context> \
- BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)> \
- initialize_locals( \
- BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> const & locals \
- , Context const & ctx \
- ) \
- { \
- BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)> 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 <int N>
- 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<typename T>
- T* generate_pointer();
- template <typename Map, typename Tag>
- struct get_index
- {
- BOOST_STATIC_CONSTANT(int,
- value = (
- static_cast<int>((sizeof(Map::get(generate_pointer<Tag>()))) / sizeof(char)) - 2
- ));
- // if value == -1, Tag is not found
- typedef mpl::int_<value> type;
- };
-
- template <typename Local, typename Env>
- struct apply_local;
- template <typename Local, typename Env>
- struct outer_local
- {
- typedef typename
- apply_local<Local, typename Env::outer_env_type>::type
- type;
- };
- template <typename Locals, int Index>
- struct get_local_or_void
- {
- typedef typename
- mpl::eval_if_c<
- Index < Locals::size_value
- , fusion::result_of::at_c<Locals, Index>
- , mpl::identity<fusion::void_>
- >::type
- type;
- };
- template <typename Local, typename Env, int Index>
- struct get_local_from_index
- {
- typedef typename
- mpl::eval_if_c<
- Index == -1
- , outer_local<Local, Env>
- , get_local_or_void<typename Env::locals_type, Index>
- >::type
- type;
- };
- template <typename Local, typename Env>
- struct get_local
- {
- static const int index_value = get_index<typename Env::map_type, Local>::value;
- typedef typename
- get_local_from_index<Local, Env, index_value>::type
- type;
- };
- template <typename Local, typename Env>
- struct apply_local
- {
- // $$$ TODO: static assert that Env is a scoped_environment $$$
- typedef typename get_local<Local, Env>::type type;
- };
- template <typename Key>
- struct eval_local
- {
- template <typename RT, int Index, typename Env>
- static RT
- get(Env const& env, mpl::false_)
- {
- return RT(fusion::at_c<Index>(env.locals));
- }
- template <typename RT, int Index, typename Env>
- static RT
- get(Env const& env, mpl::true_)
- {
- static const int index_value = get_index<typename Env::outer_env_type::map_type, detail::local<Key> >::value;
- return get<RT, index_value>(
- env.outer_env
- , mpl::bool_<index_value == -1>());
- }
- template <typename RT, int Index, typename Env>
- static RT
- get(Env const& env)
- {
- return get<RT, Index>(
- env
- , mpl::bool_<Index == -1>());
- }
- };
- }
- }}
- #undef BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
- #undef BOOST_PHOENIX_MAP_LOCAL_DISPATCH
- #endif
|