normalize.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2011 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #ifndef BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_HPP_INCLUDED
  12. #include <boost/mpl/assert.hpp>
  13. #include <boost/mpl/eval_if.hpp>
  14. #include <boost/mpl/identity.hpp>
  15. #include <boost/mpl/is_sequence.hpp>
  16. #include <boost/mpl/set.hpp>
  17. #include <boost/mpl/map.hpp>
  18. #include <boost/mpl/has_key.hpp>
  19. #include <boost/mpl/insert.hpp>
  20. #include <boost/mpl/vector.hpp>
  21. #include <boost/mpl/back_inserter.hpp>
  22. #include <boost/mpl/inserter.hpp>
  23. #include <boost/mpl/fold.hpp>
  24. #include <boost/mpl/transform.hpp>
  25. #include <boost/mpl/copy.hpp>
  26. #include <boost/mpl/at.hpp>
  27. #include <boost/type_traits/is_same.hpp>
  28. #include <boost/type_erasure/detail/get_placeholders.hpp>
  29. #include <boost/type_erasure/detail/rebind_placeholders.hpp>
  30. #include <boost/type_erasure/detail/normalize_deduced.hpp>
  31. #include <boost/type_erasure/detail/meta.hpp>
  32. #include <boost/type_erasure/relaxed.hpp>
  33. #include <boost/type_erasure/builtin.hpp>
  34. namespace boost {
  35. namespace type_erasure {
  36. template<class F>
  37. struct deduced;
  38. template<class T, class U>
  39. struct same_type;
  40. namespace detail {
  41. struct substitution_map_tag {};
  42. // a wrapper around an mpl::map that
  43. // defaults to the identity map.
  44. template<class M>
  45. struct substitution_map
  46. {
  47. typedef substitution_map_tag tag;
  48. typedef M map_type;
  49. };
  50. }
  51. }
  52. namespace mpl {
  53. template<>
  54. struct at_impl< ::boost::type_erasure::detail::substitution_map_tag>
  55. {
  56. template<class Seq, class Key>
  57. struct apply
  58. {
  59. typedef typename ::boost::mpl::eval_if<
  60. ::boost::mpl::has_key<typename Seq::map_type, Key>,
  61. ::boost::mpl::at<typename Seq::map_type, Key>,
  62. ::boost::mpl::identity<Key>
  63. >::type type;
  64. };
  65. };
  66. template<>
  67. struct has_key_impl< ::boost::type_erasure::detail::substitution_map_tag>
  68. {
  69. template<class Seq, class Key>
  70. struct apply : boost::mpl::true_
  71. {};
  72. };
  73. }
  74. namespace type_erasure {
  75. namespace detail {
  76. // Given the arguments to same_type, determines
  77. // which should be the key and which should be
  78. // the value in the substitution map.
  79. template<class T, class U>
  80. struct select_pair
  81. {
  82. BOOST_MPL_ASSERT((::boost::is_same<T, U>));
  83. typedef void type;
  84. };
  85. template<class T, class U>
  86. struct select_pair<T, ::boost::type_erasure::deduced<U> >
  87. {
  88. typedef ::boost::mpl::pair< ::boost::type_erasure::deduced<U>, T> type;
  89. };
  90. template<class T, class U>
  91. struct select_pair< ::boost::type_erasure::deduced<T>, U>
  92. {
  93. typedef ::boost::mpl::pair< ::boost::type_erasure::deduced<T>, U> type;
  94. };
  95. template<class T, class U>
  96. struct select_pair<
  97. ::boost::type_erasure::deduced<T>,
  98. ::boost::type_erasure::deduced<U>
  99. >
  100. {
  101. typedef ::boost::mpl::pair<
  102. ::boost::type_erasure::deduced<T>,
  103. ::boost::type_erasure::deduced<U>
  104. > type;
  105. };
  106. #ifndef BOOST_TYPE_ERASURE_USE_MP11
  107. // given a partial substitution map from same_type,
  108. // resolves a placeholder as far as possible.
  109. template<class M, class T>
  110. struct resolve_same_type
  111. {
  112. typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
  113. ::boost::type_erasure::detail::resolve_same_type<
  114. M,
  115. typename ::boost::mpl::at<M, T>::type
  116. >,
  117. ::boost::mpl::identity<T>
  118. >::type type;
  119. };
  120. // M is a map of placeholder substitutions
  121. template<class M, class T>
  122. struct normalize_placeholder
  123. {
  124. typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
  125. ::boost::type_erasure::detail::normalize_placeholder<
  126. M,
  127. typename ::boost::mpl::at<M, T>::type
  128. >,
  129. ::boost::mpl::identity<T>
  130. >::type type;
  131. };
  132. template<class M, class T>
  133. struct normalize_placeholder<M, ::boost::type_erasure::deduced<T> >
  134. {
  135. typedef typename ::boost::mpl::eval_if< ::boost::mpl::has_key<M, T>,
  136. ::boost::type_erasure::detail::normalize_placeholder<
  137. M,
  138. typename ::boost::mpl::at<M, T>::type
  139. >,
  140. ::boost::type_erasure::detail::normalize_deduced<
  141. M,
  142. T
  143. >
  144. >::type type;
  145. };
  146. // Takes a mpl::map of placeholder substitutions and
  147. // fully resolves it. i.e. a -> b, b -> c, becomes
  148. // a -> c, b -> c. Also resolves deduced placeholders
  149. // whose arguments are all resolved.
  150. template<class M>
  151. struct create_placeholder_map
  152. {
  153. typedef typename ::boost::mpl::fold<
  154. M,
  155. ::boost::mpl::map0<>,
  156. ::boost::mpl::insert<
  157. ::boost::mpl::_1,
  158. ::boost::mpl::pair<
  159. ::boost::mpl::first< ::boost::mpl::_2>,
  160. ::boost::type_erasure::detail::normalize_placeholder<M, ::boost::mpl::second< ::boost::mpl::_2> >
  161. >
  162. >
  163. >::type type;
  164. };
  165. template<class Bindings, class P, class Out, class Sub>
  166. struct convert_deduced
  167. {
  168. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  169. typename P::first,
  170. Bindings
  171. >::type result1;
  172. typedef typename ::boost::mpl::at<Sub, result1>::type result;
  173. typedef typename ::boost::mpl::eval_if<
  174. ::boost::mpl::has_key<Out, typename P::second>,
  175. ::boost::mpl::identity<Out>,
  176. ::boost::mpl::insert<Out, ::boost::mpl::pair<typename P::second, result> >
  177. >::type type;
  178. BOOST_MPL_ASSERT((boost::is_same<typename ::boost::mpl::at<type, typename P::second>::type, result>));
  179. };
  180. template<class Bindings, class M, class Sub>
  181. struct convert_deductions
  182. {
  183. typedef typename ::boost::mpl::fold<
  184. M,
  185. Bindings,
  186. ::boost::type_erasure::detail::convert_deduced<
  187. Bindings, ::boost::mpl::_2, ::boost::mpl::_1, Sub
  188. >
  189. >::type type;
  190. };
  191. template<class Bindings, class P, class Out>
  192. struct add_deduced
  193. {
  194. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  195. typename P::first,
  196. Bindings
  197. >::type result;
  198. typedef typename ::boost::mpl::eval_if<
  199. ::boost::mpl::has_key<Out, typename P::second>,
  200. ::boost::mpl::identity<Out>,
  201. ::boost::mpl::insert<Out, ::boost::mpl::pair<typename P::second, result> >
  202. >::type type;
  203. BOOST_MPL_ASSERT((boost::is_same<typename ::boost::mpl::at<type, typename P::second>::type, result>));
  204. };
  205. template<class Bindings, class M>
  206. struct add_deductions
  207. {
  208. typedef typename ::boost::mpl::fold<
  209. M,
  210. Bindings,
  211. ::boost::type_erasure::detail::add_deduced<
  212. Bindings, ::boost::mpl::_2, ::boost::mpl::_1
  213. >
  214. >::type type;
  215. };
  216. // Fold Op for normalize_concept_impl
  217. template<class Out, class T>
  218. struct insert_concept
  219. {
  220. typedef ::boost::mpl::pair<
  221. typename ::boost::mpl::insert<typename Out::first, T>::type,
  222. typename Out::second
  223. > type;
  224. };
  225. template<class Out, class T, class U>
  226. struct insert_concept<Out, ::boost::type_erasure::same_type<T, U> >
  227. {
  228. typedef typename ::boost::type_erasure::detail::resolve_same_type<
  229. typename Out::second,
  230. T
  231. >::type t1;
  232. typedef typename ::boost::type_erasure::detail::resolve_same_type<
  233. typename Out::second,
  234. U
  235. >::type t2;
  236. typedef ::boost::mpl::pair<
  237. typename Out::first,
  238. typename ::boost::mpl::eval_if<
  239. ::boost::is_same<t1, t2>,
  240. ::boost::mpl::identity<typename Out::second>,
  241. ::boost::mpl::insert<
  242. typename Out::second,
  243. typename ::boost::type_erasure::detail::select_pair<
  244. t1,
  245. t2
  246. >::type
  247. >
  248. >::type
  249. > type;
  250. };
  251. // flattens a concept returning an mpl::pair
  252. // - first is an MPL sequence containing the leaf concepts
  253. // - second is an MPL map of the placeholder substitutions
  254. // used to resolve same_type.
  255. template<class Concept, class Out = ::boost::mpl::pair< ::boost::mpl::set0<>, ::boost::mpl::map0<> > >
  256. struct normalize_concept_impl
  257. {
  258. typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
  259. ::boost::mpl::fold<Concept, Out, normalize_concept_impl< ::boost::mpl::_2, ::boost::mpl::_1> >,
  260. ::boost::type_erasure::detail::insert_concept<Out, Concept>
  261. >::type type;
  262. };
  263. struct append_typeinfo
  264. {
  265. template<class Set, class T>
  266. struct apply
  267. {
  268. typedef typename ::boost::mpl::insert<
  269. Set,
  270. ::boost::type_erasure::typeid_<T>
  271. >::type type;
  272. };
  273. };
  274. // Seq should be a flattened MPL sequence of leaf concepts.
  275. // adds typeid_<P> for every placeholder used.
  276. template<class Seq>
  277. struct add_typeinfo
  278. {
  279. typedef typename ::boost::mpl::fold<
  280. Seq,
  281. ::boost::mpl::set0<>,
  282. ::boost::type_erasure::detail::get_placeholders<
  283. ::boost::mpl::_2,
  284. ::boost::mpl::_1
  285. >
  286. >::type placeholders;
  287. typedef typename ::boost::mpl::fold<
  288. placeholders,
  289. Seq,
  290. ::boost::type_erasure::detail::append_typeinfo
  291. >::type type;
  292. };
  293. template<class Concept>
  294. struct get_placeholder_normalization_map
  295. {
  296. typedef typename ::boost::type_erasure::detail::create_placeholder_map<
  297. typename normalize_concept_impl<Concept>::type::second
  298. >::type type;
  299. };
  300. // Flattens a Concept to an mpl::vector of primitive
  301. // concepts. Resolves same_type and deduced placeholders.
  302. template<class Concept>
  303. struct normalize_concept
  304. {
  305. typedef typename normalize_concept_impl<Concept>::type impl;
  306. typedef typename ::boost::type_erasure::detail::create_placeholder_map<
  307. typename impl::second
  308. >::type substitutions;
  309. typedef typename ::boost::mpl::fold<
  310. typename impl::first,
  311. ::boost::mpl::set0<>,
  312. ::boost::mpl::insert<
  313. ::boost::mpl::_1,
  314. ::boost::type_erasure::detail::rebind_placeholders<
  315. ::boost::mpl::_2,
  316. ::boost::type_erasure::detail::substitution_map<substitutions>
  317. >
  318. >
  319. >::type basic;
  320. typedef typename ::boost::mpl::eval_if<
  321. ::boost::type_erasure::is_relaxed<Concept>,
  322. ::boost::type_erasure::detail::add_typeinfo<basic>,
  323. ::boost::mpl::identity<basic>
  324. >::type concept_set;
  325. typedef typename ::boost::mpl::copy<
  326. concept_set,
  327. ::boost::mpl::back_inserter< ::boost::mpl::vector0<> >
  328. >::type type;
  329. };
  330. // Returns an MPL sequence containing all the concepts
  331. // in Concept. If Concept is considered as a DAG,
  332. // the result will be sorted topologically.
  333. template<
  334. class Concept,
  335. class Map = typename ::boost::type_erasure::detail::create_placeholder_map<
  336. typename ::boost::type_erasure::detail::normalize_concept_impl<
  337. Concept
  338. >::type::second
  339. >::type,
  340. class Out = ::boost::mpl::set0<>
  341. >
  342. struct collect_concepts
  343. {
  344. typedef typename ::boost::type_erasure::detail::rebind_placeholders<
  345. Concept,
  346. ::boost::type_erasure::detail::substitution_map<Map>
  347. >::type transformed;
  348. typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
  349. ::boost::mpl::fold<Concept, Out, collect_concepts< ::boost::mpl::_2, Map, ::boost::mpl::_1> >,
  350. ::boost::mpl::identity<Out>
  351. >::type type1;
  352. typedef typename ::boost::mpl::eval_if<
  353. ::boost::is_same<transformed, void>,
  354. ::boost::mpl::identity<type1>,
  355. ::boost::mpl::insert<
  356. type1,
  357. transformed
  358. >
  359. >::type type;
  360. };
  361. #else
  362. template<bool>
  363. struct resolve_same_type_impl;
  364. template<class M, class T>
  365. using resolve_same_type_t =
  366. typename ::boost::type_erasure::detail::resolve_same_type_impl<
  367. (::boost::mp11::mp_map_contains<M, T>::value)
  368. >::template apply<M, T>;
  369. template<>
  370. struct resolve_same_type_impl<true>
  371. {
  372. template<class M, class T>
  373. using apply = ::boost::type_erasure::detail::resolve_same_type_t<
  374. M,
  375. ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<M, T> >
  376. >;
  377. };
  378. template<>
  379. struct resolve_same_type_impl<false>
  380. {
  381. template<class M, class T>
  382. using apply = T;
  383. };
  384. // given a partial substitution map from same_type,
  385. // resolves a placeholder as far as possible.
  386. template<class M, class T>
  387. using resolve_same_type = ::boost::mpl::identity< ::boost::type_erasure::detail::resolve_same_type_t<M, T> >;
  388. // M is a map of placeholder substitutions
  389. template<bool>
  390. struct normalize_placeholder_impl;
  391. template<class M, class T>
  392. using normalize_placeholder_t =
  393. typename ::boost::type_erasure::detail::normalize_placeholder_impl<
  394. ::boost::mp11::mp_map_contains<M, T>::value
  395. >::template apply<M, T>;
  396. template<>
  397. struct normalize_placeholder_impl<true>
  398. {
  399. template<class M, class T>
  400. using apply = ::boost::type_erasure::detail::normalize_placeholder_t<
  401. M,
  402. typename ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<M, T> >
  403. >;
  404. };
  405. template<class T>
  406. struct normalize_deduced_impl
  407. {
  408. template<class Map>
  409. using apply = T;
  410. };
  411. template<template<class...> class F, class... T>
  412. struct normalize_deduced_impl< ::boost::type_erasure::deduced<F<T...> > >
  413. {
  414. template<class Map>
  415. using apply = typename ::boost::type_erasure::deduced<F<normalize_placeholder_t<Map, T>...> >::type;
  416. };
  417. template<>
  418. struct normalize_placeholder_impl<false>
  419. {
  420. template<class M, class T>
  421. using apply = typename ::boost::type_erasure::detail::normalize_deduced_impl<T>::template apply<M>;
  422. };
  423. template<class Map, class T>
  424. using normalize_placeholder = ::boost::mpl::identity< ::boost::type_erasure::detail::normalize_placeholder_t<Map, T> >;
  425. // Takes a mpl::map of placeholder substitutions and
  426. // fully resolves it. i.e. a -> b, b -> c, becomes
  427. // a -> c, b -> c. Also resolves deduced placeholders
  428. // whose arguments are all resolved.
  429. template<class M>
  430. struct create_placeholder_map
  431. {
  432. template<class P>
  433. using transform_one = ::boost::mpl::pair<
  434. typename ::boost::mpl::first<P>::type,
  435. ::boost::type_erasure::detail::normalize_placeholder_t<
  436. M,
  437. typename ::boost::mpl::second<P>::type
  438. >
  439. >;
  440. typedef ::boost::mp11::mp_transform<
  441. transform_one,
  442. M
  443. > type;
  444. };
  445. template<class M>
  446. using create_placeholder_map_t = typename ::boost::type_erasure::detail::create_placeholder_map<M>::type;
  447. template<class Bindings, class P, class Out, class Sub>
  448. struct convert_deduced
  449. {
  450. typedef ::boost::type_erasure::detail::rebind_placeholders_in_argument_t<
  451. typename P::first,
  452. Bindings
  453. > result1;
  454. typedef ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<Sub, result1> > result;
  455. typedef ::boost::mp11::mp_map_insert<Out, ::boost::mpl::pair<typename P::second, result> > type;
  456. BOOST_MPL_ASSERT((boost::is_same< ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<type, typename P::second> >, result>));
  457. };
  458. template<class Bindings, class Sub>
  459. struct convert_deduced_f
  460. {
  461. template<class Out, class P>
  462. using apply = typename ::boost::type_erasure::detail::convert_deduced<Bindings, P, Out, Sub>::type;
  463. };
  464. template<class Bindings, class M, class Sub>
  465. using convert_deductions_t =
  466. ::boost::mp11::mp_fold<
  467. M,
  468. ::boost::type_erasure::detail::make_mp_list<Bindings>,
  469. ::boost::type_erasure::detail::convert_deduced_f<Bindings, Sub>::template apply
  470. >;
  471. template<class Bindings, class M, class Sub>
  472. using convert_deductions = ::boost::mpl::identity< ::boost::type_erasure::detail::convert_deductions_t<Bindings, M, Sub> >;
  473. template<class Bindings, class P, class Out>
  474. struct add_deduced
  475. {
  476. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  477. typename P::first,
  478. Bindings
  479. >::type result;
  480. typedef ::boost::mp11::mp_map_insert<Out, ::boost::mpl::pair<typename P::second, result> > type;
  481. BOOST_MPL_ASSERT((boost::is_same< ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<type, typename P::second> >, result>));
  482. };
  483. template<class Bindings>
  484. struct add_deduced_f
  485. {
  486. template<class Out, class P>
  487. using apply = typename ::boost::type_erasure::detail::add_deduced<Bindings, P, Out>::type;
  488. };
  489. template<class Bindings, class M>
  490. using add_deductions_t =
  491. ::boost::mp11::mp_fold<
  492. M,
  493. ::boost::type_erasure::detail::make_mp_list<Bindings>,
  494. ::boost::type_erasure::detail::add_deduced_f<
  495. ::boost::type_erasure::detail::make_mp_list<Bindings>
  496. >::template apply
  497. >;
  498. template<class Bindings, class M>
  499. using add_deductions = ::boost::mpl::identity< ::boost::type_erasure::detail::add_deductions_t<Bindings, M> >;
  500. // Fold Op for normalize_concept_impl
  501. template<class T>
  502. struct insert_concept_impl
  503. {
  504. template<class Out>
  505. using apply =
  506. ::boost::mpl::pair<
  507. ::boost::mp11::mp_set_push_back<typename Out::first, T>,
  508. typename Out::second
  509. >;
  510. };
  511. template<class Map, class T>
  512. using mpl_insert = typename ::boost::mpl::insert<Map, T>::type;
  513. template<class T1, class T2, class Out>
  514. using insert_concept_same_type =
  515. ::boost::mpl::pair<
  516. typename Out::first,
  517. typename ::boost::type_erasure::detail::eval_if<
  518. ::boost::is_same<T1, T2>::value,
  519. ::boost::type_erasure::detail::first,
  520. ::boost::mp11::mp_map_insert, // FIXME: is this supposed to be a replace?
  521. typename Out::second,
  522. typename ::boost::type_erasure::detail::select_pair<
  523. T1,
  524. T2
  525. >::type
  526. >
  527. >;
  528. template<class T, class U>
  529. struct insert_concept_impl< ::boost::type_erasure::same_type<T, U> >
  530. {
  531. template<class Out>
  532. using apply = ::boost::type_erasure::detail::insert_concept_same_type<
  533. ::boost::type_erasure::detail::resolve_same_type_t<
  534. typename Out::second,
  535. T
  536. >,
  537. ::boost::type_erasure::detail::resolve_same_type_t<
  538. typename Out::second,
  539. U
  540. >,
  541. Out
  542. >;
  543. };
  544. template<bool>
  545. struct normalize_concept_impl_test;
  546. template<class Out, class Concept>
  547. using normalize_concept_impl_f =
  548. typename ::boost::type_erasure::detail::normalize_concept_impl_test<
  549. ::boost::mpl::is_sequence<Concept>::value
  550. >::template apply<Out, Concept>;
  551. template<>
  552. struct normalize_concept_impl_test<true>
  553. {
  554. template<class Out, class Concept>
  555. using apply =
  556. ::boost::mp11::mp_fold<
  557. ::boost::type_erasure::detail::make_mp_list<Concept>,
  558. Out,
  559. ::boost::type_erasure::detail::normalize_concept_impl_f
  560. >;
  561. };
  562. template<>
  563. struct normalize_concept_impl_test<false>
  564. {
  565. template<class Out, class Concept>
  566. using apply = typename ::boost::type_erasure::detail::insert_concept_impl<Concept>::template apply<Out>;
  567. };
  568. template<class Concept>
  569. using normalize_concept_impl_t =
  570. ::boost::type_erasure::detail::normalize_concept_impl_f<
  571. ::boost::mpl::pair< ::boost::mp11::mp_list<>, ::boost::mp11::mp_list<> >,
  572. Concept
  573. >;
  574. template<class Concept>
  575. using normalize_concept_impl = ::boost::mpl::identity< ::boost::type_erasure::detail::normalize_concept_impl_t<Concept> >;
  576. template<class S, class T>
  577. using get_all_placeholders_impl = typename ::boost::type_erasure::detail::get_placeholders<T, S>::type;
  578. template<class Seq>
  579. using get_all_placeholders =
  580. ::boost::mp11::mp_fold<
  581. Seq,
  582. ::boost::mp11::mp_list<>,
  583. ::boost::type_erasure::detail::get_all_placeholders_impl
  584. >;
  585. template<class T>
  586. using make_identity_pair = ::boost::mpl::pair<T, T>;
  587. template<class Concept>
  588. using make_identity_placeholder_map =
  589. ::boost::mp11::mp_transform<
  590. ::boost::type_erasure::detail::make_identity_pair,
  591. ::boost::type_erasure::detail::get_all_placeholders<
  592. typename normalize_concept_impl_t<Concept>::first
  593. >
  594. >;
  595. template<class S, class T>
  596. using append_type_info = ::boost::mp11::mp_set_push_back<
  597. S,
  598. ::boost::type_erasure::typeid_<T>
  599. >;
  600. template<class Seq>
  601. using add_typeinfo_t =
  602. ::boost::mp11::mp_fold<
  603. get_all_placeholders<Seq>,
  604. Seq,
  605. ::boost::type_erasure::detail::append_type_info
  606. >;
  607. // Seq should be a flattened mp_list sequence of leaf concepts.
  608. // adds typeid_<P> for every placeholder used.
  609. template<class Seq>
  610. using add_typeinfo = ::boost::mpl::identity<add_typeinfo_t<Seq> >;
  611. template<class Substitutions>
  612. struct normalize_concept_substitute_f
  613. {
  614. template<class Set, class Concept>
  615. using apply = ::boost::mp11::mp_set_push_back<Set,
  616. typename ::boost::type_erasure::detail::rebind_placeholders<
  617. Concept,
  618. Substitutions
  619. >::type
  620. >;
  621. };
  622. template<class Concept, class Pair>
  623. using normalize_concept_adjustments =
  624. ::boost::type_erasure::detail::eval_if<
  625. ::boost::type_erasure::is_relaxed<Concept>::value,
  626. ::boost::type_erasure::detail::add_typeinfo_t,
  627. ::boost::type_erasure::detail::first,
  628. ::boost::mp11::mp_fold<
  629. typename Pair::first,
  630. ::boost::mp11::mp_list<>,
  631. ::boost::type_erasure::detail::normalize_concept_substitute_f<
  632. ::boost::type_erasure::detail::create_placeholder_map_t<
  633. typename Pair::second
  634. >
  635. >::template apply
  636. >
  637. >;
  638. template<class Concept>
  639. using get_placeholder_normalization_map_t =
  640. ::boost::type_erasure::detail::create_placeholder_map_t<
  641. typename normalize_concept_impl_t<Concept>::second
  642. >;
  643. template<class Concept>
  644. using get_placeholder_normalization_map =
  645. ::boost::type_erasure::detail::create_placeholder_map<
  646. typename normalize_concept_impl_t<Concept>::second
  647. >;
  648. // Flattens a Concept to an mpl::vector of primitive
  649. // concepts. Resolves same_type and deduced placeholders.
  650. template<class Concept>
  651. using normalize_concept_t =
  652. ::boost::type_erasure::detail::normalize_concept_adjustments<
  653. Concept,
  654. boost::type_erasure::detail::normalize_concept_impl_t<Concept>
  655. >;
  656. template<class Concept>
  657. using normalize_concept = ::boost::mpl::identity< ::boost::type_erasure::detail::normalize_concept_t<Concept> >;
  658. template<class Map>
  659. struct collect_concepts_f;
  660. template<class Out, class Concept, class Map>
  661. using collect_concepts_recursive = ::boost::mp11::mp_fold<
  662. ::boost::type_erasure::detail::make_mp_list<Concept>,
  663. Out,
  664. ::boost::type_erasure::detail::collect_concepts_f<Map>::template apply
  665. >;
  666. template<class Concept, class Map, class Out, class Transformed>
  667. using collect_concepts_impl =
  668. ::boost::type_erasure::detail::eval_if< ::boost::is_same<Transformed, void>::value,
  669. ::boost::type_erasure::detail::first,
  670. ::boost::mp11::mp_set_push_front,
  671. ::boost::type_erasure::detail::eval_if< ::boost::mpl::is_sequence<Concept>::value,
  672. ::boost::type_erasure::detail::collect_concepts_recursive,
  673. ::boost::type_erasure::detail::first,
  674. Out,
  675. Concept,
  676. Map
  677. >,
  678. Transformed
  679. >;
  680. template<class Concept,
  681. class Map = ::boost::type_erasure::detail::create_placeholder_map_t<
  682. typename ::boost::type_erasure::detail::normalize_concept_impl_t<
  683. Concept
  684. >::second
  685. >,
  686. class Out = ::boost::mp11::mp_list<>
  687. >
  688. using collect_concepts_t =
  689. collect_concepts_impl<Concept, Map, Out,
  690. typename ::boost::type_erasure::detail::rebind_placeholders<
  691. Concept,
  692. Map
  693. >::type
  694. >;
  695. template<class Map>
  696. struct collect_concepts_f
  697. {
  698. template<class Out, class Concept>
  699. using apply = ::boost::type_erasure::detail::collect_concepts_t<Concept, Map, Out>;
  700. };
  701. // Returns an MPL sequence containing all the concepts
  702. // in Concept. If Concept is considered as a DAG,
  703. // the result will be sorted topologically.
  704. template<class Concept>
  705. using collect_concepts = ::boost::mpl::identity<
  706. ::boost::type_erasure::detail::collect_concepts_t<Concept> >;
  707. #endif
  708. }
  709. }
  710. }
  711. #endif