fold.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2006 Dan Marsden
  4. Copyright (c) 2009-2010 Christopher Schmidt
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #include <boost/preprocessor/cat.hpp>
  9. #ifdef BOOST_FUSION_REVERSE_FOLD
  10. # ifdef BOOST_FUSION_ITER_FOLD
  11. # define BOOST_FUSION_FOLD_NAME reverse_iter_fold
  12. # else
  13. # define BOOST_FUSION_FOLD_NAME reverse_fold
  14. # endif
  15. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION end
  16. # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION prior
  17. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) \
  18. typename fusion::result_of::prior<IT>::type
  19. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) fusion::prior(IT)
  20. #else
  21. # ifdef BOOST_FUSION_ITER_FOLD
  22. # define BOOST_FUSION_FOLD_NAME iter_fold
  23. # else
  24. # define BOOST_FUSION_FOLD_NAME fold
  25. # endif
  26. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION begin
  27. # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION next
  28. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) IT
  29. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) IT
  30. #endif
  31. #ifdef BOOST_FUSION_ITER_FOLD
  32. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) IT&
  33. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) IT
  34. #else
  35. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) \
  36. typename fusion::result_of::deref<IT>::type
  37. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT)
  38. #endif
  39. namespace boost { namespace fusion
  40. {
  41. namespace detail
  42. {
  43. template<typename State, typename It, typename F>
  44. struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)
  45. : boost::result_of<
  46. F(
  47. typename add_reference<typename add_const<State>::type>::type,
  48. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It))
  49. >
  50. {};
  51. template<typename Result,int N>
  52. struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)
  53. {
  54. template<typename State, typename It0, typename F>
  55. static Result
  56. call(State const& state,It0 const& it0,F f)
  57. {
  58. typedef typename
  59. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  60. It0 const
  61. >::type
  62. It1;
  63. It1 it1 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0);
  64. typedef typename
  65. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  66. It1
  67. >::type
  68. It2;
  69. It2 it2 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1);
  70. typedef typename
  71. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  72. It2
  73. >::type
  74. It3;
  75. It3 it3 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it2);
  76. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State,It0,F>::type State1;
  77. State1 const state1=f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0));
  78. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State1,It1,F>::type State2;
  79. State2 const state2=f(state1,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1));
  80. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State2,It2,F>::type State3;
  81. State3 const state3=f(state2,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it2));
  82. return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
  83. Result
  84. , N-4
  85. >::call(
  86. f(state3,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it3)),
  87. fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it3),
  88. f);
  89. }
  90. };
  91. template<typename Result>
  92. struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,3>
  93. {
  94. template<typename State, typename It0, typename F>
  95. static Result
  96. call(State const& state,It0 const& it0,F f)
  97. {
  98. typedef typename
  99. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  100. It0 const
  101. >::type
  102. It1;
  103. It1 it1 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0);
  104. typedef typename
  105. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  106. It1
  107. >::type
  108. It2;
  109. It2 it2 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1);
  110. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State,It0,F>::type State1;
  111. State1 const state1=f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0));
  112. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State1,It1,F>::type State2;
  113. State2 const state2=f(state1,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1));
  114. return f(state2,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it2));
  115. }
  116. };
  117. template<typename Result>
  118. struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,2>
  119. {
  120. template<typename State, typename It0, typename F>
  121. static Result
  122. call(State const& state,It0 const& it0,F f)
  123. {
  124. typedef typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<State,It0,F>::type State1;
  125. State1 const state1=f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0));
  126. return f(
  127. state1,
  128. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(
  129. fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0)));
  130. }
  131. };
  132. template<typename Result>
  133. struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,1>
  134. {
  135. template<typename State, typename It0, typename F>
  136. static Result
  137. call(State const& state,It0 const& it0,F f)
  138. {
  139. return f(state,
  140. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0));
  141. }
  142. };
  143. template<typename Result>
  144. struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,0>
  145. {
  146. template<typename State, typename It0, typename F>
  147. static Result
  148. call(State const& state,It0 const& it0, F)
  149. {
  150. return static_cast<Result>(state);
  151. }
  152. };
  153. template<typename StateRef, typename It0, typename F, int N>
  154. struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)
  155. {
  156. typedef typename
  157. BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  158. StateRef
  159. , It0 const
  160. , F
  161. >::type
  162. rest1;
  163. typedef typename
  164. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  165. It0 const
  166. >::type
  167. it1;
  168. typedef typename
  169. BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  170. rest1
  171. , it1
  172. , F
  173. >::type
  174. rest2;
  175. typedef typename
  176. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<it1>::type
  177. it2;
  178. typedef typename
  179. BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  180. rest2
  181. , it2
  182. , F
  183. >::type
  184. rest3;
  185. typedef typename
  186. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<it2>::type
  187. it3;
  188. typedef typename
  189. BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  190. typename BOOST_PP_CAT(
  191. BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  192. rest3
  193. , it3
  194. , F
  195. >::type
  196. , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  197. it3
  198. >::type
  199. , F
  200. , N-4
  201. >::type
  202. type;
  203. };
  204. template<typename StateRef, typename It0, typename F>
  205. struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  206. StateRef
  207. , It0
  208. , F
  209. , 3
  210. >
  211. {
  212. typedef typename
  213. BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  214. StateRef
  215. , It0 const
  216. , F
  217. >::type
  218. rest1;
  219. typedef typename
  220. result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  221. It0 const
  222. >::type
  223. it1;
  224. typedef typename
  225. BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  226. typename BOOST_PP_CAT(
  227. BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  228. rest1
  229. , it1
  230. , F
  231. >::type
  232. , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  233. it1 const
  234. >::type const
  235. , F
  236. >::type
  237. type;
  238. };
  239. template<typename StateRef, typename It0, typename F>
  240. struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  241. StateRef
  242. , It0
  243. , F
  244. , 2
  245. >
  246. : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  247. typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  248. StateRef
  249. , It0 const
  250. , F
  251. >::type
  252. , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  253. It0 const
  254. >::type const
  255. , F
  256. >
  257. {};
  258. template<typename StateRef, typename It0, typename F>
  259. struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  260. StateRef
  261. , It0
  262. , F
  263. , 1
  264. >
  265. : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)<
  266. StateRef
  267. , It0 const
  268. , F
  269. >
  270. {};
  271. template<typename StateRef, typename It0, typename F>
  272. struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  273. StateRef
  274. , It0
  275. , F
  276. , 0
  277. >
  278. {
  279. typedef StateRef type;
  280. };
  281. template<typename StateRef, typename It0, typename F, int SeqSize>
  282. struct BOOST_PP_CAT(result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)
  283. {
  284. typedef typename
  285. BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)<
  286. typename boost::result_of<
  287. F(
  288. StateRef,
  289. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(
  290. It0 const)
  291. )
  292. >::type
  293. , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<
  294. It0 const
  295. >::type
  296. , F
  297. , SeqSize-1
  298. >::type
  299. type;
  300. };
  301. template<int SeqSize, typename StateRef, typename Seq, typename F>
  302. struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)
  303. {
  304. typedef typename
  305. BOOST_PP_CAT(
  306. result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)<
  307. StateRef
  308. , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
  309. typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
  310. )
  311. , F
  312. , SeqSize
  313. >::type
  314. type;
  315. static type
  316. call(StateRef state, Seq& seq, F f)
  317. {
  318. typedef
  319. BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
  320. type
  321. , SeqSize
  322. >
  323. unrolled_impl;
  324. return unrolled_impl::call(
  325. state,
  326. BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(
  327. fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq)),
  328. f);
  329. }
  330. };
  331. template<typename StateRef, typename Seq, typename F>
  332. struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,Seq,F>
  333. {
  334. typedef StateRef type;
  335. static StateRef
  336. call(StateRef state, Seq&, F)
  337. {
  338. return static_cast<StateRef>(state);
  339. }
  340. };
  341. template<typename Seq, typename State, typename F, bool IsSegmented>
  342. struct BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)
  343. : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<
  344. result_of::size<Seq>::value
  345. , typename add_reference<
  346. typename add_const<State>::type
  347. >::type
  348. , Seq
  349. , F
  350. >
  351. {};
  352. }
  353. namespace result_of
  354. {
  355. template<typename Seq, typename State, typename F>
  356. struct BOOST_FUSION_FOLD_NAME
  357. : detail::BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)<
  358. Seq
  359. , State
  360. , F
  361. , traits::is_segmented<Seq>::type::value
  362. >
  363. {};
  364. }
  365. template<typename Seq, typename State, typename F>
  366. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  367. Seq
  368. , State const
  369. , F
  370. >::type
  371. BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f)
  372. {
  373. return result_of::BOOST_FUSION_FOLD_NAME<Seq,State const,F>::call(
  374. state,
  375. seq,
  376. f);
  377. }
  378. template<typename Seq, typename State, typename F>
  379. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  380. Seq const
  381. , State const
  382. , F
  383. >::type
  384. BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f)
  385. {
  386. return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call(
  387. state,
  388. seq,
  389. f);
  390. }
  391. template<typename Seq, typename State, typename F>
  392. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  393. Seq
  394. , State const
  395. , F
  396. >::type
  397. BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f)
  398. {
  399. return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call(
  400. state,
  401. seq,
  402. f);
  403. }
  404. template<typename Seq, typename State, typename F>
  405. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  406. Seq const
  407. , State const
  408. , F
  409. >::type
  410. BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f)
  411. {
  412. return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call(
  413. state,
  414. seq,
  415. f);
  416. }
  417. }}
  418. #undef BOOST_FUSION_FOLD_NAME
  419. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION
  420. #undef BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION
  421. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM
  422. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM
  423. #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM
  424. #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM