string.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. // Copyright Eric Niebler 2009
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/mpl for documentation.
  8. // $Id: string.cpp 49240 2009-04-01 09:21:07Z eric_niebler $
  9. // $Date: 2009-04-01 02:21:07 -0700 (Wed, 1 Apr 2009) $
  10. // $Revision: 49240 $
  11. #include <string>
  12. #include <cstring>
  13. #include <iostream>
  14. #include <boost/mpl/string.hpp>
  15. #include <boost/mpl/at.hpp>
  16. #include <boost/mpl/back.hpp>
  17. #include <boost/mpl/empty.hpp>
  18. #include <boost/mpl/front.hpp>
  19. #include <boost/mpl/erase.hpp>
  20. #include <boost/mpl/insert.hpp>
  21. #include <boost/mpl/advance.hpp>
  22. #include <boost/mpl/for_each.hpp>
  23. #include <boost/mpl/vector_c.hpp>
  24. #include <boost/mpl/pop_back.hpp>
  25. #include <boost/mpl/pop_front.hpp>
  26. #include <boost/mpl/push_back.hpp>
  27. #include <boost/mpl/push_front.hpp>
  28. #include <boost/type_traits/is_same.hpp>
  29. #include <boost/detail/lightweight_test.hpp>
  30. namespace mpl = boost::mpl;
  31. // Accept a string as a template parameter!
  32. template<char const *sz>
  33. struct greeting
  34. {
  35. std::string say_hello() const
  36. {
  37. return sz;
  38. }
  39. };
  40. struct push_char
  41. {
  42. push_char(std::string &str)
  43. : str_(&str)
  44. {}
  45. void operator()(char ch) const
  46. {
  47. this->str_->push_back(ch);
  48. }
  49. std::string *str_;
  50. };
  51. int main()
  52. {
  53. // Test mpl::size of strings
  54. {
  55. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
  56. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> full;
  57. BOOST_MPL_ASSERT_RELATION(0, ==, (mpl::size<mpl::string<> >::value));
  58. BOOST_MPL_ASSERT_RELATION(1, ==, (mpl::size<mpl::string<'a'> >::value));
  59. BOOST_MPL_ASSERT_RELATION(2, ==, (mpl::size<mpl::string<'ab'> >::value));
  60. BOOST_MPL_ASSERT_RELATION(2, ==, (mpl::size<mpl::string<'a','b'> >::value));
  61. BOOST_MPL_ASSERT_RELATION(4, ==, (mpl::size<mpl::string<'abcd'> >::value));
  62. BOOST_MPL_ASSERT_RELATION(5, ==, (mpl::size<mpl::string<'abcd','e'> >::value));
  63. BOOST_MPL_ASSERT_RELATION(31, ==, (mpl::size<almost_full>::value));
  64. BOOST_MPL_ASSERT_RELATION(32, ==, (mpl::size<full>::value));
  65. }
  66. // Test mpl::begin and mpl::end with strings
  67. {
  68. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
  69. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> full;
  70. BOOST_MPL_ASSERT((
  71. boost::is_same<
  72. mpl::begin<mpl::string<> >::type
  73. , mpl::end<mpl::string<> >::type
  74. >
  75. ));
  76. BOOST_MPL_ASSERT((
  77. boost::is_same<
  78. mpl::begin<mpl::string<'a'> >::type
  79. , mpl::string_iterator<mpl::string<'a'>, 0, 0>
  80. >
  81. ));
  82. BOOST_MPL_ASSERT((
  83. boost::is_same<
  84. mpl::end<mpl::string<'a'> >::type
  85. , mpl::string_iterator<mpl::string<'a'>, 1, 0>
  86. >
  87. ));
  88. BOOST_MPL_ASSERT((
  89. boost::is_same<
  90. mpl::begin<almost_full>::type
  91. , mpl::string_iterator<almost_full, 0, 0>
  92. >
  93. ));
  94. BOOST_MPL_ASSERT((
  95. boost::is_same<
  96. mpl::end<almost_full>::type
  97. , mpl::string_iterator<almost_full, 8, 0>
  98. >
  99. ));
  100. BOOST_MPL_ASSERT((
  101. boost::is_same<
  102. mpl::begin<full>::type
  103. , mpl::string_iterator<full, 0, 0>
  104. >
  105. ));
  106. BOOST_MPL_ASSERT((
  107. boost::is_same<
  108. mpl::end<full>::type
  109. , mpl::string_iterator<full, 8, 0>
  110. >
  111. ));
  112. }
  113. // testing push_back
  114. {
  115. typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
  116. BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
  117. typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
  118. BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ab'> >));
  119. typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
  120. BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
  121. typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
  122. BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'abcd'> >));
  123. typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
  124. BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
  125. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
  126. typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
  127. BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >));
  128. }
  129. // Test mpl::next
  130. {
  131. typedef mpl::string<'a','bc','def','ghij'> s;
  132. typedef mpl::begin<s>::type i0;
  133. BOOST_MPL_ASSERT((boost::is_same<i0, mpl::string_iterator<s,0,0> >));
  134. typedef mpl::next<i0>::type i1;
  135. BOOST_MPL_ASSERT((boost::is_same<i1, mpl::string_iterator<s,1,0> >));
  136. typedef mpl::next<i1>::type i2;
  137. BOOST_MPL_ASSERT((boost::is_same<i2, mpl::string_iterator<s,1,1> >));
  138. typedef mpl::next<i2>::type i3;
  139. BOOST_MPL_ASSERT((boost::is_same<i3, mpl::string_iterator<s,2,0> >));
  140. typedef mpl::next<i3>::type i4;
  141. BOOST_MPL_ASSERT((boost::is_same<i4, mpl::string_iterator<s,2,1> >));
  142. typedef mpl::next<i4>::type i5;
  143. BOOST_MPL_ASSERT((boost::is_same<i5, mpl::string_iterator<s,2,2> >));
  144. typedef mpl::next<i5>::type i6;
  145. BOOST_MPL_ASSERT((boost::is_same<i6, mpl::string_iterator<s,3,0> >));
  146. typedef mpl::next<i6>::type i7;
  147. BOOST_MPL_ASSERT((boost::is_same<i7, mpl::string_iterator<s,3,1> >));
  148. typedef mpl::next<i7>::type i8;
  149. BOOST_MPL_ASSERT((boost::is_same<i8, mpl::string_iterator<s,3,2> >));
  150. typedef mpl::next<i8>::type i9;
  151. BOOST_MPL_ASSERT((boost::is_same<i9, mpl::string_iterator<s,3,3> >));
  152. typedef mpl::next<i9>::type i10;
  153. BOOST_MPL_ASSERT((boost::is_same<i10, mpl::string_iterator<s,4,0> >));
  154. BOOST_MPL_ASSERT((boost::is_same<i10, mpl::end<s>::type>));
  155. }
  156. // Test mpl::prior
  157. {
  158. typedef mpl::string<'a','bc','def','ghij'> s;
  159. typedef mpl::end<s>::type i10;
  160. BOOST_MPL_ASSERT((boost::is_same<i10, mpl::string_iterator<s,4,0> >));
  161. typedef mpl::prior<i10>::type i9;
  162. BOOST_MPL_ASSERT((boost::is_same<i9, mpl::string_iterator<s,3,3> >));
  163. typedef mpl::prior<i9>::type i8;
  164. BOOST_MPL_ASSERT((boost::is_same<i8, mpl::string_iterator<s,3,2> >));
  165. typedef mpl::prior<i8>::type i7;
  166. BOOST_MPL_ASSERT((boost::is_same<i7, mpl::string_iterator<s,3,1> >));
  167. typedef mpl::prior<i7>::type i6;
  168. BOOST_MPL_ASSERT((boost::is_same<i6, mpl::string_iterator<s,3,0> >));
  169. typedef mpl::prior<i6>::type i5;
  170. BOOST_MPL_ASSERT((boost::is_same<i5, mpl::string_iterator<s,2,2> >));
  171. typedef mpl::prior<i5>::type i4;
  172. BOOST_MPL_ASSERT((boost::is_same<i4, mpl::string_iterator<s,2,1> >));
  173. typedef mpl::prior<i4>::type i3;
  174. BOOST_MPL_ASSERT((boost::is_same<i3, mpl::string_iterator<s,2,0> >));
  175. typedef mpl::prior<i3>::type i2;
  176. BOOST_MPL_ASSERT((boost::is_same<i2, mpl::string_iterator<s,1,1> >));
  177. typedef mpl::prior<i2>::type i1;
  178. BOOST_MPL_ASSERT((boost::is_same<i1, mpl::string_iterator<s,1,0> >));
  179. typedef mpl::prior<i1>::type i0;
  180. BOOST_MPL_ASSERT((boost::is_same<i0, mpl::string_iterator<s,0,0> >));
  181. BOOST_MPL_ASSERT((boost::is_same<i0, mpl::begin<s>::type>));
  182. }
  183. // Test mpl::deref
  184. {
  185. typedef mpl::string<'a','bc','def','ghij'> s;
  186. typedef mpl::begin<s>::type i0;
  187. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i0>::type, mpl::char_<'a'> >));
  188. typedef mpl::next<i0>::type i1;
  189. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i1>::type, mpl::char_<'b'> >));
  190. typedef mpl::next<i1>::type i2;
  191. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i2>::type, mpl::char_<'c'> >));
  192. typedef mpl::next<i2>::type i3;
  193. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i3>::type, mpl::char_<'d'> >));
  194. typedef mpl::next<i3>::type i4;
  195. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i4>::type, mpl::char_<'e'> >));
  196. typedef mpl::next<i4>::type i5;
  197. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i5>::type, mpl::char_<'f'> >));
  198. typedef mpl::next<i5>::type i6;
  199. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i6>::type, mpl::char_<'g'> >));
  200. typedef mpl::next<i6>::type i7;
  201. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i7>::type, mpl::char_<'h'> >));
  202. typedef mpl::next<i7>::type i8;
  203. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i8>::type, mpl::char_<'i'> >));
  204. typedef mpl::next<i8>::type i9;
  205. BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i9>::type, mpl::char_<'j'> >));
  206. }
  207. // testing push_back
  208. {
  209. typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
  210. BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
  211. typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
  212. BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ab'> >));
  213. typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
  214. BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
  215. typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
  216. BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'abcd'> >));
  217. typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
  218. BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
  219. typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
  220. typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
  221. BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >));
  222. typedef mpl::string<'a','a','a','a','a','a','a','aaaa'> must_repack;
  223. typedef mpl::push_back<must_repack, mpl::char_<'X'> >::type t7;
  224. BOOST_MPL_ASSERT((boost::is_same<t7, mpl::string<'aaaa','aaaa','aaaX'> >));
  225. }
  226. BOOST_MPL_ASSERT((mpl::empty<mpl::string<> >));
  227. BOOST_MPL_ASSERT_NOT((mpl::empty<mpl::string<'hi!'> >));
  228. // testing push_front
  229. {
  230. typedef mpl::push_front<mpl::string<>, mpl::char_<'a'> >::type t1;
  231. BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
  232. typedef mpl::push_front<t1, mpl::char_<'b'> >::type t2;
  233. BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ba'> >));
  234. typedef mpl::push_front<t2, mpl::char_<'c'> >::type t3;
  235. BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'cba'> >));
  236. typedef mpl::push_front<t3, mpl::char_<'d'> >::type t4;
  237. BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'dcba'> >));
  238. typedef mpl::push_front<t4, mpl::char_<'e'> >::type t5;
  239. BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'e','dcba'> >));
  240. typedef mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> almost_full;
  241. typedef mpl::push_front<almost_full, mpl::char_<'X'> >::type t6;
  242. BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'Xaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >));
  243. typedef mpl::string<'aaaa','a','a','a','a','a','a','a'> must_repack;
  244. typedef mpl::push_front<must_repack, mpl::char_<'X'> >::type t7;
  245. BOOST_MPL_ASSERT((boost::is_same<t7, mpl::string<'Xaaa','aaaa','aaaa'> >));
  246. }
  247. // Test c_str<>
  248. BOOST_TEST(0 == std::strcmp(
  249. mpl::c_str<mpl::string<> >::value
  250. , ""
  251. ));
  252. BOOST_TEST(0 == std::strcmp(
  253. mpl::c_str<mpl::string<'Hell','o wo','rld!'> >::value
  254. , "Hell" "o wo" "rld!"
  255. ));
  256. BOOST_TEST(0 == std::strcmp(
  257. mpl::c_str<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >::value
  258. , "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaX"
  259. ));
  260. // test using a string as a template parameter
  261. greeting<mpl::c_str<mpl::string<'Hell','o wo','rld!'> >::value> g;
  262. BOOST_TEST("Hello world!" == g.say_hello());
  263. std::string result;
  264. mpl::for_each<mpl::string<'Hell','o wo','rld!'> >(push_char(result));
  265. BOOST_TEST("Hello world!" == result);
  266. BOOST_TEST(('h' == mpl::front<mpl::string<'hi!'> >::type()));
  267. BOOST_TEST(('!' == mpl::back<mpl::string<'hi!'> >::type()));
  268. // back-inserter with copy
  269. typedef mpl::vector_c<char, 'a','b','c','d','e'> rgc;
  270. BOOST_TEST(0 == std::strcmp("abcde", mpl::c_str<rgc>::value));
  271. typedef mpl::copy<rgc, mpl::back_inserter<mpl::string<> > >::type str;
  272. BOOST_TEST(0 == std::strcmp("abcde", mpl::c_str<str>::value));
  273. // test insert_range and erase
  274. {
  275. typedef mpl::string<'Hell','o wo','rld!'> hello;
  276. typedef mpl::advance_c<mpl::begin<hello>::type, 5>::type where;
  277. typedef mpl::string<' cru','el'> cruel;
  278. typedef mpl::insert_range<hello, where, cruel>::type hello_cruel;
  279. BOOST_TEST(0 == std::strcmp("Hello cruel world!", mpl::c_str<hello_cruel>::value));
  280. typedef mpl::erase<hello, mpl::begin<hello>::type, where>::type erased1;
  281. BOOST_TEST(0 == std::strcmp(" world!", mpl::c_str<erased1>::value));
  282. }
  283. // test pop_front
  284. {
  285. BOOST_MPL_ASSERT((
  286. boost::is_same<
  287. mpl::pop_front<mpl::string<'a'> >::type
  288. , mpl::string<>
  289. >
  290. ));
  291. BOOST_MPL_ASSERT((
  292. boost::is_same<
  293. mpl::pop_front<mpl::string<'ab'> >::type
  294. , mpl::string<'b'>
  295. >
  296. ));
  297. BOOST_MPL_ASSERT((
  298. boost::is_same<
  299. mpl::pop_front<mpl::string<'abc'> >::type
  300. , mpl::string<'bc'>
  301. >
  302. ));
  303. BOOST_MPL_ASSERT((
  304. boost::is_same<
  305. mpl::pop_front<mpl::string<'abcd'> >::type
  306. , mpl::string<'bcd'>
  307. >
  308. ));
  309. BOOST_MPL_ASSERT((
  310. boost::is_same<
  311. mpl::pop_front<mpl::string<'abcd','e'> >::type
  312. , mpl::string<'bcd','e'>
  313. >
  314. ));
  315. BOOST_MPL_ASSERT((
  316. boost::is_same<
  317. mpl::pop_front<mpl::string<'d','e'> >::type
  318. , mpl::string<'e'>
  319. >
  320. ));
  321. BOOST_MPL_ASSERT((
  322. boost::is_same<
  323. mpl::pop_front<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >::type
  324. , mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'>
  325. >
  326. ));
  327. }
  328. // test pop_back
  329. {
  330. BOOST_MPL_ASSERT((
  331. boost::is_same<
  332. mpl::pop_back<mpl::string<'a'> >::type
  333. , mpl::string<>
  334. >
  335. ));
  336. BOOST_MPL_ASSERT((
  337. boost::is_same<
  338. mpl::pop_back<mpl::string<'ab'> >::type
  339. , mpl::string<'a'>
  340. >
  341. ));
  342. BOOST_MPL_ASSERT((
  343. boost::is_same<
  344. mpl::pop_back<mpl::string<'abc'> >::type
  345. , mpl::string<'ab'>
  346. >
  347. ));
  348. BOOST_MPL_ASSERT((
  349. boost::is_same<
  350. mpl::pop_back<mpl::string<'abcd'> >::type
  351. , mpl::string<'abc'>
  352. >
  353. ));
  354. BOOST_MPL_ASSERT((
  355. boost::is_same<
  356. mpl::pop_back<mpl::string<'abcd','e'> >::type
  357. , mpl::string<'abcd'>
  358. >
  359. ));
  360. BOOST_MPL_ASSERT((
  361. boost::is_same<
  362. mpl::pop_back<mpl::string<'d','e'> >::type
  363. , mpl::string<'d'>
  364. >
  365. ));
  366. BOOST_MPL_ASSERT((
  367. boost::is_same<
  368. mpl::pop_back<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >::type
  369. , mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'>
  370. >
  371. ));
  372. }
  373. {
  374. BOOST_TEST((
  375. mpl::at_c<
  376. mpl::string<'\x7f'>
  377. , 0
  378. >::type::value == (char)0x7f
  379. ));
  380. BOOST_TEST((
  381. mpl::at_c<
  382. mpl::string<'\x80'>
  383. , 0
  384. >::type::value == (char)0x80
  385. ));
  386. BOOST_TEST((
  387. mpl::at_c<
  388. mpl::string<
  389. mpl::at_c<
  390. mpl::string<'\x7f'>
  391. , 0
  392. >::type::value
  393. >
  394. , 0
  395. >::type::value == (char)0x7f
  396. ));
  397. BOOST_TEST((
  398. mpl::at_c<
  399. mpl::string<
  400. mpl::at_c<
  401. mpl::string<'\x80'>
  402. , 0
  403. >::type::value
  404. >
  405. , 0
  406. >::type::value == (char)0x80
  407. ));
  408. }
  409. return boost::report_errors();
  410. }