Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:46:32

0001 /*=============================================================================
0002     Copyright (c) 2001-2007 Joel de Guzman
0003     Copyright (c) 2004 Daniel Wallin
0004     Copyright (c) 2011 Thomas Heller
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 ==============================================================================*/
0009 #ifndef PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
0010 #define PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
0011 
0012 #include <boost/mpl/int.hpp>
0013 #include <boost/mpl/bool.hpp>
0014 #include <boost/mpl/eval_if.hpp>
0015 #include <boost/mpl/identity.hpp>
0016 #include <boost/fusion/include/at.hpp>
0017 #include <boost/fusion/include/value_at.hpp>
0018 #include <boost/preprocessor/enum.hpp>
0019 #include <boost/preprocessor/repeat.hpp>
0020 #include <boost/type_traits/remove_reference.hpp>
0021 #include <boost/type_traits/is_reference.hpp>
0022 
0023 #define BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM(z, n, data) \
0024     typename T##n = unused<n>
0025 
0026 #define BOOST_PHOENIX_MAP_LOCAL_DISPATCH(z, n, data)  \
0027     typedef char(&result##n)[n+2];              \
0028     static result##n get(T##n*);
0029 
0030 namespace boost { namespace phoenix
0031 {
0032     template <typename Env, typename OuterEnv, typename Locals, typename Map>
0033     struct scoped_environment;
0034 
0035     namespace detail
0036     {
0037         template <typename Key>
0038         struct local
0039         {
0040             typedef Key key_type;
0041         };
0042 
0043         namespace result_of
0044         {
0045             template <typename Locals, typename Context>
0046             struct initialize_locals;
0047             
0048             template <typename Context>
0049             struct initialize_locals<vector0<>, Context>
0050             {
0051                 typedef vector0<> type;
0052             };
0053 
0054         #define M1(Z, N, D)                                                     \
0055             typename boost::phoenix::result_of::eval<                           \
0056                 BOOST_PP_CAT(A, N)                                              \
0057               , Context                                                         \
0058             >::type                                                             \
0059         /**/
0060 
0061         #define M0(Z, N, D)                                                     \
0062             template <BOOST_PHOENIX_typename_A(N), typename Context>            \
0063             struct initialize_locals<                                           \
0064                 BOOST_PP_CAT(vector, N)<                                        \
0065                     BOOST_PHOENIX_A(N)                                          \
0066                 >                                                               \
0067               , Context                                                         \
0068             >                                                                   \
0069             {                                                                   \
0070                 typedef                                                         \
0071                     BOOST_PP_CAT(vector, N)<                                    \
0072                         BOOST_PP_ENUM(N, M1, _)                                 \
0073                     >                                                           \
0074                     type;                                                       \
0075             };                                                                  \
0076         /**/
0077             BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
0078         #undef M0
0079         }
0080 
0081         template <typename Context>
0082         vector0<>
0083         initialize_locals(vector0<> const &, Context const &)
0084         {
0085             vector0<> vars;
0086             return vars;
0087         }
0088     #define M2(Z, N, D)                                                         \
0089         eval(locals. BOOST_PP_CAT(a, N), ctx)                                   \
0090     /**/
0091         
0092     #define M0(Z, N, D)                                                         \
0093         template <BOOST_PHOENIX_typename_A(N), typename Context>                \
0094         BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)>                        \
0095         initialize_locals(                                                      \
0096             BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> const & locals          \
0097           , Context const & ctx                                                 \
0098         )                                                                       \
0099         {                                                                       \
0100             BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)> vars               \
0101                 = {BOOST_PP_ENUM(N, M2, _)};                                    \
0102             return vars;                                                        \
0103         }                                                                       \
0104     /**/
0105         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
0106         #undef M0
0107         #undef M1
0108         #undef M2
0109 
0110         template <int N>
0111         struct unused;
0112 
0113         template <
0114             BOOST_PP_ENUM(
0115                 BOOST_PHOENIX_LOCAL_LIMIT
0116               , BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
0117               , _
0118             )
0119         >
0120         struct map_local_index_to_tuple
0121         {
0122             typedef char(&not_found)[1];
0123             static not_found get(...);
0124 
0125             BOOST_PP_REPEAT(BOOST_PHOENIX_LOCAL_LIMIT, BOOST_PHOENIX_MAP_LOCAL_DISPATCH, _)
0126         };
0127         
0128         template<typename T>
0129         T* generate_pointer();
0130 
0131         template <typename Map, typename Tag>
0132         struct get_index
0133         {
0134             BOOST_STATIC_CONSTANT(int,
0135                 value = (
0136                     static_cast<int>((sizeof(Map::get(generate_pointer<Tag>()))) / sizeof(char)) - 2
0137                 ));
0138 
0139             // if value == -1, Tag is not found
0140             typedef mpl::int_<value> type;
0141         };
0142 
0143         
0144         template <typename Local, typename Env>
0145         struct apply_local;
0146 
0147         template <typename Local, typename Env>
0148         struct outer_local
0149         {
0150             typedef typename
0151                 apply_local<Local, typename Env::outer_env_type>::type
0152             type;
0153         };
0154 
0155         template <typename Locals, int Index>
0156         struct get_local_or_void
0157         {
0158             typedef typename
0159                 mpl::eval_if_c<
0160                     Index < Locals::size_value
0161                   , fusion::result_of::at_c<Locals, Index>
0162                   , mpl::identity<fusion::void_>
0163                 >::type
0164                 type;
0165         };
0166 
0167         template <typename Local, typename Env, int Index>
0168         struct get_local_from_index
0169         {
0170             typedef typename
0171                 mpl::eval_if_c<
0172                     Index == -1
0173                   , outer_local<Local, Env>
0174                   , get_local_or_void<typename Env::locals_type, Index>
0175                 >::type
0176                 type;
0177         };
0178 
0179         template <typename Local, typename Env>
0180         struct get_local
0181         {
0182             static const int index_value = get_index<typename Env::map_type, Local>::value;
0183 
0184             typedef typename
0185                 get_local_from_index<Local, Env, index_value>::type
0186             type;
0187         };
0188 
0189         template <typename Local, typename Env>
0190         struct apply_local
0191         {
0192             // $$$ TODO: static assert that Env is a scoped_environment $$$
0193             typedef typename get_local<Local, Env>::type type;
0194         };
0195 
0196         template <typename Key>
0197         struct eval_local
0198         {
0199             template <typename RT, int Index, typename Env>
0200             static RT
0201             get(Env const& env, mpl::false_)
0202             {
0203                 return RT(fusion::at_c<Index>(env.locals));
0204             }
0205 
0206             template <typename RT, int Index, typename Env>
0207             static RT
0208             get(Env const& env, mpl::true_)
0209             {
0210                 static const int index_value = get_index<typename Env::outer_env_type::map_type, detail::local<Key> >::value;
0211 
0212                 return get<RT, index_value>(
0213                     env.outer_env
0214                   , mpl::bool_<index_value == -1>());
0215             }
0216 
0217             template <typename RT, int Index, typename Env>
0218             static RT
0219             get(Env const& env)
0220             {
0221                 return get<RT, Index>(
0222                     env
0223                   , mpl::bool_<Index == -1>());
0224             }
0225         };
0226     }
0227 }}
0228 
0229 #undef BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
0230 #undef BOOST_PHOENIX_MAP_LOCAL_DISPATCH
0231 
0232 #endif