/src/contrib/boost/spirit/home/phoenix/stl/container/container.hpp

http://pythonocc.googlecode.com/ · C++ Header · 706 lines · 518 code · 73 blank · 115 comment · 1 complexity · 56b7b3364856797892079a0131716502 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2004 Angus Leeming
  3. Copyright (c) 2004 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef PHOENIX_STL_CONTAINER_CONTAINER_HPP
  8. #define PHOENIX_STL_CONTAINER_CONTAINER_HPP
  9. #include <boost/spirit/home/phoenix/stl/container/detail/container.hpp>
  10. #include <boost/spirit/home/phoenix/function/function.hpp>
  11. #include <boost/mpl/and.hpp>
  12. #include <boost/mpl/not.hpp>
  13. #include <boost/mpl/or.hpp>
  14. #include <boost/type_traits/is_const.hpp>
  15. namespace boost { namespace phoenix
  16. {
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //
  19. // STL container member functions
  20. //
  21. // Lazy functions for STL container member functions
  22. //
  23. // These functions provide a mechanism for the lazy evaluation of the
  24. // public member functions of the STL containers. For an overview of
  25. // what is meant by 'lazy evaluation', see the comments in operators.hpp
  26. // and functions.hpp.
  27. //
  28. // Lazy functions are provided for all of the member functions of the
  29. // following containers:
  30. //
  31. // deque - list - map - multimap - vector.
  32. //
  33. // Indeed, should *your* class have member functions with the same names
  34. // and signatures as those listed below, then it will automatically be
  35. // supported. To summarize, lazy functions are provided for member
  36. // functions:
  37. //
  38. // assign - at - back - begin - capacity - clear - empty - end -
  39. // erase - front - get_allocator - insert - key_comp - max_size -
  40. // pop_back - pop_front - push_back - push_front - rbegin - rend -
  41. // reserve - resize . size - splice - value_comp.
  42. //
  43. // The lazy functions' names are the same as the corresponding member
  44. // function. Sample usage:
  45. //
  46. // "Normal" version "Lazy" version
  47. // ---------------- --------------
  48. // my_vector.at(5) phoenix::at(arg1, 5)
  49. // my_list.size() phoenix::size(arg1)
  50. // my_vector1.swap(my_vector2) phoenix::swap(arg1, arg2)
  51. //
  52. // Notice that member functions with names that clash with a
  53. // function in stl algorithms are absent. This will be provided
  54. // in Phoenix's algorithm module.
  55. //
  56. // No support is provided here for lazy versions of operator+=,
  57. // operator[] etc. Such operators are not specific to STL containers and
  58. // lazy versions can therefore be found in operators.hpp.
  59. //
  60. ///////////////////////////////////////////////////////////////////////////////
  61. ///////////////////////////////////////////////////////////////////////////////
  62. //
  63. // Lazy member function implementaions.
  64. //
  65. // The structs below provide the guts of the implementation. Thereafter,
  66. // the corresponding lazy function itself is simply:
  67. //
  68. // function<stl::assign> const assign = stl::assign();
  69. //
  70. // The structs provide a nested "result" class template whose
  71. // "type" typedef enables the lazy function to ascertain the type
  72. // to be returned when it is invoked.
  73. //
  74. // They also provide operator() member functions with signatures
  75. // corresponding to those of the underlying member function of
  76. // the STL container.
  77. //
  78. ///////////////////////////////////////////////////////////////////////////////
  79. namespace stl
  80. {
  81. struct assign
  82. {
  83. template <
  84. typename C
  85. , typename Arg1 = fusion::void_
  86. , typename Arg2 = fusion::void_
  87. , typename Arg3 = fusion::void_
  88. >
  89. struct result
  90. {
  91. typedef typename add_reference<C>::type type;
  92. };
  93. template <typename C, typename Arg1>
  94. C& operator()(C& c, Arg1 const& arg1) const
  95. {
  96. c.assign(arg1);
  97. return c;
  98. }
  99. template <typename C, typename Arg1, typename Arg2>
  100. C& operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
  101. {
  102. c.assign(arg1, arg2);
  103. return c;
  104. }
  105. template <typename C, typename Arg1, typename Arg2, typename Arg3>
  106. C& operator()(
  107. C& c
  108. , Arg1 const& arg1
  109. , Arg2 const& arg2
  110. , Arg3 const& arg3) const
  111. {
  112. return c.assign(arg1, arg2, arg3);
  113. }
  114. };
  115. struct at
  116. {
  117. template <typename C, typename Index>
  118. struct result
  119. {
  120. typedef typename const_qualified_reference_of<C>::type type;
  121. };
  122. template <typename C, typename Index>
  123. typename result<C, Index>::type
  124. operator()(C& c, Index const& i) const
  125. {
  126. return c.at(i);
  127. }
  128. };
  129. struct back
  130. {
  131. template <typename C>
  132. struct result
  133. {
  134. typedef
  135. typename const_qualified_reference_of<C>::type
  136. type;
  137. };
  138. template <typename C>
  139. typename result<C>::type
  140. operator()(C& c) const
  141. {
  142. return c.back();
  143. }
  144. };
  145. struct begin
  146. {
  147. template <typename C>
  148. struct result
  149. {
  150. typedef typename const_qualified_iterator_of<C>::type type;
  151. };
  152. template <typename C>
  153. typename result<C>::type
  154. operator()(C& c) const
  155. {
  156. return c.begin();
  157. }
  158. };
  159. struct capacity
  160. {
  161. template <typename C>
  162. struct result
  163. {
  164. typedef typename size_type_of<C>::type type;
  165. };
  166. template <typename C>
  167. typename result<C>::type
  168. operator()(C const& c) const
  169. {
  170. return c.capacity();
  171. }
  172. };
  173. struct clear
  174. {
  175. template <typename C>
  176. struct result
  177. {
  178. typedef void type;
  179. };
  180. template <typename C>
  181. void operator()(C& c) const
  182. {
  183. return c.clear();
  184. }
  185. };
  186. struct empty
  187. {
  188. template <typename C>
  189. struct result
  190. {
  191. typedef bool type;
  192. };
  193. template <typename C>
  194. bool operator()(C const& c) const
  195. {
  196. return c.empty();
  197. }
  198. };
  199. struct end
  200. {
  201. template <typename C>
  202. struct result
  203. {
  204. typedef typename const_qualified_iterator_of<C>::type type;
  205. };
  206. template <typename C>
  207. typename result<C>::type
  208. operator()(C& c) const
  209. {
  210. return c.end();
  211. }
  212. };
  213. struct erase
  214. {
  215. // This mouthful can differentiate between the generic erase
  216. // functions (Container == std::deque, std::list, std::vector) and
  217. // that specific to the two map-types, std::map and std::multimap.
  218. //
  219. // where C is a std::deque, std::list, std::vector:
  220. //
  221. // 1) iterator C::erase(iterator where);
  222. // 2) iterator C::erase(iterator first, iterator last);
  223. //
  224. // where M is a std::map or std::multimap:
  225. //
  226. // 3) size_type M::erase(const Key& keyval);
  227. // 4) void M::erase(iterator where);
  228. // 5) void M::erase(iterator first, iterator last);
  229. template <typename C, typename Arg1, typename Arg2 = fusion::void_>
  230. struct result
  231. {
  232. // BOOST_MSVC #if branch here in map_erase_result non-
  233. // standard behavior. The return type should be void but
  234. // VC7.1 prefers to return iterator_of<C>. As a result,
  235. // VC7.1 complains of error C2562:
  236. // boost::phoenix::stl::erase::operator() 'void' function
  237. // returning a value. Oh well... :*
  238. typedef
  239. boost::mpl::eval_if<
  240. boost::is_same<Arg1, typename iterator_of<C>::type>
  241. #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1500)
  242. , iterator_of<C>
  243. #else
  244. , boost::mpl::identity<void>
  245. #endif
  246. , size_type_of<C>
  247. >
  248. map_erase_result;
  249. typedef typename
  250. boost::mpl::eval_if<
  251. has_mapped_type<C>
  252. , map_erase_result
  253. , iterator_of<C>
  254. >::type
  255. type;
  256. };
  257. template <typename C, typename Arg1>
  258. typename result<C, Arg1>::type
  259. operator()(C& c, Arg1 const& arg1) const
  260. {
  261. return c.erase(arg1);
  262. }
  263. template <typename C, typename Arg1, typename Arg2>
  264. typename result<C, Arg1, Arg2>::type
  265. operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
  266. {
  267. return c.erase(arg1, arg2);
  268. }
  269. };
  270. struct front
  271. {
  272. template <typename C>
  273. struct result
  274. {
  275. typedef typename const_qualified_reference_of<C>::type type;
  276. };
  277. template <typename C>
  278. typename result<C>::type
  279. operator()(C& c) const
  280. {
  281. return c.front();
  282. }
  283. };
  284. struct get_allocator
  285. {
  286. template <typename C>
  287. struct result
  288. {
  289. typedef typename allocator_type_of<C>::type type;
  290. };
  291. template <typename C>
  292. typename result<C>::type
  293. operator()(C const& c) const
  294. {
  295. return c.get_allocator();
  296. }
  297. };
  298. struct insert
  299. {
  300. // This mouthful can differentiate between the generic insert
  301. // functions (Container == deque, list, vector) and those
  302. // specific to the two map-types, std::map and std::multimap.
  303. //
  304. // where C is a std::deque, std::list, std::vector:
  305. //
  306. // 1) iterator C::insert(iterator where, value_type value);
  307. // 2) void C::insert(
  308. // iterator where, size_type count, value_type value);
  309. // 3) template <typename Iter>
  310. // void C::insert(iterator where, Iter first, Iter last);
  311. //
  312. // where M is a std::map and MM is a std::multimap:
  313. //
  314. // 4) pair<iterator, bool> M::insert(value_type const&);
  315. // 5) iterator MM::insert(value_type const&);
  316. //
  317. // where M is a std::map or std::multimap:
  318. //
  319. // 6) template <typename Iter>
  320. // void M::insert(Iter first, Iter last);
  321. template <
  322. typename C
  323. , typename Arg1
  324. , typename Arg2 = fusion::void_
  325. , typename Arg3 = fusion::void_
  326. >
  327. class result
  328. {
  329. struct pair_iterator_bool
  330. {
  331. typedef typename std::pair<typename C::iterator, bool> type;
  332. };
  333. typedef
  334. boost::mpl::eval_if<
  335. map_insert_returns_pair<C>
  336. , pair_iterator_bool
  337. , iterator_of<C>
  338. >
  339. choice_1;
  340. typedef
  341. boost::mpl::eval_if<
  342. boost::mpl::and_<
  343. boost::is_same<Arg3, fusion::void_>
  344. , boost::mpl::not_<boost::is_same<Arg1, Arg2> > >
  345. , iterator_of<C>
  346. , boost::mpl::identity<void>
  347. >
  348. choice_2;
  349. public:
  350. typedef typename
  351. boost::mpl::eval_if<
  352. boost::is_same<Arg2, fusion::void_>
  353. , choice_1
  354. , choice_2
  355. >::type
  356. type;
  357. };
  358. template <typename C, typename Arg1>
  359. typename result<C, Arg1>::type
  360. operator()(C& c, Arg1 const& arg1) const
  361. {
  362. return c.insert(arg1);
  363. }
  364. template <typename C, typename Arg1, typename Arg2>
  365. typename result<C, Arg1, Arg2>::type
  366. operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
  367. {
  368. return c.insert(arg1, arg2);
  369. }
  370. template <typename C, typename Arg1, typename Arg2, typename Arg3>
  371. typename result<C, Arg1, Arg2, Arg3>::type
  372. operator()(
  373. C& c, Arg1 const& arg1, Arg2 const& arg2, Arg3 const& arg3) const
  374. {
  375. return c.insert(arg1, arg2, arg3);
  376. }
  377. };
  378. struct key_comp
  379. {
  380. template <typename C>
  381. struct result
  382. {
  383. typedef typename key_compare_of<C>::type type;
  384. };
  385. template <typename C>
  386. typename result<C>::type
  387. operator()(C const& c) const
  388. {
  389. return c.key_comp();
  390. }
  391. };
  392. struct max_size
  393. {
  394. template <typename C>
  395. struct result
  396. {
  397. typedef typename size_type_of<C>::type type;
  398. };
  399. template <typename C>
  400. typename result<C>::type
  401. operator()(C const& c) const
  402. {
  403. return c.max_size();
  404. }
  405. };
  406. struct pop_back
  407. {
  408. template <typename C>
  409. struct result
  410. {
  411. typedef void type;
  412. };
  413. template <typename C>
  414. void operator()(C& c) const
  415. {
  416. return c.pop_back();
  417. }
  418. };
  419. struct pop_front
  420. {
  421. template <typename C>
  422. struct result
  423. {
  424. typedef void type;
  425. };
  426. template <typename C>
  427. void operator()(C& c) const
  428. {
  429. return c.pop_front();
  430. }
  431. };
  432. struct push_back
  433. {
  434. template <typename C, typename Arg>
  435. struct result
  436. {
  437. typedef void type;
  438. };
  439. template <typename C, typename Arg>
  440. void operator()(C& c, Arg const& data) const
  441. {
  442. return c.push_back(data);
  443. }
  444. };
  445. struct push_front
  446. {
  447. template <typename C, typename Arg>
  448. struct result
  449. {
  450. typedef void type;
  451. };
  452. template <typename C, typename Arg>
  453. void operator()(C& c, Arg const& data) const
  454. {
  455. return c.push_front(data);
  456. }
  457. };
  458. struct rbegin
  459. {
  460. template <typename C>
  461. struct result
  462. {
  463. typedef typename
  464. const_qualified_reverse_iterator_of<C>::type
  465. type;
  466. };
  467. template <typename C>
  468. typename result<C>::type
  469. operator()(C& c) const
  470. {
  471. return c.rbegin();
  472. }
  473. };
  474. struct rend
  475. {
  476. template <typename C>
  477. struct result
  478. {
  479. typedef typename
  480. const_qualified_reverse_iterator_of<C>::type
  481. type;
  482. };
  483. template <typename C>
  484. typename result<C>::type
  485. operator()(C& c) const
  486. {
  487. return c.rend();
  488. }
  489. };
  490. struct reserve
  491. {
  492. template <typename C, typename Arg>
  493. struct result
  494. {
  495. typedef void type;
  496. };
  497. template <typename C, typename Arg>
  498. void operator()(C& c, Arg const& count) const
  499. {
  500. return c.reserve(count);
  501. }
  502. };
  503. struct resize
  504. {
  505. template <typename C, typename Arg1, typename Arg2 = fusion::void_>
  506. struct result
  507. {
  508. typedef void type;
  509. };
  510. template <typename C, typename Arg1>
  511. void operator()(C& c, Arg1 const& arg1) const
  512. {
  513. return c.resize(arg1);
  514. }
  515. template <typename C, typename Arg1, typename Arg2>
  516. void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
  517. {
  518. return c.resize(arg1, arg2);
  519. }
  520. };
  521. struct size
  522. {
  523. template <typename C>
  524. struct result
  525. {
  526. typedef typename size_type_of<C>::type type;
  527. };
  528. template <typename C>
  529. typename result<C>::type
  530. operator()(C const& c) const
  531. {
  532. return c.size();
  533. }
  534. };
  535. struct splice
  536. {
  537. template <
  538. typename C
  539. , typename Arg1
  540. , typename Arg2
  541. , typename Arg3 = fusion::void_
  542. , typename Arg4 = fusion::void_
  543. >
  544. struct result
  545. {
  546. typedef void type;
  547. };
  548. template <typename C, typename Arg1, typename Arg2>
  549. void operator()(C& c, Arg1 const& arg1, Arg2& arg2) const
  550. {
  551. c.splice(arg1, arg2);
  552. }
  553. template <
  554. typename C
  555. , typename Arg1
  556. , typename Arg2
  557. , typename Arg3
  558. >
  559. void operator()(
  560. C& c
  561. , Arg1 const& arg1
  562. , Arg2& arg2
  563. , Arg3 const& arg3
  564. ) const
  565. {
  566. c.splice(arg1, arg2, arg3);
  567. }
  568. template <
  569. typename C
  570. , typename Arg1
  571. , typename Arg2
  572. , typename Arg3
  573. , typename Arg4
  574. >
  575. void operator()(
  576. C& c
  577. , Arg1 const& arg1
  578. , Arg2& arg2
  579. , Arg3 const& arg3
  580. , Arg4 const& arg4
  581. ) const
  582. {
  583. c.splice(arg1, arg2, arg3, arg4);
  584. }
  585. };
  586. struct value_comp
  587. {
  588. template <typename C>
  589. struct result
  590. {
  591. typedef typename value_compare_of<C>::type type;
  592. };
  593. template <typename C>
  594. typename result<C>::type
  595. operator()(C const& c) const
  596. {
  597. return c.value_comp();
  598. }
  599. };
  600. } // namespace stl
  601. ///////////////////////////////////////////////////////////////////////////////
  602. //
  603. // The lazy functions themselves.
  604. //
  605. ///////////////////////////////////////////////////////////////////////////////
  606. function<stl::assign> const assign = stl::assign();
  607. function<stl::at> const at = stl::at();
  608. function<stl::back> const back = stl::back();
  609. function<stl::begin> const begin = stl::begin();
  610. function<stl::capacity> const capacity = stl::capacity();
  611. function<stl::clear> const clear = stl::clear();
  612. function<stl::empty> const empty = stl::empty();
  613. function<stl::end> const end = stl::end();
  614. function<stl::erase> const erase = stl::erase();
  615. function<stl::front> const front = stl::front();
  616. function<stl::get_allocator> const get_allocator = stl::get_allocator();
  617. function<stl::insert> const insert = stl::insert();
  618. function<stl::key_comp> const key_comp = stl::key_comp();
  619. function<stl::max_size> const max_size = stl::max_size();
  620. function<stl::pop_back> const pop_back = stl::pop_back();
  621. function<stl::pop_front> const pop_front = stl::pop_front();
  622. function<stl::push_back> const push_back = stl::push_back();
  623. function<stl::push_front> const push_front = stl::push_front();
  624. function<stl::rbegin> const rbegin = stl::rbegin();
  625. function<stl::rend> const rend = stl::rend();
  626. function<stl::reserve> const reserve = stl::reserve();
  627. function<stl::resize> const resize = stl::resize();
  628. function<stl::size> const size = stl::size();
  629. function<stl::splice> const splice = stl::splice();
  630. function<stl::value_comp> const value_comp = stl::value_comp();
  631. }} // namespace boost::phoenix
  632. #endif // PHOENIX_STL_CONTAINERS_HPP