fold.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2006 Dan Marsden
  4. Copyright (c) 2009-2010 Christopher Schmidt
  5. Copyright (c) 2015 Kohei Takahashi
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. ==============================================================================*/
  9. #include <boost/preprocessor/cat.hpp>
  10. #define FUSION_HASH #
  11. #ifdef BOOST_FUSION_REVERSE_FOLD
  12. # ifdef BOOST_FUSION_ITER_FOLD
  13. # define BOOST_FUSION_FOLD_NAME reverse_iter_fold
  14. # else
  15. # define BOOST_FUSION_FOLD_NAME reverse_fold
  16. # endif
  17. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION end
  18. # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION prior
  19. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) \
  20. typename fusion::result_of::prior<IT>::type
  21. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) fusion::prior(IT)
  22. #else
  23. # ifdef BOOST_FUSION_ITER_FOLD
  24. # define BOOST_FUSION_FOLD_NAME iter_fold
  25. # else
  26. # define BOOST_FUSION_FOLD_NAME fold
  27. # endif
  28. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION begin
  29. # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION next
  30. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) IT
  31. # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) IT
  32. #endif
  33. #ifdef BOOST_FUSION_ITER_FOLD
  34. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) IT&
  35. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) IT
  36. #else
  37. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) \
  38. typename fusion::result_of::deref<IT>::type
  39. # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT)
  40. #endif
  41. #if (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
  42. FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
  43. FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void
  44. FUSION_HASH else
  45. FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
  46. FUSION_HASH endif
  47. #else
  48. # if BOOST_WORKAROUND(BOOST_MSVC, < 1500)
  49. # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void
  50. # else
  51. # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
  52. # endif
  53. #endif
  54. namespace boost { namespace fusion
  55. {
  56. namespace detail
  57. {
  58. template<int SeqSize, typename It, typename State, typename F, typename = void
  59. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  60. FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
  61. #endif
  62. #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
  63. (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
  64. // Dirty hack: those compilers cannot choose exactly one partial specialization.
  65. , bool = SeqSize == 0
  66. #endif
  67. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  68. FUSION_HASH endif
  69. #endif
  70. >
  71. struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)
  72. {};
  73. template<typename It, typename State, typename F>
  74. struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<0,It,State,F
  75. , typename boost::enable_if_has_type<BOOST_FUSION_FOLD_IMPL_ENABLER(State)>::type
  76. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  77. FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
  78. #endif
  79. #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
  80. (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
  81. , true
  82. #endif
  83. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  84. FUSION_HASH endif
  85. #endif
  86. >
  87. {
  88. typedef typename State::type type;
  89. };
  90. template<int SeqSize, typename It, typename State, typename F>
  91. struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<SeqSize,It,State,F
  92. , typename boost::enable_if_has_type<
  93. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  94. FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, >= 1500)
  95. #endif
  96. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1500) || \
  97. (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
  98. // Following SFINAE enables to avoid MSVC 9's partial specialization
  99. // ambiguous bug but MSVC 8 don't compile, and moreover MSVC 8 style
  100. // workaround won't work with MSVC 9.
  101. typename boost::disable_if_c<SeqSize == 0, State>::type::type
  102. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  103. FUSION_HASH else
  104. BOOST_FUSION_FOLD_IMPL_ENABLER(State)
  105. #endif
  106. #else
  107. BOOST_FUSION_FOLD_IMPL_ENABLER(State)
  108. #endif
  109. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  110. FUSION_HASH endif
  111. #endif
  112. >::type
  113. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  114. FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
  115. #endif
  116. #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
  117. (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
  118. , false
  119. #endif
  120. #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
  121. FUSION_HASH endif
  122. #endif
  123. >
  124. : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
  125. SeqSize-1
  126. , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
  127. , boost::result_of<
  128. F(
  129. typename add_reference<typename State::type>::type,
  130. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
  131. )
  132. >
  133. , F
  134. >
  135. {};
  136. template<typename It, typename State, typename F>
  137. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  138. inline typename BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
  139. 0
  140. , It
  141. , State
  142. , F
  143. >::type
  144. BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<0>, It const&, typename State::type state, F&)
  145. {
  146. return state;
  147. }
  148. template<typename It, typename State, typename F, int SeqSize>
  149. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  150. inline typename lazy_enable_if_c<
  151. SeqSize != 0
  152. , BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
  153. SeqSize
  154. , It
  155. , State
  156. , F
  157. >
  158. >::type
  159. BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<SeqSize>, It const& it, typename State::type state, F& f)
  160. {
  161. return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)<
  162. typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
  163. , boost::result_of<
  164. F(
  165. typename add_reference<typename State::type>::type,
  166. BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
  167. )
  168. >
  169. , F
  170. >(
  171. mpl::int_<SeqSize-1>()
  172. , fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it)
  173. , f(state, BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it))
  174. , f
  175. );
  176. }
  177. template<typename Seq, typename State, typename F
  178. , bool = traits::is_sequence<Seq>::value
  179. , bool = traits::is_segmented<Seq>::value>
  180. struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)
  181. {};
  182. template<typename Seq, typename State, typename F>
  183. struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F, true, false>
  184. : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
  185. result_of::size<Seq>::value
  186. , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
  187. typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
  188. )
  189. , add_reference<State>
  190. , F
  191. >
  192. {};
  193. template<typename Seq, typename State, typename F>
  194. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  195. inline typename BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>::type
  196. BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F& f)
  197. {
  198. return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)<
  199. BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
  200. typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
  201. )
  202. , add_reference<State>
  203. , F
  204. >(
  205. typename result_of::size<Seq>::type()
  206. , BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(
  207. fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq)
  208. )
  209. , state
  210. , f
  211. );
  212. }
  213. }
  214. namespace result_of
  215. {
  216. template<typename Seq, typename State, typename F>
  217. struct BOOST_FUSION_FOLD_NAME
  218. : detail::BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>
  219. {};
  220. }
  221. template<typename Seq, typename State, typename F>
  222. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  223. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  224. Seq
  225. , State const
  226. , F
  227. >::type
  228. BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f)
  229. {
  230. return detail::BOOST_FUSION_FOLD_NAME<Seq, State const, F>(seq, state, f);
  231. }
  232. template<typename Seq, typename State, typename F>
  233. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  234. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  235. Seq const
  236. , State const
  237. , F
  238. >::type
  239. BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f)
  240. {
  241. return detail::BOOST_FUSION_FOLD_NAME<Seq const, State const, F>(seq, state, f);
  242. }
  243. template<typename Seq, typename State, typename F>
  244. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  245. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  246. Seq
  247. , State
  248. , F
  249. >::type
  250. BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f)
  251. {
  252. return detail::BOOST_FUSION_FOLD_NAME<Seq, State, F>(seq, state, f);
  253. }
  254. template<typename Seq, typename State, typename F>
  255. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  256. inline typename result_of::BOOST_FUSION_FOLD_NAME<
  257. Seq const
  258. , State
  259. , F
  260. >::type
  261. BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f)
  262. {
  263. return detail::BOOST_FUSION_FOLD_NAME<Seq const, State, F>(seq, state, f);
  264. }
  265. }}
  266. #undef BOOST_FUSION_FOLD_NAME
  267. #undef BOOST_FUSION_FOLD_IMPL_ENABLER
  268. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION
  269. #undef BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION
  270. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM
  271. #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM
  272. #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM
  273. #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM
  274. #undef FUSION_HASH