fold_impl_body.hpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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/workaround.hpp>
  16. # include <boost/mpl/aux_/config/ctps.hpp>
  17. # include <boost/mpl/aux_/nttp_decl.hpp>
  18. # include <boost/mpl/aux_/config/eti.hpp>
  19. # include <boost/preprocessor/iterate.hpp>
  20. # include <boost/preprocessor/dec.hpp>
  21. # include <boost/preprocessor/cat.hpp>
  22. // local macros, #undef-ined at the end of the header
  23. # define AUX778076_ITER_FOLD_STEP(unused, i, unused2) \
  24. typedef typename apply2< \
  25. ForwardOp \
  26. , BOOST_PP_CAT(state,i) \
  27. , AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,i)) \
  28. >::type BOOST_PP_CAT(state,BOOST_PP_INC(i)); \
  29. typedef typename mpl::next<BOOST_PP_CAT(iter,i)>::type \
  30. BOOST_PP_CAT(iter,BOOST_PP_INC(i)); \
  31. /**/
  32. # define AUX778076_FOLD_IMPL_NAME \
  33. BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \
  34. /**/
  35. # define AUX778076_FOLD_CHUNK_NAME \
  36. BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \
  37. /**/
  38. namespace boost { namespace mpl { namespace aux {
  39. /// forward declaration
  40. template<
  41. BOOST_MPL_AUX_NTTP_DECL(int, N)
  42. , typename First
  43. , typename Last
  44. , typename State
  45. , typename ForwardOp
  46. >
  47. struct AUX778076_FOLD_IMPL_NAME;
  48. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  49. # if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
  50. # define BOOST_PP_ITERATION_PARAMS_1 \
  51. (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/fold_impl_body.hpp>))
  52. # include BOOST_PP_ITERATE()
  53. // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
  54. template<
  55. BOOST_MPL_AUX_NTTP_DECL(int, N)
  56. , typename First
  57. , typename Last
  58. , typename State
  59. , typename ForwardOp
  60. >
  61. struct AUX778076_FOLD_IMPL_NAME
  62. {
  63. typedef AUX778076_FOLD_IMPL_NAME<
  64. BOOST_MPL_LIMIT_UNROLLING
  65. , First
  66. , Last
  67. , State
  68. , ForwardOp
  69. > chunk_;
  70. typedef AUX778076_FOLD_IMPL_NAME<
  71. ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
  72. , typename chunk_::iterator
  73. , Last
  74. , typename chunk_::state
  75. , ForwardOp
  76. > res_;
  77. typedef typename res_::state state;
  78. typedef typename res_::iterator iterator;
  79. };
  80. // fallback implementation for sequences of unknown size
  81. template<
  82. typename First
  83. , typename Last
  84. , typename State
  85. , typename ForwardOp
  86. >
  87. struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,ForwardOp>
  88. : AUX778076_FOLD_IMPL_NAME<
  89. -1
  90. , typename mpl::next<First>::type
  91. , Last
  92. , typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
  93. , ForwardOp
  94. >
  95. {
  96. };
  97. template<
  98. typename Last
  99. , typename State
  100. , typename ForwardOp
  101. >
  102. struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,ForwardOp>
  103. {
  104. typedef State state;
  105. typedef Last iterator;
  106. };
  107. # else // BOOST_WORKAROUND(__BORLANDC__, < 0x600)
  108. // Borland have some serious problems with the unrolled version, so
  109. // we always use a basic implementation
  110. template<
  111. BOOST_MPL_AUX_NTTP_DECL(int, N)
  112. , typename First
  113. , typename Last
  114. , typename State
  115. , typename ForwardOp
  116. >
  117. struct AUX778076_FOLD_IMPL_NAME
  118. {
  119. typedef AUX778076_FOLD_IMPL_NAME<
  120. -1
  121. , typename mpl::next<First>::type
  122. , Last
  123. , typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
  124. , ForwardOp
  125. > res_;
  126. typedef typename res_::state state;
  127. typedef typename res_::iterator iterator;
  128. typedef state type;
  129. };
  130. template<
  131. BOOST_MPL_AUX_NTTP_DECL(int, N)
  132. , typename Last
  133. , typename State
  134. , typename ForwardOp
  135. >
  136. struct AUX778076_FOLD_IMPL_NAME<N,Last,Last,State,ForwardOp >
  137. {
  138. typedef State state;
  139. typedef Last iterator;
  140. typedef state type;
  141. };
  142. # endif // BOOST_WORKAROUND(__BORLANDC__, < 0x600)
  143. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  144. template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
  145. struct AUX778076_FOLD_CHUNK_NAME;
  146. # define BOOST_PP_ITERATION_PARAMS_1 \
  147. (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/fold_impl_body.hpp>))
  148. # include BOOST_PP_ITERATE()
  149. // implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
  150. template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
  151. struct AUX778076_FOLD_CHUNK_NAME
  152. {
  153. template<
  154. typename First
  155. , typename Last
  156. , typename State
  157. , typename ForwardOp
  158. >
  159. struct result_
  160. {
  161. typedef AUX778076_FOLD_IMPL_NAME<
  162. BOOST_MPL_LIMIT_UNROLLING
  163. , First
  164. , Last
  165. , State
  166. , ForwardOp
  167. > chunk_;
  168. typedef AUX778076_FOLD_IMPL_NAME<
  169. ( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
  170. , typename chunk_::iterator
  171. , Last
  172. , typename chunk_::state
  173. , ForwardOp
  174. > res_;
  175. typedef typename res_::state state;
  176. typedef typename res_::iterator iterator;
  177. };
  178. };
  179. // fallback implementation for sequences of unknown size
  180. template<
  181. typename First
  182. , typename Last
  183. , typename State
  184. , typename ForwardOp
  185. >
  186. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step);
  187. template<
  188. typename Last
  189. , typename State
  190. >
  191. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)
  192. {
  193. typedef Last iterator;
  194. typedef State state;
  195. };
  196. template<>
  197. struct AUX778076_FOLD_CHUNK_NAME<-1>
  198. {
  199. template<
  200. typename First
  201. , typename Last
  202. , typename State
  203. , typename ForwardOp
  204. >
  205. struct result_
  206. {
  207. typedef typename if_<
  208. typename is_same<First,Last>::type
  209. , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)<Last,State>
  210. , BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)<First,Last,State,ForwardOp>
  211. >::type res_;
  212. typedef typename res_::state state;
  213. typedef typename res_::iterator iterator;
  214. };
  215. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  216. /// ETI workaround
  217. template<> struct result_<int,int,int,int>
  218. {
  219. typedef int state;
  220. typedef int iterator;
  221. };
  222. #endif
  223. };
  224. template<
  225. typename First
  226. , typename Last
  227. , typename State
  228. , typename ForwardOp
  229. >
  230. struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)
  231. {
  232. // can't inherit here - it breaks MSVC 7.0
  233. typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_<
  234. typename mpl::next<First>::type
  235. , Last
  236. , typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
  237. , ForwardOp
  238. > chunk_;
  239. typedef typename chunk_::state state;
  240. typedef typename chunk_::iterator iterator;
  241. };
  242. template<
  243. BOOST_MPL_AUX_NTTP_DECL(int, N)
  244. , typename First
  245. , typename Last
  246. , typename State
  247. , typename ForwardOp
  248. >
  249. struct AUX778076_FOLD_IMPL_NAME
  250. : AUX778076_FOLD_CHUNK_NAME<N>
  251. ::template result_<First,Last,State,ForwardOp>
  252. {
  253. };
  254. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  255. }}}
  256. # undef AUX778076_FOLD_IMPL_NAME
  257. # undef AUX778076_FOLD_CHUNK_NAME
  258. # undef AUX778076_ITER_FOLD_STEP
  259. #undef AUX778076_FOLD_IMPL_OP
  260. #undef AUX778076_FOLD_IMPL_NAME_PREFIX
  261. ///// iteration
  262. #else
  263. # define n_ BOOST_PP_FRAME_ITERATION(1)
  264. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  265. template<
  266. typename First
  267. , typename Last
  268. , typename State
  269. , typename ForwardOp
  270. >
  271. struct AUX778076_FOLD_IMPL_NAME<n_,First,Last,State,ForwardOp>
  272. {
  273. typedef First iter0;
  274. typedef State state0;
  275. BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused)
  276. typedef BOOST_PP_CAT(state,n_) state;
  277. typedef BOOST_PP_CAT(iter,n_) iterator;
  278. };
  279. #else
  280. template<> struct AUX778076_FOLD_CHUNK_NAME<n_>
  281. {
  282. template<
  283. typename First
  284. , typename Last
  285. , typename State
  286. , typename ForwardOp
  287. >
  288. struct result_
  289. {
  290. typedef First iter0;
  291. typedef State state0;
  292. BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused)
  293. typedef BOOST_PP_CAT(state,n_) state;
  294. typedef BOOST_PP_CAT(iter,n_) iterator;
  295. };
  296. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  297. /// ETI workaround
  298. template<> struct result_<int,int,int,int>
  299. {
  300. typedef int state;
  301. typedef int iterator;
  302. };
  303. #endif
  304. };
  305. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  306. # undef n_
  307. #endif // BOOST_PP_IS_ITERATING