reverse_fold_impl_body.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION!
  2. #if !defined(BOOST_PP_IS_ITERATING)
  3. // Copyright Aleksey Gurtovoy 2000-2004
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/mpl for documentation.
  10. // $Id$
  11. // $Date$
  12. // $Revision$
  13. # include <boost/mpl/limits/unrolling.hpp>
  14. # include <boost/mpl/aux_/preprocessor/repeat.hpp>
  15. # include <boost/mpl/aux_/config/ctps.hpp>
  16. # include <boost/mpl/aux_/nttp_decl.hpp>
  17. # include <boost/preprocessor/arithmetic/sub.hpp>
  18. # include <boost/preprocessor/iterate.hpp>
  19. # include <boost/preprocessor/dec.hpp>
  20. # include <boost/preprocessor/inc.hpp>
  21. # include <boost/preprocessor/cat.hpp>
  22. // local macros, #undef-ined at the end of the header
  23. # define AUX778076_ITER_FOLD_FORWARD_STEP(unused, n_, unused2) \
  24. typedef typename apply2< \
  25. ForwardOp \
  26. , BOOST_PP_CAT(fwd_state,n_) \
  27. , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,n_)) \
  28. >::type BOOST_PP_CAT(fwd_state,BOOST_PP_INC(n_)); \
  29. typedef typename mpl::next<BOOST_PP_CAT(iter,n_)>::type \
  30. BOOST_PP_CAT(iter,BOOST_PP_INC(n_)); \
  31. /**/
  32. # define AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC(n_) \
  33. typedef typename apply2< \
  34. BackwardOp \
  35. , BOOST_PP_CAT(bkwd_state,n_) \
  36. , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,BOOST_PP_DEC(n_))) \
  37. >::type BOOST_PP_CAT(bkwd_state,BOOST_PP_DEC(n_)); \
  38. /**/
  39. # define AUX778076_ITER_FOLD_BACKWARD_STEP(unused, n_, j) \
  40. AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC( \
  41. BOOST_PP_SUB_D(1,j,n_) \
  42. ) \
  43. /**/
  44. # define AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(n_) \
  45. typedef typename nested_chunk::state BOOST_PP_CAT(bkwd_state,n_);
  46. /**/
  47. # define AUX778076_FOLD_IMPL_NAME \
  48. BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \
  49. /**/
  50. # define AUX778076_FOLD_CHUNK_NAME \
  51. BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \
  52. /**/
  53. namespace boost { namespace mpl { namespace aux {
  54. /// forward declaration
  55. template<
  56. BOOST_MPL_AUX_NTTP_DECL(long, N)
  57. , typename First
  58. , typename Last
  59. , typename State
  60. , typename BackwardOp
  61. , typename ForwardOp
  62. >
  63. struct AUX778076_FOLD_IMPL_NAME;
  64. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
  65. && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC)
  66. # define BOOST_PP_ITERATION_PARAMS_1 \
  67. (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/reverse_fold_impl_body.hpp>))
  68. # include BOOST_PP_ITERATE()
  69. // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
  70. template<
  71. BOOST_MPL_AUX_NTTP_DECL(long, N)
  72. , typename First
  73. , typename Last
  74. , typename State
  75. , typename BackwardOp
  76. , typename ForwardOp
  77. >
  78. struct AUX778076_FOLD_IMPL_NAME
  79. {
  80. typedef First iter0;
  81. typedef State fwd_state0;
  82. BOOST_MPL_PP_REPEAT(
  83. BOOST_MPL_LIMIT_UNROLLING
  84. , AUX778076_ITER_FOLD_FORWARD_STEP
  85. , unused
  86. )
  87. typedef AUX778076_FOLD_IMPL_NAME<
  88. ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
  89. , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING)
  90. , Last
  91. , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING)
  92. , BackwardOp
  93. , ForwardOp
  94. > nested_chunk;
  95. AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING)
  96. BOOST_MPL_PP_REPEAT(
  97. BOOST_MPL_LIMIT_UNROLLING
  98. , AUX778076_ITER_FOLD_BACKWARD_STEP
  99. , BOOST_MPL_LIMIT_UNROLLING
  100. )
  101. typedef bkwd_state0 state;
  102. typedef typename nested_chunk::iterator iterator;
  103. };
  104. // fallback implementation for sequences of unknown size
  105. template<
  106. typename First
  107. , typename Last
  108. , typename State
  109. , typename BackwardOp
  110. , typename ForwardOp
  111. >
  112. struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,BackwardOp,ForwardOp>
  113. {
  114. typedef AUX778076_FOLD_IMPL_NAME<
  115. -1
  116. , typename mpl::next<First>::type
  117. , Last
  118. , typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
  119. , BackwardOp
  120. , ForwardOp
  121. > nested_step;
  122. typedef typename apply2<
  123. BackwardOp
  124. , typename nested_step::state
  125. , AUX778076_FOLD_IMPL_OP(First)
  126. >::type state;
  127. typedef typename nested_step::iterator iterator;
  128. };
  129. template<
  130. typename Last
  131. , typename State
  132. , typename BackwardOp
  133. , typename ForwardOp
  134. >
  135. struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,BackwardOp,ForwardOp>
  136. {
  137. typedef State state;
  138. typedef Last iterator;
  139. };
  140. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  141. template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
  142. struct AUX778076_FOLD_CHUNK_NAME;
  143. # define BOOST_PP_ITERATION_PARAMS_1 \
  144. (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/reverse_fold_impl_body.hpp>))
  145. # include BOOST_PP_ITERATE()
  146. // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
  147. template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
  148. struct AUX778076_FOLD_CHUNK_NAME
  149. {
  150. template<
  151. typename First
  152. , typename Last
  153. , typename State
  154. , typename BackwardOp
  155. , typename ForwardOp
  156. >
  157. struct result_
  158. {
  159. typedef First iter0;
  160. typedef State fwd_state0;
  161. BOOST_MPL_PP_REPEAT(
  162. BOOST_MPL_LIMIT_UNROLLING
  163. , AUX778076_ITER_FOLD_FORWARD_STEP
  164. , unused
  165. )
  166. typedef AUX778076_FOLD_IMPL_NAME<
  167. ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
  168. , BOOST_PP_CAT(iter,BOOST_MPL_LIMIT_UNROLLING)
  169. , Last
  170. , BOOST_PP_CAT(fwd_state,BOOST_MPL_LIMIT_UNROLLING)
  171. , BackwardOp
  172. , ForwardOp
  173. > nested_chunk;
  174. AUX778076_FIRST_BACKWARD_STATE_TYPEDEF(BOOST_MPL_LIMIT_UNROLLING)
  175. BOOST_MPL_PP_REPEAT(
  176. BOOST_MPL_LIMIT_UNROLLING
  177. , AUX778076_ITER_FOLD_BACKWARD_STEP
  178. , BOOST_MPL_LIMIT_UNROLLING
  179. )
  180. typedef bkwd_state0 state;
  181. typedef typename nested_chunk::iterator iterator;
  182. };
  183. };
  184. // fallback implementation for sequences of unknown size
  185. template<
  186. typename First
  187. , typename Last
  188. , typename State
  189. , typename BackwardOp
  190. , typename ForwardOp
  191. >
  192. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step);
  193. template<
  194. typename Last
  195. , typename State
  196. >
  197. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)
  198. {
  199. typedef Last iterator;
  200. typedef State state;
  201. };
  202. template<>
  203. struct AUX778076_FOLD_CHUNK_NAME<-1>
  204. {
  205. template<
  206. typename First
  207. , typename Last
  208. , typename State
  209. , typename BackwardOp
  210. , typename ForwardOp
  211. >
  212. struct result_
  213. {
  214. typedef typename if_<
  215. typename is_same<First,Last>::type
  216. , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)<Last,State>
  217. , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)<First,Last,State,BackwardOp,ForwardOp>
  218. >::type res_;
  219. typedef typename res_::state state;
  220. typedef typename res_::iterator iterator;
  221. };
  222. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  223. /// ETI workaround
  224. template<> struct result_<int,int,int,int,int>
  225. {
  226. typedef int state;
  227. typedef int iterator;
  228. };
  229. #endif
  230. };
  231. template<
  232. typename First
  233. , typename Last
  234. , typename State
  235. , typename BackwardOp
  236. , typename ForwardOp
  237. >
  238. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)
  239. {
  240. typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_<
  241. typename mpl::next<First>::type
  242. , Last
  243. , typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
  244. , BackwardOp
  245. , ForwardOp
  246. > nested_step;
  247. typedef typename apply2<
  248. BackwardOp
  249. , typename nested_step::state
  250. , AUX778076_FOLD_IMPL_OP(First)
  251. >::type state;
  252. typedef typename nested_step::iterator iterator;
  253. };
  254. template<
  255. BOOST_MPL_AUX_NTTP_DECL(long, N)
  256. , typename First
  257. , typename Last
  258. , typename State
  259. , typename BackwardOp
  260. , typename ForwardOp
  261. >
  262. struct AUX778076_FOLD_IMPL_NAME
  263. : AUX778076_FOLD_CHUNK_NAME<N>
  264. ::template result_<First,Last,State,BackwardOp,ForwardOp>
  265. {
  266. };
  267. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  268. }}}
  269. # undef AUX778076_FIRST_BACKWARD_STATE_TYPEDEF
  270. # undef AUX778076_ITER_FOLD_BACKWARD_STEP
  271. # undef AUX778076_ITER_FOLD_BACKWARD_STEP_FUNC
  272. # undef AUX778076_ITER_FOLD_FORWARD_STEP
  273. #undef AUX778076_FOLD_IMPL_OP
  274. #undef AUX778076_FOLD_IMPL_NAME_PREFIX
  275. ///// iteration
  276. #else
  277. # define n_ BOOST_PP_FRAME_ITERATION(1)
  278. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
  279. && !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC)
  280. template<
  281. typename First
  282. , typename Last
  283. , typename State
  284. , typename BackwardOp
  285. , typename ForwardOp
  286. >
  287. struct AUX778076_FOLD_IMPL_NAME<n_,First,Last,State,BackwardOp,ForwardOp>
  288. {
  289. typedef First iter0;
  290. typedef State fwd_state0;
  291. BOOST_MPL_PP_REPEAT(
  292. n_
  293. , AUX778076_ITER_FOLD_FORWARD_STEP
  294. , unused
  295. )
  296. typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_);
  297. BOOST_MPL_PP_REPEAT(
  298. n_
  299. , AUX778076_ITER_FOLD_BACKWARD_STEP
  300. , n_
  301. )
  302. typedef bkwd_state0 state;
  303. typedef BOOST_PP_CAT(iter,n_) iterator;
  304. };
  305. #else
  306. template<> struct AUX778076_FOLD_CHUNK_NAME<n_>
  307. {
  308. template<
  309. typename First
  310. , typename Last
  311. , typename State
  312. , typename BackwardOp
  313. , typename ForwardOp
  314. >
  315. struct result_
  316. {
  317. typedef First iter0;
  318. typedef State fwd_state0;
  319. BOOST_MPL_PP_REPEAT(
  320. n_
  321. , AUX778076_ITER_FOLD_FORWARD_STEP
  322. , unused
  323. )
  324. typedef BOOST_PP_CAT(fwd_state,n_) BOOST_PP_CAT(bkwd_state,n_);
  325. BOOST_MPL_PP_REPEAT(
  326. n_
  327. , AUX778076_ITER_FOLD_BACKWARD_STEP
  328. , n_
  329. )
  330. typedef bkwd_state0 state;
  331. typedef BOOST_PP_CAT(iter,n_) iterator;
  332. };
  333. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  334. /// ETI workaround
  335. template<> struct result_<int,int,int,int,int>
  336. {
  337. typedef int state;
  338. typedef int iterator;
  339. };
  340. #endif
  341. };
  342. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  343. # undef n_
  344. #endif // BOOST_PP_IS_ITERATING