File indexing completed on 2025-01-18 09:46:32
0001
0002
0003
0004
0005
0006
0007
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(¬_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
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
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