PageRenderTime 39ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Test/CppLinqTests.hpp

http://cpplinq.codeplex.com
C++ Header | 3186 lines | 2560 code | 536 blank | 90 comment | 148 complexity | f10911cdf4db1fdd53a15b0a47816ee3 MD5 | raw file
  1. // ----------------------------------------------------------------------------------------------
  2. // Copyright (c) Mårten Rånge.
  3. // ----------------------------------------------------------------------------------------------
  4. // This source code is subject to terms and conditions of the Microsoft Public License. A
  5. // copy of the license can be found in the License.html file at the root of this distribution.
  6. // If you cannot locate the Microsoft Public License, please send an email to
  7. // dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  8. // by the terms of the Microsoft Public License.
  9. // ----------------------------------------------------------------------------------------------
  10. // You must not remove this notice, or any other, from this software.
  11. // ----------------------------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. // ----------------------------------------------------------------------------------------------
  14. #ifdef _MSC_VER
  15. # pragma warning (disable:4100)
  16. # pragma warning (disable:4996)
  17. #endif
  18. // ----------------------------------------------------------------------------------------------
  19. #ifdef _MSC_VER
  20. # include <windows.h>
  21. #endif
  22. // ----------------------------------------------------------------------------------------------
  23. #include <algorithm>
  24. #include <chrono>
  25. #include <cstdint>
  26. #include <map>
  27. #include <numeric>
  28. #include <set>
  29. #include <string>
  30. #include <sstream>
  31. #include <vector>
  32. // ----------------------------------------------------------------------------------------------
  33. #include <limits.h>
  34. #include <stdio.h>
  35. // ----------------------------------------------------------------------------------------------
  36. #include "../CppLinq/cpplinq.hpp"
  37. // ----------------------------------------------------------------------------------------------
  38. #define TEST_PRELUDE() test_prelude(__FILE__, __LINE__, __FUNCTION__)
  39. #define TEST_ASSERT(expected, found) test_assert(__FILE__, __LINE__, expected, #expected, found, #found, (expected == found))
  40. #define PRINT_INDEX(idx) print_index (#idx, idx);
  41. // ----------------------------------------------------------------------------------------------
  42. namespace
  43. {
  44. struct customer
  45. {
  46. std::size_t id ;
  47. std::string first_name ;
  48. std::string last_name ;
  49. customer (std::size_t id = 0, std::string first_name = "", std::string last_name = "")
  50. : id (std::move (id))
  51. , first_name (std::move (first_name))
  52. , last_name (std::move (last_name))
  53. {
  54. }
  55. customer & operator= (customer const & c)
  56. {
  57. if (std::addressof (c) == this)
  58. {
  59. return *this;
  60. }
  61. id = c.id ;
  62. first_name = c.first_name ;
  63. last_name = c.last_name ;
  64. return *this;
  65. }
  66. customer (customer const & c)
  67. : id (c.id)
  68. , first_name (c.first_name)
  69. , last_name (c.last_name)
  70. {
  71. }
  72. customer (customer && c)
  73. : id (std::move (c.id))
  74. , first_name (std::move (c.first_name))
  75. , last_name (std::move (c.last_name))
  76. {
  77. }
  78. bool operator==(customer const & c) const
  79. {
  80. return id == c.id && first_name == c.first_name && last_name == c.last_name;
  81. }
  82. bool operator !=(customer const & c) const
  83. {
  84. return !(*this == c);
  85. }
  86. bool operator<(customer const & c) const
  87. {
  88. return id < c.id;
  89. }
  90. };
  91. struct customer_address
  92. {
  93. std::size_t id ;
  94. std::size_t customer_id ;
  95. std::string country ;
  96. customer_address (std::size_t id, std::size_t customer_id, std::string country)
  97. : id (std::move (id))
  98. , customer_id (std::move (customer_id))
  99. , country (std::move (country))
  100. {
  101. }
  102. };
  103. struct player
  104. {
  105. std::size_t id;
  106. };
  107. struct game
  108. {
  109. std::size_t id ;
  110. std::set<player*> players ;
  111. };
  112. template <typename T>
  113. void ignore (T && v) CPPLINQ_NOEXCEPT
  114. {
  115. }
  116. template<typename TValueArray>
  117. std::size_t get_array_size (TValueArray & a)
  118. {
  119. return cpplinq::detail::get_array_properties<TValueArray>::size;
  120. }
  121. std::size_t get_even_counts (int const * is, std::size_t count)
  122. {
  123. auto c = 0U;
  124. for (auto index = 0U; index < count; ++index)
  125. {
  126. auto i = is[index];
  127. if (i%2 == 0)
  128. {
  129. ++c;
  130. }
  131. }
  132. return c;
  133. }
  134. std::size_t errors = 0U;
  135. std::vector<int> const empty_vector ;
  136. std::vector<customer> empty_customers ;
  137. customer const customers[] =
  138. {
  139. customer (1 , "Bill" , "Gates" ),
  140. customer (2 , "Steve" , "Jobs" ),
  141. customer (3 , "Richard" , "Stallman"),
  142. customer (4 , "Linus" , "Torvalds"),
  143. customer (11, "Steve" , "Ballmer" ),
  144. customer (12, "Tim" , "Cook" ),
  145. customer (21, "Melinda" , "Gates" ),
  146. };
  147. std::size_t const count_of_customers = get_array_size (customers);
  148. customer_address const customer_addresses[] =
  149. {
  150. customer_address (2, 4, "Finland" ),
  151. customer_address (3, 4, "USA" ),
  152. customer_address (1, 1, "USA" ),
  153. };
  154. std::size_t const count_of_customer_addresses = get_array_size (customer_addresses);
  155. customer const customers_set1[] =
  156. {
  157. customer (1 , "Bill" , "Gates" ),
  158. customer (2 , "Steve" , "Jobs" ),
  159. customer (3 , "Richard" , "Stallman"),
  160. customer (4 , "Linus" , "Torvalds"),
  161. customer (3 , "Richard" , "Stallman"),
  162. customer (2 , "Steve" , "Jobs" ),
  163. customer (1 , "Bill" , "Gates" ),
  164. };
  165. customer const customers_set2[] =
  166. {
  167. customer (1 , "Bill" , "Gates" ),
  168. customer (11, "Steve" , "Ballmer" ),
  169. customer (12, "Tim" , "Cook" ),
  170. };
  171. int const ints[] = {3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5};
  172. std::size_t const count_of_ints = get_array_size (ints);
  173. std::size_t const even_count_of_ints = get_even_counts (ints, count_of_ints);
  174. int const simple_ints[] = {1,2,3,4,5,6,7,8,9};
  175. std::size_t const count_of_simple_ints = get_array_size (simple_ints);
  176. int const set1[] = {5,4,3,2,1,2,3,4,5};
  177. std::size_t const count_of_set1 = get_array_size (set1);
  178. int const set2[] = {9,8,4,5,6,7,1,8,9};
  179. std::size_t const count_of_set2 = get_array_size (set2);
  180. double const double_set[] = {-1.0,0.0,2.0};
  181. std::size_t const count_of_double_set = get_array_size (double_set);
  182. std::set<game*> empty_game_set ;
  183. auto is_even = [](int i) {return i%2==0;};
  184. auto is_odd = [](int i) {return i%2==1;};
  185. auto smaller_than_five = [](int i) {return i < 5;};
  186. auto greater_than_five = [](int i) {return i > 5;};
  187. auto double_it = [](int i) {return i+i;};
  188. auto sum_aggregator = [](int s, int i) {return s+i;};
  189. auto mul_aggregator = [](int s, int i) {return s*i;};
  190. auto to_string = [](int i) -> std::string {std::stringstream sstr; sstr<<i; return sstr.str ();};
  191. void print_index (char const * name, std::size_t index)
  192. {
  193. printf (" @%s:%u\n", name, static_cast<std::uint32_t> (index)); // VS doesn't support %zu yet
  194. }
  195. void test_prelude (
  196. char const * file
  197. , int line_no
  198. , char const * test
  199. )
  200. {
  201. printf (
  202. "%s(%d): RUNNING: %s\n"
  203. , file
  204. , line_no
  205. , test
  206. );
  207. }
  208. bool test_assert (
  209. char const * file
  210. , int line_no
  211. , bool expected
  212. , char const * expected_name
  213. , bool found
  214. , char const * found_name
  215. , bool result
  216. )
  217. {
  218. if (!result)
  219. {
  220. ++errors;
  221. printf (
  222. "%s(%d): ERROR_EXPECTED: %s(%s), FOUND: %s(%s)\n"
  223. , file
  224. , line_no
  225. , expected ? "true" : "false"
  226. , expected_name
  227. , found ? "true" : "false"
  228. , found_name
  229. );
  230. }
  231. return result;
  232. }
  233. bool test_assert (
  234. char const * file
  235. , int line_no
  236. , std::string expected
  237. , char const * expected_name
  238. , std::string found
  239. , char const * found_name
  240. , bool result
  241. )
  242. {
  243. if (!result)
  244. {
  245. ++errors;
  246. printf (
  247. "%s(%d): ERROR_EXPECTED: %s(%s), FOUND: %s(%s)\n"
  248. , file
  249. , line_no
  250. , expected.c_str ()
  251. , expected_name
  252. , found.c_str ()
  253. , found_name
  254. );
  255. }
  256. return result;
  257. }
  258. bool test_assert (
  259. char const * file
  260. , int line_no
  261. , int expected
  262. , char const * expected_name
  263. , int found
  264. , char const * found_name
  265. , bool result
  266. )
  267. {
  268. if (!result)
  269. {
  270. ++errors;
  271. printf (
  272. "%s(%d): ERROR_EXPECTED: %d(%s), FOUND: %d(%s)\n"
  273. , file
  274. , line_no
  275. , expected
  276. , expected_name
  277. , found
  278. , found_name
  279. );
  280. }
  281. return result;
  282. }
  283. bool test_assert (
  284. char const * file
  285. , int line_no
  286. , double expected
  287. , char const * expected_name
  288. , double found
  289. , char const * found_name
  290. , bool result
  291. )
  292. {
  293. if (!result)
  294. {
  295. ++errors;
  296. printf (
  297. "%s(%d): ERROR_EXPECTED: %f(%s), FOUND: %f(%s)\n"
  298. , file
  299. , line_no
  300. , expected
  301. , expected_name
  302. , found
  303. , found_name
  304. );
  305. }
  306. return result;
  307. }
  308. bool test_assert (
  309. char const * file
  310. , int line_no
  311. , std::size_t expected
  312. , char const * expected_name
  313. , std::size_t found
  314. , char const * found_name
  315. , bool result
  316. )
  317. {
  318. if (!result)
  319. {
  320. ++errors;
  321. printf (
  322. "%s(%d): ERROR_EXPECTED: %u(%s), FOUND: %u(%s)\n"
  323. , file
  324. , line_no
  325. , static_cast<std::uint32_t> (expected) // VS doesn't support %zu yet
  326. , expected_name
  327. , static_cast<std::uint32_t> (found) // VS doesn't support %zu yet
  328. , found_name
  329. );
  330. }
  331. return result;
  332. }
  333. bool test_assert (
  334. char const * file
  335. , int line_no
  336. , customer expected
  337. , char const * expected_name
  338. , customer found
  339. , char const * found_name
  340. , bool result
  341. )
  342. {
  343. if (!result)
  344. {
  345. ++errors;
  346. printf (
  347. "%s(%d): ERROR_EXPECTED: (%u,%s,%s)(%s), FOUND: (%u,%s,%s)(%s)\n"
  348. , file
  349. , line_no
  350. , static_cast<std::uint32_t> (expected.id), expected.first_name.c_str (), expected.last_name.c_str () // VS doesn't support %zu yet
  351. , expected_name
  352. , static_cast<std::uint32_t> (found.id), found.first_name.c_str (), found.last_name.c_str () // VS doesn't support %zu yet
  353. , found_name
  354. );
  355. }
  356. return result;
  357. }
  358. void test_int_at (std::size_t index, int v)
  359. {
  360. if (
  361. TEST_ASSERT (true, (index < count_of_ints))
  362. && TEST_ASSERT (ints[index], v)
  363. )
  364. {
  365. }
  366. else
  367. {
  368. PRINT_INDEX (index);
  369. }
  370. }
  371. void test_opt ()
  372. {
  373. using namespace cpplinq::detail;
  374. TEST_PRELUDE ();
  375. {
  376. opt<int> o;
  377. TEST_ASSERT (false, o.has_value ());
  378. // Test to make sure that 'if (o)' compiles
  379. if (o)
  380. {
  381. }
  382. }
  383. {
  384. opt<int> o1;
  385. opt<int> o2 (10);
  386. TEST_ASSERT (false, o1.has_value ());
  387. TEST_ASSERT (true, o2.has_value ());
  388. TEST_ASSERT (10, *o2);
  389. o1 = o1;
  390. o2 = o2;
  391. TEST_ASSERT (false, o1.has_value ());
  392. TEST_ASSERT (true, o2.has_value ());
  393. TEST_ASSERT (10, *o2);
  394. o1 = std::move (o1);
  395. o2 = std::move (o2);
  396. TEST_ASSERT (false, o1.has_value ());
  397. TEST_ASSERT (true, o2.has_value ());
  398. TEST_ASSERT (10, *o2);
  399. opt<int> o3 (o2);
  400. opt<int> o4 (o1);
  401. o3.swap (o4);
  402. TEST_ASSERT (false, o3.has_value ());
  403. TEST_ASSERT (true, o4.has_value ());
  404. TEST_ASSERT (10, *o4);
  405. o1.swap (o2);
  406. TEST_ASSERT (true, o1.has_value ());
  407. TEST_ASSERT (10, *o1);
  408. TEST_ASSERT (false, o2.has_value ());
  409. o2 = o1;
  410. TEST_ASSERT (true, o1.has_value ());
  411. TEST_ASSERT (10, *o1);
  412. TEST_ASSERT (true, o2.has_value ());
  413. TEST_ASSERT (10, *o2);
  414. o1 = 11;
  415. o2 = 12;
  416. TEST_ASSERT (true, o1.has_value ());
  417. TEST_ASSERT (11, *o1);
  418. TEST_ASSERT (true, o2.has_value ());
  419. TEST_ASSERT (12, *o2);
  420. }
  421. {
  422. opt<std::string> o1;
  423. opt<std::string> o2 ("Test");
  424. TEST_ASSERT (false, o1.has_value ());
  425. TEST_ASSERT (true, o2.has_value ());
  426. TEST_ASSERT ("Test", *o2);
  427. TEST_ASSERT (4U, o2->size ());
  428. o1 = "Test2";
  429. o2 = "Test3";
  430. TEST_ASSERT (true, o1.has_value ());
  431. TEST_ASSERT ("Test2", *o1);
  432. TEST_ASSERT (true, o2.has_value ());
  433. TEST_ASSERT ("Test3", *o2);
  434. o1.swap (o2);
  435. TEST_ASSERT (true, o1.has_value ());
  436. TEST_ASSERT ("Test3", *o1);
  437. TEST_ASSERT (true, o2.has_value ());
  438. TEST_ASSERT ("Test2", *o2);
  439. }
  440. {
  441. opt<int> o (1);
  442. TEST_ASSERT (true, o.has_value ());
  443. o.clear ();
  444. TEST_ASSERT (false, o.has_value ());
  445. }
  446. }
  447. void test_lookup ()
  448. {
  449. using namespace cpplinq;
  450. using namespace cpplinq::detail;
  451. TEST_PRELUDE ();
  452. {
  453. lookup<size_type, customer> lookup (
  454. 16U
  455. , from (empty_customers)
  456. , [] (customer const & c){return c.id;}
  457. );
  458. TEST_ASSERT (0U, lookup.size_of_keys ());
  459. TEST_ASSERT (0U, lookup.size_of_values ());
  460. {
  461. auto results = lookup[999] >> to_vector ();
  462. TEST_ASSERT (0U, results.size ());
  463. }
  464. {
  465. auto results = lookup.range_of_values () >> to_vector ();
  466. TEST_ASSERT (0U, results.size ());
  467. }
  468. }
  469. {
  470. lookup<size_type, customer> lookup (
  471. 16U
  472. , from_array (customers)
  473. , [] (customer const & c){return c.id;}
  474. );
  475. TEST_ASSERT (count_of_customers, lookup.size_of_keys ());
  476. TEST_ASSERT (count_of_customers, lookup.size_of_values ());
  477. {
  478. auto results = lookup.range_of_values () >> to_vector ();
  479. if (TEST_ASSERT (count_of_customers, results.size ()))
  480. {
  481. for (std::size_t iter = 0U; iter < count_of_customers; ++iter)
  482. {
  483. // As customers are sorted on id in the test data set
  484. // this is ok
  485. if (!TEST_ASSERT (customers[iter].id, results[iter].id))
  486. {
  487. PRINT_INDEX (iter);
  488. }
  489. }
  490. }
  491. }
  492. for (auto customer : customers)
  493. {
  494. auto results = lookup[customer.id] >> to_vector ();
  495. if (TEST_ASSERT (1U, results.size ()))
  496. {
  497. auto result = results.front ();
  498. if (!TEST_ASSERT (customer.id, result.id))
  499. {
  500. PRINT_INDEX (customer.id);
  501. }
  502. }
  503. else
  504. {
  505. PRINT_INDEX (customer.id);
  506. }
  507. }
  508. }
  509. {
  510. lookup<size_type, customer_address> lookup (
  511. 16U
  512. , from_array (customer_addresses)
  513. , [] (customer_address const & ca){return ca.customer_id;}
  514. );
  515. TEST_ASSERT (2U, lookup.size_of_keys ());
  516. TEST_ASSERT (count_of_customer_addresses, lookup.size_of_values ());
  517. {
  518. auto results = lookup.range_of_values () >> to_vector ();
  519. TEST_ASSERT (count_of_customer_addresses, results.size ());
  520. }
  521. {
  522. auto results = lookup[1] >> to_vector ();
  523. if (TEST_ASSERT (1U, results.size ()))
  524. {
  525. auto result = results.front ();
  526. TEST_ASSERT (1U, result.id);
  527. }
  528. }
  529. {
  530. auto results = lookup[4] >> to_vector ();
  531. if (TEST_ASSERT (2U, results.size ()))
  532. {
  533. auto result1 = results[0];
  534. TEST_ASSERT (2U, result1.id);
  535. auto result2 = results[1];
  536. TEST_ASSERT (3U, result2.id);
  537. }
  538. }
  539. {
  540. auto results = lookup[999] >> to_vector ();
  541. TEST_ASSERT (0U, results.size ());
  542. }
  543. }
  544. }
  545. void test_from ()
  546. {
  547. using namespace cpplinq;
  548. TEST_PRELUDE ();
  549. {
  550. auto q = from (empty_vector);
  551. typedef decltype (q.front ()) return_type;
  552. static_assert (
  553. std::is_reference<return_type>::value
  554. , "from::front () must return reference"
  555. );
  556. std::size_t index = 0U;
  557. while (q.next ())
  558. {
  559. test_int_at (index, q.front ());
  560. ++index;
  561. }
  562. TEST_ASSERT (0U, index);
  563. }
  564. {
  565. auto q = from_array (ints);
  566. typedef decltype (q.front ()) return_type;
  567. static_assert (
  568. std::is_reference<return_type>::value
  569. , "from::front () must return reference"
  570. );
  571. auto index = 0U;
  572. while (q.next ())
  573. {
  574. test_int_at (index, q.front ());
  575. ++index;
  576. }
  577. TEST_ASSERT (count_of_ints, index);
  578. }
  579. {
  580. auto q = from_copy (empty_vector);
  581. typedef decltype (q.front ()) return_type;
  582. static_assert (
  583. std::is_reference<return_type>::value
  584. , "from::front () must return reference"
  585. );
  586. std::size_t index = 0U;
  587. while (q.next ())
  588. {
  589. test_int_at (index, q.front ());
  590. ++index;
  591. }
  592. TEST_ASSERT (0U, index);
  593. }
  594. {
  595. std::vector<int> is (ints, ints + count_of_ints);
  596. auto q = from_copy (is);
  597. typedef decltype (q.front ()) return_type;
  598. static_assert (
  599. std::is_reference<return_type>::value
  600. , "from::front () must return reference"
  601. );
  602. auto index = 0U;
  603. while (q.next ())
  604. {
  605. test_int_at (index, q.front ());
  606. ++index;
  607. }
  608. TEST_ASSERT (count_of_ints, index);
  609. }
  610. {
  611. auto q = from_array (customers);
  612. typedef decltype (q.front ()) return_type;
  613. static_assert (
  614. std::is_reference<return_type>::value
  615. , "front () must return non-reference when value_type = customer"
  616. );
  617. }
  618. {
  619. std::vector<customer> cs;
  620. auto q = from_copy (cs);
  621. typedef decltype (q.front ()) return_type;
  622. static_assert (
  623. std::is_reference<return_type>::value
  624. , "front () must return non-reference when value_type = customer"
  625. );
  626. }
  627. }
  628. void test_range ()
  629. {
  630. using namespace cpplinq;
  631. TEST_PRELUDE ();
  632. {
  633. auto r = range (10, 0);
  634. typedef decltype (r.front ()) return_type;
  635. static_assert (
  636. !std::is_reference<return_type>::value
  637. , "front () must return non-reference when value_type = int"
  638. );
  639. bool isempty = !r.next ();
  640. TEST_ASSERT (true, isempty);
  641. }
  642. {
  643. auto start = 12;
  644. auto count = 10;
  645. auto index = start;
  646. auto q = range (start, count);
  647. typedef decltype (q.front ()) return_type;
  648. static_assert (
  649. !std::is_reference<return_type>::value
  650. , "front () must return non-reference when value_type = int"
  651. );
  652. while (q.next ())
  653. {
  654. if (!TEST_ASSERT (index, q.front ()))
  655. {
  656. PRINT_INDEX (index);
  657. }
  658. ++index;
  659. }
  660. TEST_ASSERT (start + count , index);
  661. }
  662. }
  663. void test_repeat ()
  664. {
  665. using namespace cpplinq;
  666. TEST_PRELUDE ();
  667. {
  668. auto r = repeat (42, 0);
  669. typedef decltype (r.front ()) return_type;
  670. static_assert (
  671. !std::is_reference<return_type>::value
  672. , "front () must return non-reference when value_type = int"
  673. );
  674. bool isempty = !r.next ();
  675. TEST_ASSERT (true, isempty);
  676. }
  677. {
  678. auto value = 42;
  679. int count = 10;
  680. int total = 0;
  681. auto r = repeat (value, count);
  682. typedef decltype (r.front ()) return_type;
  683. static_assert (
  684. !std::is_reference<return_type>::value
  685. , "front () must return non-reference when value_type = int"
  686. );
  687. while (r.next ())
  688. {
  689. if (!TEST_ASSERT (value, r.front ()))
  690. {
  691. PRINT_INDEX (total);
  692. }
  693. ++total;
  694. }
  695. TEST_ASSERT (total , count);
  696. }
  697. {
  698. auto value = customers[0];
  699. int count = 10;
  700. int total = 0;
  701. auto r = repeat (value, count);
  702. while (r.next ())
  703. {
  704. if (!TEST_ASSERT (value, r.front ()))
  705. {
  706. PRINT_INDEX (total);
  707. }
  708. ++total;
  709. }
  710. TEST_ASSERT (total , count);
  711. }
  712. }
  713. void test_empty ()
  714. {
  715. using namespace cpplinq;
  716. TEST_PRELUDE ();
  717. {
  718. auto r = empty<int>();
  719. typedef decltype (r.front ()) return_type;
  720. static_assert (
  721. !std::is_reference<return_type>::value
  722. , "front () must return non-reference when value_type = int"
  723. );
  724. bool isempty = !r.next ();
  725. TEST_ASSERT (true, isempty);
  726. }
  727. {
  728. auto r = empty<customer>();
  729. bool isempty = !r.next ();
  730. TEST_ASSERT (true, isempty);
  731. }
  732. {
  733. auto customers = empty<customer>() >> to_list ();
  734. TEST_ASSERT (0U, customers.size ());
  735. }
  736. }
  737. void test_singleton ()
  738. {
  739. using namespace cpplinq;
  740. TEST_PRELUDE ();
  741. {
  742. auto singleton_result = singleton (1) >> to_vector ();
  743. TEST_ASSERT (1U, singleton_result.size ());
  744. TEST_ASSERT (1, singleton_result[0]);
  745. }
  746. }
  747. void test_generate ()
  748. {
  749. using namespace cpplinq;
  750. TEST_PRELUDE ();
  751. {
  752. auto x = -1;
  753. auto generate_result =
  754. generate (
  755. [&]()
  756. {
  757. return (++x < 3)
  758. ? to_opt (x)
  759. : to_opt<int> ()
  760. ;
  761. })
  762. >> to_vector ()
  763. ;
  764. if (TEST_ASSERT (3U, generate_result.size ()))
  765. {
  766. TEST_ASSERT (0, generate_result[0]);
  767. TEST_ASSERT (1, generate_result[1]);
  768. TEST_ASSERT (2, generate_result[2]);
  769. }
  770. }
  771. }
  772. void test_set ()
  773. {
  774. using namespace cpplinq;
  775. TEST_PRELUDE ();
  776. {
  777. auto count_result = from (empty_game_set) >> count ();
  778. TEST_ASSERT (0U, count_result);
  779. }
  780. {
  781. auto count_result =
  782. from (empty_game_set)
  783. >> select ([] (game * g) { return g->id; })
  784. >> distinct ()
  785. >> count ()
  786. ;
  787. TEST_ASSERT (0U, count_result);
  788. }
  789. {
  790. // TODO: Test code for more complex select_many
  791. auto count_result =
  792. from (empty_game_set)
  793. >> where ([] (game * g) { return g != nullptr; })
  794. >> select_many (
  795. [] (game * g)
  796. {
  797. auto r =
  798. from (g->players)
  799. // >> where ([] (player * p) { return p != nullptr; })
  800. // >> select ([] (player* p) { return p->id; })
  801. ;
  802. return r;
  803. })
  804. >> distinct ()
  805. >> count ()
  806. ;
  807. TEST_ASSERT (0U, count_result);
  808. }
  809. }
  810. void test_count ()
  811. {
  812. using namespace cpplinq;
  813. TEST_PRELUDE ();
  814. {
  815. auto count_result = from (empty_vector) >> count ();
  816. TEST_ASSERT (0U, count_result);
  817. }
  818. {
  819. auto count_result = from_array (ints) >> count ();
  820. TEST_ASSERT (count_of_ints, count_result);
  821. }
  822. {
  823. auto count_result = from (empty_vector) >> count (is_even);
  824. TEST_ASSERT (0U, count_result);
  825. }
  826. {
  827. auto count_result = from_array (ints) >> count (is_even);
  828. TEST_ASSERT (even_count_of_ints, count_result);
  829. }
  830. }
  831. void test_any ()
  832. {
  833. using namespace cpplinq;
  834. TEST_PRELUDE ();
  835. {
  836. auto any_result = from (empty_vector) >> any ();
  837. TEST_ASSERT (false, any_result);
  838. }
  839. {
  840. auto any_result = from_array (ints) >> any ();
  841. TEST_ASSERT (true, any_result);
  842. }
  843. {
  844. auto any_result = from (empty_vector) >> any (is_even);
  845. TEST_ASSERT (false, any_result);
  846. }
  847. {
  848. auto any_result = from_array (ints) >> any (is_even);
  849. TEST_ASSERT (true, any_result);
  850. }
  851. }
  852. void test_first ()
  853. {
  854. using namespace cpplinq;
  855. TEST_PRELUDE ();
  856. std::string expected_on_failure ("sequence_empty_exception");
  857. {
  858. sequence_empty_exception caught_exception;
  859. try
  860. {
  861. int first_result = from (empty_vector) >> first ();
  862. ignore (first_result);
  863. }
  864. catch (sequence_empty_exception const & ex)
  865. {
  866. caught_exception = ex;
  867. }
  868. TEST_ASSERT (expected_on_failure, caught_exception.what ());
  869. }
  870. {
  871. int first_result = from_array (ints) >> first ();
  872. TEST_ASSERT (3, first_result);
  873. }
  874. {
  875. sequence_empty_exception caught_exception;
  876. try
  877. {
  878. int first_result = from (empty_vector) >> first (is_even);
  879. ignore (first_result);
  880. }
  881. catch (sequence_empty_exception const & ex)
  882. {
  883. caught_exception = ex;
  884. }
  885. TEST_ASSERT (expected_on_failure, caught_exception.what ());
  886. }
  887. {
  888. int first_result = from_array (ints) >> first (is_even);
  889. TEST_ASSERT (4, first_result);
  890. }
  891. {
  892. // Issue: https://cpplinq.codeplex.com/workitem/15
  893. // Reported by: Sepidar
  894. auto result =
  895. range (0, 3)
  896. >> where ([](int i) {return i % 2 == 1;})
  897. >> orderby ([](int i) {return i;})
  898. >> first ()
  899. ;
  900. TEST_ASSERT (1, result);
  901. }
  902. }
  903. void test_first_or_default ()
  904. {
  905. using namespace cpplinq;
  906. TEST_PRELUDE ();
  907. {
  908. int first_result = from (empty_vector) >> first_or_default ();
  909. TEST_ASSERT (0, first_result);
  910. }
  911. {
  912. int first_result = from_array (ints) >> first_or_default ();
  913. TEST_ASSERT (3, first_result);
  914. }
  915. {
  916. int first_result = from (empty_vector) >> first_or_default (is_even);
  917. TEST_ASSERT (0, first_result);
  918. }
  919. {
  920. int first_result = from_array (ints) >> first_or_default (is_even);
  921. TEST_ASSERT (4, first_result);
  922. }
  923. }
  924. void test_last_or_default ()
  925. {
  926. using namespace cpplinq;
  927. TEST_PRELUDE ();
  928. {
  929. int first_result = from (empty_vector) >> last_or_default ();
  930. TEST_ASSERT (0, first_result);
  931. }
  932. {
  933. int first_result = from_array (ints) >> last_or_default ();
  934. TEST_ASSERT (5, first_result);
  935. }
  936. {
  937. int first_result = from (empty_vector) >> last_or_default (is_even);
  938. TEST_ASSERT (0, first_result);
  939. }
  940. {
  941. int first_result = from_array (ints) >> last_or_default (is_even);
  942. TEST_ASSERT (2, first_result);
  943. }
  944. }
  945. void test_sum ()
  946. {
  947. using namespace cpplinq;
  948. TEST_PRELUDE ();
  949. {
  950. int sum_result = from (empty_vector) >> sum ();
  951. TEST_ASSERT (0, sum_result);
  952. }
  953. {
  954. int sum_of_ints = std::accumulate (ints, ints + count_of_ints, 0);
  955. int sum_result = from_array (ints) >> sum ();
  956. TEST_ASSERT (sum_of_ints, sum_result);
  957. }
  958. {
  959. int sum_result = from (empty_vector) >> sum (double_it);
  960. TEST_ASSERT (0, sum_result);
  961. }
  962. {
  963. int sum_of_ints = std::accumulate (ints, ints + count_of_ints, 0);
  964. int sum_result = from_array (ints) >> sum (double_it);
  965. TEST_ASSERT (2*sum_of_ints, sum_result);
  966. }
  967. {
  968. std::size_t sum_result = from_array (customers) >> sum ([] (customer const & c) { return c.id; });
  969. TEST_ASSERT (54U, sum_result);
  970. }
  971. }
  972. void test_min ()
  973. {
  974. using namespace cpplinq;
  975. TEST_PRELUDE ();
  976. {
  977. int min_result = from (empty_vector) >> min ();
  978. TEST_ASSERT (INT_MAX, min_result);
  979. }
  980. {
  981. int min_result = from_array (ints) >> min ();
  982. TEST_ASSERT (1, min_result);
  983. }
  984. {
  985. int min_result = from (empty_vector) >> min (double_it);
  986. TEST_ASSERT (INT_MAX, min_result);
  987. }
  988. {
  989. int min_result = from_array (ints) >> min (double_it);
  990. TEST_ASSERT (2, min_result);
  991. }
  992. {
  993. double min_result = from_array (double_set) >> min ();
  994. TEST_ASSERT (-1.0, min_result);
  995. }
  996. {
  997. std::size_t min_result = from_array (customers) >> min ([] (customer const & c) { return c.id; });
  998. TEST_ASSERT (1U, min_result);
  999. }
  1000. }
  1001. void test_avg ()
  1002. {
  1003. using namespace cpplinq;
  1004. TEST_PRELUDE ();
  1005. {
  1006. int avg_result = from (empty_vector) >> avg ();
  1007. TEST_ASSERT (0, avg_result);
  1008. }
  1009. {
  1010. int avg_result = from_array (ints) >> avg ();
  1011. TEST_ASSERT (4, avg_result);
  1012. }
  1013. {
  1014. int avg_result = from (empty_vector) >> avg (double_it);
  1015. TEST_ASSERT (0, avg_result);
  1016. }
  1017. {
  1018. int avg_result = from_array (ints) >> avg (double_it);
  1019. TEST_ASSERT (9, avg_result);
  1020. }
  1021. {
  1022. std::size_t avg_result = from_array (customers) >> avg ([] (customer const & c) { return c.id; });
  1023. TEST_ASSERT (7U, avg_result);
  1024. }
  1025. }
  1026. void test_max ()
  1027. {
  1028. using namespace cpplinq;
  1029. TEST_PRELUDE ();
  1030. {
  1031. int max_result = from (empty_vector) >> max ();
  1032. TEST_ASSERT (INT_MIN, max_result);
  1033. }
  1034. {
  1035. int max_result = from_array (ints) >> max ();
  1036. TEST_ASSERT (9, max_result);
  1037. }
  1038. {
  1039. int max_result = from (empty_vector) >> max (double_it);
  1040. TEST_ASSERT (INT_MIN, max_result);
  1041. }
  1042. {
  1043. int max_result = from_array (ints) >> max (double_it);
  1044. TEST_ASSERT (18, max_result);
  1045. }
  1046. {
  1047. double max_result = from_array (double_set) >> max ();
  1048. TEST_ASSERT (2.0, max_result);
  1049. }
  1050. {
  1051. std::size_t max_result = from_array (customers) >> max ([] (customer const & c) { return c.id; });
  1052. TEST_ASSERT (21U, max_result);
  1053. }
  1054. }
  1055. void test_concatenate ()
  1056. {
  1057. using namespace cpplinq;
  1058. TEST_PRELUDE ();
  1059. {
  1060. std::wstring concatenate_result =
  1061. from (empty_vector)
  1062. >> select ([] (int i){return std::wstring ();})
  1063. >> concatenate (L"")
  1064. ;
  1065. TEST_ASSERT (true, concatenate_result.empty ());
  1066. }
  1067. {
  1068. std::string concatenate_result =
  1069. from_array (customers)
  1070. >> select ([](customer const & c){return c.last_name;})
  1071. >> concatenate (", ")
  1072. ;
  1073. TEST_ASSERT ("Gates, Jobs, Stallman, Torvalds, Ballmer, Cook, Gates", concatenate_result);
  1074. }
  1075. }
  1076. void test_for_each ()
  1077. {
  1078. using namespace cpplinq;
  1079. TEST_PRELUDE ();
  1080. {
  1081. std::size_t index = 0U;
  1082. from (empty_vector) >> for_each ([&](int i){test_int_at (index, i); ++index;});
  1083. TEST_ASSERT (0U, index);
  1084. }
  1085. {
  1086. auto index = 0U;
  1087. from_array (ints) >> for_each ([&](int i){test_int_at (index, i); ++index;});
  1088. TEST_ASSERT (count_of_ints, index);
  1089. }
  1090. }
  1091. void test_all ()
  1092. {
  1093. using namespace cpplinq;
  1094. TEST_PRELUDE ();
  1095. {
  1096. std::size_t index = 0U;
  1097. auto all_result = from (empty_vector) >> all ([&](int i)-> bool {test_int_at (index, i); ++index; return true;});
  1098. TEST_ASSERT (true, all_result);
  1099. TEST_ASSERT (0U, index);
  1100. }
  1101. {
  1102. auto index = 0U;
  1103. auto all_result = from_array (ints) >> all ([&](int i)-> bool {test_int_at (index, i); ++index; return true;});
  1104. TEST_ASSERT (true, all_result);
  1105. TEST_ASSERT (count_of_ints, index);
  1106. }
  1107. {
  1108. std::size_t index = 0U;
  1109. auto all_result = from_array (ints) >> all ([&](int i)-> bool {test_int_at (index, i); ++index; return index < 10;});
  1110. TEST_ASSERT (false, all_result);
  1111. TEST_ASSERT (10U, index);
  1112. }
  1113. }
  1114. void test_to_vector ()
  1115. {
  1116. using namespace cpplinq;
  1117. TEST_PRELUDE ();
  1118. {
  1119. std::vector<int> to_vector_result = from (empty_vector) >> to_vector ();
  1120. TEST_ASSERT (0U, to_vector_result.size ());
  1121. }
  1122. {
  1123. std::vector<int> to_vector_result = from_array (ints) >> to_vector ();
  1124. TEST_ASSERT (count_of_ints, to_vector_result.size ());
  1125. for (auto index = 0U; index < to_vector_result.size (); ++index)
  1126. {
  1127. test_int_at (index, to_vector_result[index]);
  1128. }
  1129. }
  1130. }
  1131. void test_to_map ()
  1132. {
  1133. using namespace cpplinq;
  1134. TEST_PRELUDE ();
  1135. {
  1136. std::map<int,int> to_map_result = from (empty_vector) >> to_map ([](int i){return i;});
  1137. TEST_ASSERT (0U, to_map_result.size ());
  1138. }
  1139. {
  1140. auto to_map_result = from_array (customers) >> to_map ([](customer const & c){return c.id;});
  1141. TEST_ASSERT (count_of_customers, to_map_result.size ());
  1142. for (auto index = 0U; index < count_of_customers; ++index)
  1143. {
  1144. auto c1 = customers[index];
  1145. auto find_c2 = to_map_result.find (c1.id);
  1146. if (TEST_ASSERT (true, (find_c2 != to_map_result.end ())))
  1147. {
  1148. auto c2 = find_c2->second;
  1149. if (
  1150. TEST_ASSERT (c1.id, c2.id)
  1151. && TEST_ASSERT (c1.first_name, c2.first_name)
  1152. && TEST_ASSERT (c1.last_name, c2.last_name)
  1153. )
  1154. {
  1155. }
  1156. else
  1157. {
  1158. PRINT_INDEX (index);
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. void test_to_lookup ()
  1165. {
  1166. using namespace cpplinq;
  1167. using namespace cpplinq::detail;
  1168. TEST_PRELUDE ();
  1169. {
  1170. auto lookup = from (empty_customers) >> to_lookup ([] (customer const & c){return c.id;});
  1171. TEST_ASSERT (0U, lookup.size_of_keys ());
  1172. TEST_ASSERT (0U, lookup.size_of_values ());
  1173. }
  1174. {
  1175. auto lookup = from_array (customers) >> to_lookup ([] (customer const & c){return c.id;});
  1176. TEST_ASSERT (count_of_customers, lookup.size_of_keys ());
  1177. TEST_ASSERT (count_of_customers, lookup.size_of_values ());
  1178. for (auto customer : customers)
  1179. {
  1180. auto results = lookup[customer.id] >> to_vector ();
  1181. if (TEST_ASSERT (1U, results.size ()))
  1182. {
  1183. auto result = results.front ();
  1184. if (!TEST_ASSERT (customer.id, result.id))
  1185. {
  1186. PRINT_INDEX (customer.id);
  1187. }
  1188. }
  1189. else
  1190. {
  1191. PRINT_INDEX (customer.id);
  1192. }
  1193. }
  1194. }
  1195. {
  1196. auto lookup = from_array (customer_addresses) >> to_lookup ([] (customer_address const & ca){return ca.customer_id;});
  1197. TEST_ASSERT (2U, lookup.size_of_keys ());
  1198. TEST_ASSERT (count_of_customer_addresses, lookup.size_of_values ());
  1199. {
  1200. auto results = lookup[1] >> to_vector ();
  1201. if (TEST_ASSERT (1U, results.size ()))
  1202. {
  1203. auto result = results.front ();
  1204. TEST_ASSERT (1U, result.id);
  1205. }
  1206. }
  1207. {
  1208. auto results = lookup[4] >> to_vector ();
  1209. if (TEST_ASSERT (2U, results.size ()))
  1210. {
  1211. auto result1 = results[0];
  1212. TEST_ASSERT (2U, result1.id);
  1213. auto result2 = results[1];
  1214. TEST_ASSERT (3U, result2.id);
  1215. }
  1216. }
  1217. {
  1218. auto results = lookup[999] >> to_vector ();
  1219. TEST_ASSERT (0U, results.size ());
  1220. }
  1221. }
  1222. // code coverage test
  1223. {
  1224. auto lookup = empty<int>() >> to_lookup ([] (int i) {return i;});
  1225. auto q = lookup[999];
  1226. TEST_ASSERT (false, q.next ());
  1227. TEST_ASSERT (false, q.next ());
  1228. }
  1229. }
  1230. void test_to_list ()
  1231. {
  1232. using namespace cpplinq;
  1233. TEST_PRELUDE ();
  1234. {
  1235. std::list<int> to_list_result = from (empty_vector) >> to_list ();
  1236. TEST_ASSERT (0U, to_list_result.size ());
  1237. }
  1238. {
  1239. std::list<int> to_list_result = from_array (ints) >> to_list ();
  1240. TEST_ASSERT (count_of_ints, to_list_result.size ());
  1241. auto pos = to_list_result.begin ();
  1242. for (auto index = 0U; index < to_list_result.size (); ++index)
  1243. {
  1244. test_int_at (index, *pos++);
  1245. }
  1246. }
  1247. }
  1248. void test_container ()
  1249. {
  1250. using namespace cpplinq;
  1251. using namespace cpplinq::experimental;
  1252. TEST_PRELUDE ();
  1253. {
  1254. auto container_result = from (empty_vector) >> container ();
  1255. std::vector<int> v (container_result.begin (), container_result.end ());
  1256. TEST_ASSERT (0U, v.size ());
  1257. }
  1258. {
  1259. auto container_result = from_iterators (ints, ints + count_of_ints) >> container ();
  1260. std::vector<int> v (container_result.begin (), container_result.end ());
  1261. if (TEST_ASSERT (count_of_ints, v.size ()))
  1262. {
  1263. for (auto index = 0U; index < count_of_ints; ++index)
  1264. {
  1265. test_int_at (index, v[index]);
  1266. }
  1267. }
  1268. }
  1269. {
  1270. auto container_result = from_array (customers) >> container ();
  1271. auto begin = container_result.begin ();
  1272. auto end = container_result.end ();
  1273. TEST_ASSERT (true, (begin != end));
  1274. TEST_ASSERT (false, (begin == end));
  1275. auto c = *begin;
  1276. TEST_ASSERT (1U, c.id);
  1277. TEST_ASSERT (1U, begin->id);
  1278. TEST_ASSERT (1U, (*begin).id);
  1279. }
  1280. }
  1281. void test_where ()
  1282. {
  1283. using namespace cpplinq;
  1284. TEST_PRELUDE ();
  1285. {
  1286. auto c = from (empty_vector) >> where (is_even) >> count ();
  1287. TEST_ASSERT (0U, c);
  1288. }
  1289. {
  1290. auto c = from_array (ints) >> where (is_even) >> count ();
  1291. TEST_ASSERT (even_count_of_ints, c);
  1292. }
  1293. {
  1294. auto v = from_array (ints) >> where (is_even) >> first_or_default ();
  1295. TEST_ASSERT (4, v);
  1296. }
  1297. }
  1298. void test_ref ()
  1299. {
  1300. using namespace cpplinq;
  1301. TEST_PRELUDE ();
  1302. {
  1303. std::vector<std::reference_wrapper<int const>> ref_result =
  1304. from (empty_vector)
  1305. >> ref ()
  1306. >> to_vector ()
  1307. ;
  1308. TEST_ASSERT (0U, ref_result.size ());
  1309. }
  1310. {
  1311. std::vector<std::reference_wrapper<customer const>> ref_result =
  1312. from_array (customers)
  1313. >> ref ()
  1314. >> to_vector ()
  1315. ;
  1316. auto index = 0U;
  1317. for (auto customer : ref_result)
  1318. {
  1319. if (!TEST_ASSERT (customers[index].id, customer.get ().id))
  1320. {
  1321. PRINT_INDEX (index);
  1322. }
  1323. ++index;
  1324. }
  1325. TEST_ASSERT (count_of_customers, ref_result.size ());
  1326. }
  1327. }
  1328. void test_select ()
  1329. {
  1330. using namespace cpplinq;
  1331. TEST_PRELUDE ();
  1332. {
  1333. std::vector<double> select_result = from (empty_vector) >> select ([](int i){return 1.0*i;}) >> to_vector ();
  1334. TEST_ASSERT (0U, select_result.size ());
  1335. }
  1336. {
  1337. std::vector<std::size_t> select_result =
  1338. from_array (customers)
  1339. >> select ([](customer const & c){return c.id;})
  1340. >> to_vector ()
  1341. ;
  1342. std::size_t index = 0U;
  1343. for (auto sz : select_result)
  1344. {
  1345. if (!TEST_ASSERT (customers[index].id, sz))
  1346. {
  1347. PRINT_INDEX (index);
  1348. }
  1349. ++index;
  1350. }
  1351. TEST_ASSERT (count_of_customers, select_result.size ());
  1352. }
  1353. }
  1354. void test_join ()
  1355. {
  1356. using namespace cpplinq;
  1357. TEST_PRELUDE ();
  1358. {
  1359. auto cs = empty<customer> ();
  1360. auto cas = empty<customer_address> ();
  1361. auto join_result = cs
  1362. >> join (
  1363. cas
  1364. , [](customer const & c) {return c.id;}
  1365. , [](customer_address const & ca) {return ca.customer_id;}
  1366. , [](customer const & c, customer_address const & ca) {return std::make_pair (c, ca);}
  1367. )
  1368. >> to_vector ()
  1369. ;
  1370. TEST_ASSERT (0U, join_result.size ());
  1371. }
  1372. {
  1373. auto cas = empty<customer_address> ();
  1374. auto join_result = from_array (customers)
  1375. >> join (
  1376. cas
  1377. , [](customer const & c) {return c.id;}
  1378. , [](customer_address const & ca) {return ca.customer_id;}
  1379. , [](customer const & c, customer_address const & ca) {return std::make_pair (c, ca);}
  1380. )
  1381. >> to_vector ()
  1382. ;
  1383. TEST_ASSERT (0U, join_result.size ());
  1384. }
  1385. {
  1386. auto cs = empty<customer> ();
  1387. auto join_result = cs
  1388. >> join (
  1389. from_array (customer_addresses)
  1390. , [](customer const & c) {return c.id;}
  1391. , [](customer_address const & ca) {return ca.customer_id;}
  1392. , [](customer const & c, customer_address const & ca) {return std::make_pair (c, ca);}
  1393. )
  1394. >> to_vector ()
  1395. ;
  1396. TEST_ASSERT (0U, join_result.size ());
  1397. }
  1398. {
  1399. auto join_result = from_array (customers)
  1400. >> join (
  1401. from_array (customer_addresses)
  1402. , [](customer const & c) {return c.id;}
  1403. , [](customer_address const & ca) {return ca.customer_id;}
  1404. , [](customer const & c, customer_address const & ca) {return std::make_pair (c, ca);}
  1405. )
  1406. >> to_vector ()
  1407. ;
  1408. if (TEST_ASSERT (3U, join_result.size ()))
  1409. {
  1410. {
  1411. auto result = join_result[0];
  1412. TEST_ASSERT (1U, result.first.id);
  1413. TEST_ASSERT (1U, result.second.id);
  1414. }
  1415. {
  1416. auto result = join_result[1];
  1417. TEST_ASSERT (4U, result.first.id);
  1418. TEST_ASSERT (2U, result.second.id);
  1419. }
  1420. {
  1421. auto result = join_result[2];
  1422. TEST_ASSERT (4U, result.first.id);
  1423. TEST_ASSERT (3U, result.second.id);
  1424. }
  1425. }
  1426. }
  1427. }
  1428. void test_select_many ()
  1429. {
  1430. using namespace cpplinq;
  1431. TEST_PRELUDE ();
  1432. {
  1433. std::vector<char> select_many_result =
  1434. from_iterators (customers, customers)
  1435. >> select_many ([](customer const & c){return from (c.last_name);})
  1436. >> to_vector ()
  1437. ;
  1438. TEST_ASSERT (0U, select_many_result.size ());
  1439. }
  1440. {
  1441. std::vector<char> expected;
  1442. for (auto customer : customers)
  1443. {
  1444. expected.insert (
  1445. expected.end ()
  1446. , customer.last_name.begin ()
  1447. , customer.last_name.end ()
  1448. );
  1449. }
  1450. std::vector<char> select_many_result =
  1451. from_array (customers)
  1452. >> select_many ([](customer const & c){return from (c.last_name);})
  1453. >> to_vector ()
  1454. ;
  1455. if (TEST_ASSERT (expected.size (), select_many_result.size ()))
  1456. {
  1457. for (std::size_t index = 0U; index < expected.size (); ++index)
  1458. {
  1459. if (!TEST_ASSERT (expected[index], select_many_result[index]))
  1460. {
  1461. PRINT_INDEX (index);
  1462. }
  1463. }
  1464. }
  1465. }
  1466. }
  1467. void test_orderby ()
  1468. {
  1469. using namespace cpplinq;
  1470. TEST_PRELUDE ();
  1471. {
  1472. auto c = from (empty_vector) >> orderby_ascending ([](int i){return i;}) >> count ();
  1473. TEST_ASSERT (0U, c);
  1474. }
  1475. {
  1476. auto c =
  1477. from (empty_customers)
  1478. >> orderby_ascending ([] (customer const & c) {return c.last_name;})
  1479. >> thenby_ascending ([] (customer const & c) {return c.first_name;})
  1480. >> count ()
  1481. ;
  1482. TEST_ASSERT (0U, c);
  1483. }
  1484. const std::size_t test_set_size = 7;
  1485. auto verify = [=](
  1486. std::size_t expected[test_set_size]
  1487. , std::vector<customer> const & sequence
  1488. )
  1489. {
  1490. auto sz = sequence.size ();
  1491. if (TEST_ASSERT (test_set_size, sz))
  1492. {
  1493. std::size_t index = 0U;
  1494. for (auto c : sequence)
  1495. {
  1496. if (!TEST_ASSERT (expected[index], c.id))
  1497. {
  1498. PRINT_INDEX (index);
  1499. }
  1500. ++index;
  1501. }
  1502. }
  1503. };
  1504. {
  1505. std::size_t expected[] =
  1506. {
  1507. 1,
  1508. 2,
  1509. 3,
  1510. 4,
  1511. 11,
  1512. 12,
  1513. 21,
  1514. };
  1515. auto sequence =
  1516. from_array (customers)
  1517. >> orderby_ascending ([] (customer const & c) {return c.id;})
  1518. >> to_vector ()
  1519. ;
  1520. verify (expected, sequence);
  1521. }
  1522. {
  1523. std::size_t expected[] =
  1524. {
  1525. 21,
  1526. 12,
  1527. 11,
  1528. 4,
  1529. 3,
  1530. 2,
  1531. 1,
  1532. };
  1533. auto sequence =
  1534. from_array (customers)
  1535. >> orderby_descending ([] (customer const & c) {return c.id;})
  1536. >> to_vector ()
  1537. ;
  1538. verify (expected, sequence);
  1539. }
  1540. {
  1541. std::size_t expected[] =
  1542. {
  1543. 11,
  1544. 12,
  1545. 1,
  1546. 21,
  1547. 2,
  1548. 3,
  1549. 4,
  1550. };
  1551. auto sequence =
  1552. from_array (customers)
  1553. >> orderby_ascending ([] (customer const & c) {return c.last_name;})
  1554. >> thenby_ascending ([] (customer const & c) {return c.first_name;})
  1555. >> to_vector ()
  1556. ;
  1557. verify (expected, sequence);
  1558. }
  1559. {
  1560. std::size_t expected[] =
  1561. {
  1562. 4,
  1563. 3,
  1564. 2,
  1565. 21,
  1566. 1,
  1567. 12,
  1568. 11,
  1569. };
  1570. auto sequence =
  1571. from_array (customers)
  1572. >> orderby_descending ([] (customer const & c) {return c.last_name;})
  1573. >> thenby_descending ([] (customer const & c) {return c.first_name;})
  1574. >> to_vector ()
  1575. ;
  1576. verify (expected, sequence);
  1577. }
  1578. {
  1579. std::size_t expected[] =
  1580. {
  1581. 11,
  1582. 12,
  1583. 21,
  1584. 1,
  1585. 2,
  1586. 3,
  1587. 4,
  1588. };
  1589. auto sequence =
  1590. from_array (customers)
  1591. >> orderby ([] (customer const & c) {return c.last_name;}, true)
  1592. >> thenby ([] (customer const & c) {return c.first_name;}, false)
  1593. >> to_vector ()
  1594. ;
  1595. verify (expected, sequence);
  1596. }
  1597. }
  1598. void test_reverse ()
  1599. {
  1600. using namespace cpplinq;
  1601. TEST_PRELUDE ();
  1602. // reverse an empty range
  1603. {
  1604. auto result = empty<int>() >> reverse () >> to_vector ();
  1605. TEST_ASSERT (0U, result.size ());
  1606. }
  1607. // reverse an empty range
  1608. {
  1609. auto result = from (empty_vector) >> reverse () >> to_vector ();
  1610. TEST_ASSERT (0U, result.size ());
  1611. }
  1612. // reverse a non-empty range
  1613. {
  1614. int expected[] = {9,8,7,6,5,4,3,2,1,0};
  1615. auto expected_size = get_array_size (expected);
  1616. auto result = range (0, 10) >> reverse () >> to_vector ();
  1617. TEST_ASSERT (expected_size, result.size ());
  1618. for (auto i = 0U; i < expected_size && i < result.size (); ++i)
  1619. {
  1620. TEST_ASSERT (expected[i], result[i]);
  1621. }
  1622. }
  1623. // code coverage test
  1624. {
  1625. auto q = empty<int>() >> reverse ();
  1626. TEST_ASSERT (false, q.next ());
  1627. TEST_ASSERT (false, q.next ());
  1628. }
  1629. }
  1630. void test_skip ()
  1631. {
  1632. using namespace cpplinq;
  1633. TEST_PRELUDE ();
  1634. {
  1635. auto q = from (empty_vector) >> skip (5);
  1636. std::size_t index = 0U;
  1637. while (q.next ())
  1638. {
  1639. test_int_at (index, q.front ());
  1640. ++index;
  1641. }
  1642. TEST_ASSERT (0U, index);
  1643. }
  1644. {
  1645. auto q = from_array (ints) >> skip (5);
  1646. auto index = 5U;
  1647. while (q.next ())
  1648. {
  1649. test_int_at (index, q.front ());
  1650. ++index;
  1651. }
  1652. TEST_ASSERT (count_of_ints, index);
  1653. }
  1654. // code coverage test
  1655. {
  1656. auto q = from (empty_vector) >> skip (1);
  1657. TEST_ASSERT (false, q.next ());
  1658. TEST_ASSERT (false, q.next ());
  1659. }
  1660. }
  1661. void test_skip_while ()
  1662. {
  1663. using namespace cpplinq;
  1664. TEST_PRELUDE ();
  1665. {
  1666. auto q = from (empty_vector) >> skip_while (smaller_than_five);
  1667. std::size_t index = 0U;
  1668. while (q.next ())
  1669. {
  1670. test_int_at (index, q.front ());
  1671. ++index;
  1672. }
  1673. TEST_ASSERT (0U, index);
  1674. }
  1675. {
  1676. auto q = from_array (ints) >> skip_while (smaller_than_five);
  1677. std::size_t index = 4U;
  1678. while (q.next ())
  1679. {
  1680. test_int_at (index, q.front ());
  1681. ++index;
  1682. }
  1683. TEST_ASSERT (count_of_ints, index);
  1684. }
  1685. }
  1686. void test_take ()
  1687. {
  1688. using namespace cpplinq;
  1689. TEST_PRELUDE ();
  1690. {
  1691. auto q = from (empty_vector) >> take (5);
  1692. std::size_t index = 0U;
  1693. while (q.next ())
  1694. {
  1695. test_int_at (index, q.front ());
  1696. ++index;
  1697. }
  1698. TEST_ASSERT (0U, index);
  1699. }
  1700. {
  1701. auto q = from_array (ints) >> take (5);
  1702. std::size_t index = 0U;
  1703. while (q.next ())
  1704. {
  1705. test_int_at (index, q.front ());
  1706. ++index;
  1707. }
  1708. TEST_ASSERT (5U, index);
  1709. }
  1710. {
  1711. auto c = from_array (ints) >> take (5) >> count ();
  1712. TEST_ASSERT (5U, c);
  1713. }
  1714. }
  1715. void test_take_while ()
  1716. {
  1717. using namespace cpplinq;
  1718. TEST_PRELUDE ();
  1719. {
  1720. auto q = from (empty_vector) >> take_while (smaller_than_five);
  1721. std::size_t index = 0U;
  1722. while (q.next ())
  1723. {
  1724. test_int_at (index, q.front ());
  1725. ++index;
  1726. }
  1727. TEST_ASSERT (0U, index);
  1728. }
  1729. {
  1730. auto q = from_array (ints) >> take_while (smaller_than_five);
  1731. std::size_t index = 0U;
  1732. while (q.next ())
  1733. {
  1734. test_int_at (index, q.front ());
  1735. ++index;
  1736. }
  1737. TEST_ASSERT (4U, index);
  1738. }
  1739. // code coverage test
  1740. {
  1741. auto q = from_array (ints) >> take_while ([] (int i) {return i < 0;});
  1742. TEST_ASSERT (false, q.next ());
  1743. TEST_ASSERT (false, q.next ());
  1744. }
  1745. }
  1746. void test_contains ()
  1747. {
  1748. using namespace cpplinq;
  1749. TEST_PRELUDE ();
  1750. {
  1751. bool result = from (empty_vector) >> contains (1);
  1752. TEST_ASSERT (false, result);
  1753. }
  1754. {
  1755. bool result = from_array (ints) >> contains (1);
  1756. TEST_ASSERT (true, result);
  1757. }
  1758. {
  1759. bool result =
  1760. from (empty_customers)
  1761. >> contains (
  1762. customer (1, "Bill", "Gates"),
  1763. [](customer const& c1, customer const& c2) {return c1.id == c2.id;});
  1764. TEST_ASSERT (false, result);
  1765. }
  1766. {
  1767. bool result =
  1768. from_array (customers)
  1769. >> contains (
  1770. customer (1, "Bill", "Gates"),
  1771. [](customer const& c1, customer const& c2) {return c1.id == c2.id;});
  1772. TEST_ASSERT (true, result);
  1773. }
  1774. {
  1775. bool result =
  1776. from_array (customers)
  1777. >> contains (
  1778. customer (42, "Bill", "Gates"),
  1779. [](customer const& c1, customer const& c2) {return c1.id == c2.id;});
  1780. TEST_ASSERT (false, result);
  1781. }
  1782. }
  1783. void test_element_at_or_default ()
  1784. {
  1785. using namespace cpplinq;
  1786. TEST_PRELUDE ();
  1787. {
  1788. auto result = from (empty_vector) >> element_at_or_default (0);
  1789. TEST_ASSERT (0, result);
  1790. }
  1791. {
  1792. auto result = from (empty_vector) >> element_at_or_default (1);
  1793. TEST_ASSERT (0, result);
  1794. }
  1795. {
  1796. auto result = from_array (ints) >> element_at_or_default (0);
  1797. TEST_ASSERT (3, result);
  1798. }
  1799. {
  1800. auto result = from_array (ints) >> element_at_or_default (1);
  1801. TEST_ASSERT (1, result);
  1802. }
  1803. {
  1804. auto result = from_array (ints) >> element_at_or_default (count_of_ints-1);
  1805. TEST_ASSERT (5, result);
  1806. }
  1807. {
  1808. auto result = from_array (ints) >> element_at_or_default (count_of_ints);
  1809. TEST_ASSERT (0, result);
  1810. }
  1811. }
  1812. void test_aggregate ()
  1813. {
  1814. using namespace cpplinq;
  1815. TEST_PRELUDE ();
  1816. {
  1817. int sum_result = from (empty_vector) >> aggregate (0, sum_aggregator);
  1818. TEST_ASSERT (0, sum_result);
  1819. }
  1820. {
  1821. int sum_of_simple_ints = std::accumulate (simple_ints, simple_ints + count_of_simple_ints, 0);
  1822. int sum_result = from_array (simple_ints) >> aggregate (0, sum_aggregator);
  1823. TEST_ASSERT (sum_of_simple_ints, sum_result);
  1824. }
  1825. {
  1826. int prod_of_simple_ints = std::accumulate (simple_ints, simple_ints + count_of_simple_ints, 1, mul_aggregator);
  1827. int sum_result = from_array (simple_ints) >> aggregate (1, mul_aggregator);
  1828. TEST_ASSERT (prod_of_simple_ints, sum_result);
  1829. }
  1830. {
  1831. auto sum_result = from (empty_vector) >> aggregate (0, sum_aggregator, to_string);
  1832. TEST_ASSERT ("0", sum_result);
  1833. }
  1834. {
  1835. auto sum_of_simple_ints = to_string (std::accumulate (simple_ints, simple_ints + count_of_simple_ints, 0));
  1836. auto sum_result = from_array (simple_ints) >> aggregate (0, sum_aggregator, to_string);
  1837. TEST_ASSERT (sum_of_simple_ints, sum_result);
  1838. }
  1839. {
  1840. auto prod_of_simple_ints = to_string (std::accumulate (simple_ints, simple_ints + count_of_simple_ints, 1, mul_aggregator));
  1841. auto sum_result = from_array (simple_ints) >> aggregate (1, mul_aggregator, to_string);
  1842. TEST_ASSERT (prod_of_simple_ints, sum_result);
  1843. }
  1844. }
  1845. void test_distinct ()
  1846. {
  1847. using namespace cpplinq;
  1848. TEST_PRELUDE ();
  1849. {
  1850. auto d = from (empty_vector) >> distinct () >> to_vector ();
  1851. TEST_ASSERT (0U, d.size ());
  1852. }
  1853. {
  1854. int expected[] = {5,4,3,2,1};
  1855. auto expected_size = get_array_size (expected);
  1856. auto result = from_array (set1) >> distinct () >> to_vector ();
  1857. auto result_size = result.size ();
  1858. TEST_ASSERT (expected_size, result_size);
  1859. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  1860. {
  1861. TEST_ASSERT (expected[i], result[i]);
  1862. }
  1863. }
  1864. {
  1865. auto d = from_array (customers_set1) >> distinct () >> to_vector ();
  1866. TEST_ASSERT (4U, d.size ());
  1867. }
  1868. }
  1869. void test_union_with ()
  1870. {
  1871. using namespace cpplinq;
  1872. TEST_PRELUDE ();
  1873. // union of two empty ranges
  1874. {
  1875. auto result = from (empty_vector) >> union_with (from (empty_vector) ) >> to_vector ();
  1876. TEST_ASSERT (0U, result.size ());
  1877. }
  1878. // union of an empty range with a non-empty range
  1879. {
  1880. auto result = empty<int>() >> union_with (range (0, 10) ) >> to_vector ();
  1881. TEST_ASSERT (10U, result.size ());
  1882. for (auto i = 0U; i < 10 && i < result.size (); ++i)
  1883. {
  1884. TEST_ASSERT (static_cast<int> (i), result[i]);
  1885. }
  1886. }
  1887. // union of an empty range with a non-empty range
  1888. {
  1889. int expected[] = {5,4,3,2,1};
  1890. auto expected_size = get_array_size (expected);
  1891. auto result = from (empty_vector) >> union_with ( from_array (set1) ) >> to_vector ();
  1892. TEST_ASSERT (expected_size, result.size ());
  1893. for (auto i = 0U; i < result.size () && i < expected_size; ++i)
  1894. {
  1895. TEST_ASSERT (expected[i], result[i]);
  1896. }
  1897. }
  1898. // union of a non-empty range with an empty range
  1899. {
  1900. auto result = range (0, 10) >> union_with (empty<int>() ) >> to_vector ();
  1901. TEST_ASSERT (10U, result.size ());
  1902. for (auto i = 0U; i < 10 && i < result.size (); ++i)
  1903. {
  1904. TEST_ASSERT (static_cast<int> (i), result[i]);
  1905. }
  1906. }
  1907. // union of a non-empty range with an empty range
  1908. {
  1909. int expected[] = {5,4,3,2,1};
  1910. auto expected_size = get_array_size (expected);
  1911. auto result = from_array (set1) >> union_with (from (empty_vector)) >> to_vector ();
  1912. TEST_ASSERT (expected_size, result.size ());
  1913. for (auto i = 0U; i < expected_size && i < result.size (); ++i)
  1914. {
  1915. TEST_ASSERT (expected[i], result[i]);
  1916. }
  1917. }
  1918. // union of two non-empty ranges
  1919. {
  1920. int expected[] = {5,4,3,2,1,9,8,6,7};
  1921. auto expected_size = get_array_size (expected);
  1922. auto result = from_array (set1) >> union_with (from_array (set2)) >> to_vector ();
  1923. auto result_size = result.size ();
  1924. TEST_ASSERT (expected_size, result_size);
  1925. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  1926. {
  1927. TEST_ASSERT (expected[i], result[i]);
  1928. }
  1929. }
  1930. // union of range with duplicates with itself
  1931. {
  1932. auto result = from_array (ints) >> union_with (from_array (ints)) >> to_vector ();
  1933. auto result_size = result.size ();
  1934. TEST_ASSERT (9U, result_size);
  1935. }
  1936. }
  1937. void test_intersect_with ()
  1938. {
  1939. using namespace cpplinq;
  1940. TEST_PRELUDE ();
  1941. // intersection of two empty ranges
  1942. {
  1943. auto result = from (empty_vector) >> intersect_with (from (empty_vector) ) >> to_vector ();
  1944. TEST_ASSERT (0U, result.size ());
  1945. }
  1946. // intersection of an empty range with a non-empty range
  1947. {
  1948. auto result = empty<int>() >> intersect_with (range (0, 10) ) >> to_vector ();
  1949. TEST_ASSERT (0U, result.size ());
  1950. }
  1951. // intersection of an empty range with a non-empty range
  1952. {
  1953. auto result = from (empty_vector) >> intersect_with (from_array (set1)) >> to_vector ();
  1954. TEST_ASSERT (0U, result.size ());
  1955. }
  1956. // intersection of a non-empty range with an empty range
  1957. {
  1958. auto result = range (0, 10) >> intersect_with (empty<int>() ) >> to_vector ();
  1959. TEST_ASSERT (0U, result.size ());
  1960. }
  1961. // intersection of a non-empty range with an empty range
  1962. {
  1963. auto result = from_array (set1) >> intersect_with (from (empty_vector)) >> to_vector ();
  1964. TEST_ASSERT (0U, result.size ());
  1965. }
  1966. // intersection of two non-empty ranges
  1967. {
  1968. int expected[] = {5,4,1};
  1969. auto expected_size = get_array_size (expected);
  1970. auto result = from_array (set1) >> intersect_with (from_array (set2)) >> to_vector ();
  1971. auto result_size = result.size ();
  1972. TEST_ASSERT (expected_size, result_size);
  1973. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  1974. {
  1975. TEST_ASSERT (expected[i], result[i]);
  1976. }
  1977. }
  1978. // intersection of two non-empty ranges
  1979. {
  1980. int expected[] = {4,5,1};
  1981. auto expected_size = get_array_size (expected);
  1982. auto result = from_array (set2) >> intersect_with (from_array (set1)) >> to_vector ();
  1983. auto result_size = result.size ();
  1984. TEST_ASSERT (expected_size, result_size);
  1985. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  1986. {
  1987. TEST_ASSERT (expected[i], result[i]);
  1988. }
  1989. }
  1990. // intersection of non-empty range with duplicates with itself
  1991. {
  1992. int numbers [] = {3,1,4,1,5,9,2,6,5,4};
  1993. int expected [] = {3,1,4,5,9,2,6};
  1994. auto expected_size = get_array_size (expected);
  1995. auto result = from_array (numbers) >> intersect_with (from_array (numbers)) >> to_vector ();
  1996. auto result_size = result.size ();
  1997. TEST_ASSERT (expected_size, result_size);
  1998. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  1999. {
  2000. TEST_ASSERT (expected[i], result[i]);
  2001. }
  2002. }
  2003. // code coverage test
  2004. {
  2005. auto q = from (empty_vector) >> intersect_with (from (empty_vector) );
  2006. TEST_ASSERT (false, q.next ());
  2007. TEST_ASSERT (false, q.next ());
  2008. }
  2009. }
  2010. void test_except ()
  2011. {
  2012. using namespace cpplinq;
  2013. TEST_PRELUDE ();
  2014. // difference of two empty ranges
  2015. {
  2016. auto result = from (empty_vector) >> except (from (empty_vector)) >> to_vector ();
  2017. TEST_ASSERT (0U, result.size ());
  2018. }
  2019. // difference of an empty range with a non-empty range
  2020. {
  2021. auto result = empty<int>() >> except (range (0, 10)) >> to_vector ();
  2022. TEST_ASSERT (0U, result.size ());
  2023. }
  2024. // difference of an empty range with a non-empty range
  2025. {
  2026. auto result = from (empty_vector) >> except (from_array (set1)) >> to_vector ();
  2027. TEST_ASSERT (0U, result.size ());
  2028. }
  2029. // difference of a non-empty range with an empty range
  2030. {
  2031. auto result = range (0, 10) >> except (empty<int>()) >> to_vector ();
  2032. TEST_ASSERT (10U, result.size ());
  2033. for (auto i = 0U; i < 10 && i < result.size (); ++i)
  2034. {
  2035. TEST_ASSERT (static_cast<int> (i), result[i]);
  2036. }
  2037. }
  2038. // difference of a non-empty range with an empty range
  2039. {
  2040. int expected[] = {5,4,3,2,1};
  2041. auto expected_size = get_array_size (expected);
  2042. auto result = from_array (set1) >> except (from (empty_vector)) >> to_vector ();
  2043. TEST_ASSERT (expected_size, result.size ());
  2044. for (auto i = 0U; i < expected_size && i < result.size (); ++i)
  2045. {
  2046. TEST_ASSERT (expected[i], result[i]);
  2047. }
  2048. }
  2049. // difference of two non-empty ranges
  2050. {
  2051. int expected[] = {3,2};
  2052. auto expected_size = get_array_size (expected);
  2053. auto result = from_array (set1) >> except (from_array (set2)) >> to_vector ();
  2054. auto result_size = result.size ();
  2055. TEST_ASSERT (expected_size, result_size);
  2056. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  2057. {
  2058. TEST_ASSERT (expected[i], result[i]);
  2059. }
  2060. }
  2061. // difference of two non-empty ranges
  2062. {
  2063. int expected[] = {9,8,6,7};
  2064. auto expected_size = get_array_size (expected);
  2065. auto result = from_array (set2) >> except (from_array (set1)) >> to_vector ();
  2066. auto result_size = result.size ();
  2067. TEST_ASSERT (expected_size, result_size);
  2068. for (auto i = 0U; i < expected_size && i < result_size; ++i)
  2069. {
  2070. TEST_ASSERT (expected[i], result[i]);
  2071. }
  2072. }
  2073. // difference of non-empty range with duplicates with itself
  2074. {
  2075. int numbers [] = {3,1,4,1,5,9,2,6,5,4};
  2076. auto result = from_array (numbers) >> except (from_array (numbers)) >> to_vector ();
  2077. auto result_size = result.size ();
  2078. TEST_ASSERT (0U, result_size);
  2079. }
  2080. // difference of non-empty range with duplicates with empty set
  2081. {
  2082. auto result = from_array (ints) >> except (from (empty_vector)) >> to_vector ();
  2083. auto result_size = result.size ();
  2084. TEST_ASSERT (9U, result_size);
  2085. }
  2086. }
  2087. void test_concat ()
  2088. {
  2089. using namespace cpplinq;
  2090. TEST_PRELUDE ();
  2091. // concat two empty ranges
  2092. {
  2093. auto result = empty<int>() >> concat (empty<int>()) >> to_vector ();
  2094. TEST_ASSERT (0U, result.size ());
  2095. }
  2096. // concat two empty ranges
  2097. {
  2098. auto result = from (empty_vector) >> concat (empty<int>()) >> to_vector ();
  2099. TEST_ASSERT (0U, result.size ());
  2100. }
  2101. // concat an empty range with a non empty range
  2102. {
  2103. auto expected = range (0,10);
  2104. auto expected_result = expected >> to_vector ();
  2105. auto result = empty<int>() >> concat (expected) >> to_vector ();
  2106. TEST_ASSERT (expected_result.size (), result.size ());
  2107. for (auto i = 0U; i < expected_result.size () && i < result.size ();++i)
  2108. {
  2109. TEST_ASSERT (expected_result[i], result[i]);
  2110. }
  2111. }
  2112. // concat an empty range with a non empty range
  2113. {
  2114. auto result = empty<int>() >> concat (from_array (ints)) >> to_vector ();
  2115. TEST_ASSERT (count_of_ints, result.size ());
  2116. for (auto i = 0U; i < count_of_ints && i < result.size ();++i)
  2117. {
  2118. TEST_ASSERT (ints[i], result[i]);
  2119. }
  2120. }
  2121. // concat a non empty range with an empty range
  2122. {
  2123. auto expected = range (0,10);
  2124. auto expected_result = expected >> to_vector ();
  2125. auto result = expected >> concat (empty<int>()) >> to_vector ();
  2126. TEST_ASSERT (expected_result.size (), result.size ());
  2127. for (auto i = 0U; i < expected_result.size () && i < result.size ();++i)
  2128. {
  2129. TEST_ASSERT (expected_result[i], result[i]);
  2130. }
  2131. }
  2132. // concat a non empty range with an empty range
  2133. {
  2134. auto result = from_array (ints) >> concat (empty<int>()) >> to_vector ();
  2135. TEST_ASSERT (count_of_ints, result.size ());
  2136. for (auto i = 0U; i < count_of_ints && i < result.size ();++i)
  2137. {
  2138. TEST_ASSERT (ints[i], result[i]);
  2139. }
  2140. }
  2141. // concat two non-empty ranges
  2142. {
  2143. int set1[] = {0,1,2,3,4,5};
  2144. int set2[] = {6,7,8,9};
  2145. auto result = from_array (set1) >> concat (from_array (set2)) >> to_vector ();
  2146. TEST_ASSERT (10U, result.size ());
  2147. for (auto i = 0U; i < 10 && i < result.size (); ++i)
  2148. {
  2149. TEST_ASSERT (static_cast<int> (i), result[i]);
  2150. }
  2151. }
  2152. // code coverage test
  2153. {
  2154. auto q = empty<int>() >> concat (empty<int>());
  2155. TEST_ASSERT (false, q.next ());
  2156. TEST_ASSERT (false, q.next ());
  2157. }
  2158. }
  2159. void test_sequence_equal ()
  2160. {
  2161. using namespace cpplinq;
  2162. TEST_PRELUDE ();
  2163. // test two empty sequences
  2164. {
  2165. auto result = empty<int>() >> sequence_equal (empty<int>());
  2166. TEST_ASSERT (true, result);
  2167. }
  2168. // test two empty sequences
  2169. {
  2170. auto result = from (empty_vector) >> sequence_equal (empty<int>());
  2171. TEST_ASSERT (true, result);
  2172. }
  2173. // test empty sequence with non-empty sequence
  2174. {
  2175. auto result = empty<int>() >> sequence_equal (range (0,10));
  2176. TEST_ASSERT (false, result);
  2177. }
  2178. // test empty sequence with non-empty sequence
  2179. {
  2180. auto result = from (empty_vector) >> sequence_equal (from_array (ints));
  2181. TEST_ASSERT (false, result);
  2182. }
  2183. // test non-empty sequence with empty sequence
  2184. {
  2185. auto result = range (0, 10) >> sequence_equal (empty<int>());
  2186. TEST_ASSERT (false, result);
  2187. }
  2188. // test non-empty sequence with empty sequence
  2189. {
  2190. auto result = from_array (ints) >> sequence_equal (from (empty_vector));
  2191. TEST_ASSERT (false, result);
  2192. }
  2193. // test non-empty inequal sequences
  2194. {
  2195. auto result = range (0,5) >> sequence_equal (range (0,4));
  2196. TEST_ASSERT (false, result);
  2197. }
  2198. // test non-empty inequal sequences
  2199. {
  2200. auto result = from_array (set1) >> sequence_equal (from_array (set2));
  2201. TEST_ASSERT (false, result);
  2202. }
  2203. // test non-empty equal sequences
  2204. {
  2205. auto result = from_array (ints) >> sequence_equal (from_array (ints));
  2206. TEST_ASSERT (true, result);
  2207. }
  2208. // test non-empty equal sequences
  2209. {
  2210. auto result = range (0,10) >> sequence_equal (range (0,10));
  2211. TEST_ASSERT (true, result);
  2212. }
  2213. // test against self
  2214. {
  2215. auto seq = from_array (ints);
  2216. auto result = seq >> sequence_equal (seq);
  2217. TEST_ASSERT (true, result);
  2218. }
  2219. auto comparer = [](customer const& c1, customer const& c2)
  2220. {return c1.first_name == c2.first_name && c1.last_name == c2.last_name;};
  2221. customer customers1[] = {
  2222. customer (1 , "Bill" , "Gates" ),
  2223. customer (2 , "Steve" , "Jobs" ),
  2224. customer (3 , "Richard" , "Stallman"),
  2225. };
  2226. customer customers2[] = {
  2227. customer (11 , "Bill" , "Gates" ),
  2228. customer (12 , "Steve" , "Jobs" ),
  2229. customer (13 , "Richard" , "Stallman"),
  2230. };
  2231. customer customers3[] = {
  2232. customer (1 , "Bill" , "Gates" ),
  2233. customer (2 , "Steve" , "Jobs" ),
  2234. customer (3 , "Steve" , "Ballmer" ),
  2235. };
  2236. // test empty with comparer
  2237. {
  2238. auto result = empty<customer>() >> sequence_equal (empty<customer>(), comparer);
  2239. TEST_ASSERT (true, result);
  2240. }
  2241. // test empty with non-empty with comparer
  2242. {
  2243. auto result = from (empty_customers) >> sequence_equal (from_array (customers), comparer);
  2244. TEST_ASSERT (false, result);
  2245. }
  2246. // test non-empty with empty with comparer
  2247. {
  2248. auto result = from_array (customers) >> sequence_equal (from (empty_customers), comparer);
  2249. TEST_ASSERT (false, result);
  2250. }
  2251. // test two equal non-empty sequences with comparer
  2252. {
  2253. auto result = from_array (customers1) >> sequence_equal (from_array (customers2), comparer);
  2254. TEST_ASSERT (true, result);
  2255. }
  2256. // test two inequal non-empty sequences with comparer
  2257. {
  2258. auto result = from_array (customers1) >> sequence_equal (from_array (customers3), comparer);
  2259. TEST_ASSERT (false, result);
  2260. }
  2261. // test against self with comparer
  2262. {
  2263. auto seq = from_array (customers1);
  2264. auto result = seq >> sequence_equal (seq, comparer);
  2265. TEST_ASSERT (true, result);
  2266. }
  2267. }
  2268. void test_pairwise ()
  2269. {
  2270. using namespace cpplinq;
  2271. TEST_PRELUDE ();
  2272. {
  2273. auto pairwise_result =
  2274. from (empty_vector)
  2275. >> pairwise ()
  2276. >> to_vector ()
  2277. ;
  2278. TEST_ASSERT (0U, pairwise_result.size ());
  2279. }
  2280. {
  2281. int single_element_vector[] = {1};
  2282. auto pairwise_result =
  2283. from_array (single_element_vector)
  2284. >> pairwise ()
  2285. >> to_vector ()
  2286. ;
  2287. TEST_ASSERT (0U, pairwise_result.size ());
  2288. }
  2289. {
  2290. auto pairwise_result =
  2291. from_array (simple_ints)
  2292. >> pairwise ()
  2293. >> to_vector ()
  2294. ;
  2295. TEST_ASSERT (count_of_simple_ints-1, pairwise_result.size ());
  2296. for (std::size_t i=0; i < pairwise_result.size (); ++i)
  2297. {
  2298. TEST_ASSERT (simple_ints[i], pairwise_result[i].first);
  2299. TEST_ASSERT (simple_ints[i+1], pairwise_result[i].second);
  2300. }
  2301. }
  2302. }
  2303. void test_zip_with ()
  2304. {
  2305. using namespace cpplinq;
  2306. TEST_PRELUDE ();
  2307. {
  2308. auto zip_width_result =
  2309. from (empty_vector)
  2310. >> zip_with (from (empty_vector))
  2311. >> to_vector ()
  2312. ;
  2313. TEST_ASSERT (0U, zip_width_result.size ());
  2314. }
  2315. {
  2316. auto zip_width_result =
  2317. from (empty_vector)
  2318. >> zip_with (from_array (simple_ints))
  2319. >> to_vector ()
  2320. ;
  2321. TEST_ASSERT (0U, zip_width_result.size ());
  2322. }
  2323. {
  2324. auto zip_width_result =
  2325. from_array (simple_ints)
  2326. >> zip_with (from (empty_vector))
  2327. >> to_vector ()
  2328. ;
  2329. TEST_ASSERT (0U, zip_width_result.size ());
  2330. }
  2331. {
  2332. auto zip_width_result =
  2333. from_array (simple_ints)
  2334. >> zip_with (from_array (simple_ints))
  2335. >> to_vector ()
  2336. ;
  2337. TEST_ASSERT (count_of_simple_ints, zip_width_result.size ());
  2338. for (std::size_t i=0; i<zip_width_result.size (); ++i)
  2339. {
  2340. TEST_ASSERT (simple_ints[i], zip_width_result[i].first);
  2341. TEST_ASSERT (simple_ints[i], zip_width_result[i].second);
  2342. }
  2343. }
  2344. {
  2345. auto expected_size = std::min(count_of_ints, count_of_simple_ints);
  2346. auto zip_width_result =
  2347. from_array (ints)
  2348. >> zip_with (from_array (simple_ints))
  2349. >> to_vector ()
  2350. ;
  2351. TEST_ASSERT (expected_size, zip_width_result.size ());
  2352. for (std::size_t i=0; i<zip_width_result.size (); ++i)
  2353. {
  2354. TEST_ASSERT ( ints[i], zip_width_result[i].first);
  2355. TEST_ASSERT (simple_ints[i], zip_width_result[i].second);
  2356. }
  2357. }
  2358. {
  2359. auto expected_size = std::min(count_of_ints, count_of_simple_ints);
  2360. auto zip_width_result =
  2361. from_array (simple_ints)
  2362. >> zip_with (from_array (ints))
  2363. >> to_vector ()
  2364. ;
  2365. TEST_ASSERT (expected_size, zip_width_result.size ());
  2366. for (std::size_t i=0; i<zip_width_result.size (); ++i)
  2367. {
  2368. TEST_ASSERT (simple_ints[i], zip_width_result[i].first);
  2369. TEST_ASSERT ( ints[i], zip_width_result[i].second);
  2370. }
  2371. }
  2372. {
  2373. std::string pairrange[] = {"one", "two", "three"};
  2374. auto zip_width_result =
  2375. from_array(pairrange)
  2376. >> zip_with(from_array(simple_ints))
  2377. >> to_vector();
  2378. auto expected_size = get_array_size(pairrange);
  2379. TEST_ASSERT(expected_size, zip_width_result.size());
  2380. for (std::size_t i=0; i<zip_width_result.size (); ++i)
  2381. {
  2382. TEST_ASSERT ( pairrange[i], zip_width_result[i].first);
  2383. TEST_ASSERT (simple_ints[i], zip_width_result[i].second);
  2384. }
  2385. }
  2386. }
  2387. template<typename TPredicate>
  2388. long long execute_testruns (
  2389. std::size_t test_runs
  2390. , TPredicate predicate
  2391. )
  2392. {
  2393. auto then = std::chrono::high_resolution_clock::now ();
  2394. for (auto test_run = 0U; test_run < test_runs; ++test_run)
  2395. {
  2396. predicate ();
  2397. }
  2398. auto now = std::chrono::high_resolution_clock::now ();
  2399. auto diff = now - then;
  2400. auto diff_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count ();
  2401. return diff_in_ms;
  2402. }
  2403. void test_performance_range_sum ()
  2404. {
  2405. using namespace cpplinq;
  2406. TEST_PRELUDE ();
  2407. int const test_repeat = 80000 ;
  2408. int const test_size = 20000 ;
  2409. auto expected_complete_sum = 0 ;
  2410. auto result_complete_sum = 0 ;
  2411. auto expected = execute_testruns (
  2412. test_repeat
  2413. , [&] ()
  2414. {
  2415. auto set_sum = 0;
  2416. for (auto iter = 0; iter < test_size; ++iter)
  2417. {
  2418. set_sum += iter;
  2419. }
  2420. expected_complete_sum += set_sum;
  2421. }
  2422. );
  2423. auto result = execute_testruns (
  2424. test_repeat
  2425. , [&] ()
  2426. {
  2427. auto set_sum =
  2428. range(0, test_size)
  2429. >> sum ()
  2430. ;
  2431. result_complete_sum += set_sum;
  2432. }
  2433. );
  2434. TEST_ASSERT (expected_complete_sum, result_complete_sum);
  2435. auto ratio_limit = 3.0;
  2436. auto ratio = ((double)expected)/result;
  2437. TEST_ASSERT (true, (ratio > 1/ratio_limit && ratio < ratio_limit));
  2438. printf (
  2439. "Performance numbers for simple sum over numbers, expected:%lld, result:%lld, ratio_limit:%f, ratio:%f\n"
  2440. , expected
  2441. , result
  2442. , ratio_limit
  2443. , ratio
  2444. );
  2445. }
  2446. void test_performance_sum ()
  2447. {
  2448. using namespace cpplinq;
  2449. TEST_PRELUDE ();
  2450. int const test_repeat = 80000 ;
  2451. int const test_size = 20000 ;
  2452. auto expected_complete_sum = 0 ;
  2453. auto result_complete_sum = 0 ;
  2454. srand (19740531);
  2455. auto test_set =
  2456. range (0, test_size)
  2457. >> select ([] (int i){return rand ();})
  2458. >> to_vector (test_size)
  2459. ;
  2460. auto expected = execute_testruns (
  2461. test_repeat
  2462. , [&] ()
  2463. {
  2464. auto set_sum = 0;
  2465. for (auto v : test_set)
  2466. {
  2467. set_sum += v;
  2468. }
  2469. expected_complete_sum += set_sum;
  2470. }
  2471. );
  2472. auto result = execute_testruns (
  2473. test_repeat
  2474. , [&] ()
  2475. {
  2476. auto set_sum =
  2477. from (test_set)
  2478. >> sum ()
  2479. ;
  2480. result_complete_sum += set_sum;
  2481. }
  2482. );
  2483. TEST_ASSERT (expected_complete_sum, result_complete_sum);
  2484. auto ratio_limit = 2.0;
  2485. auto ratio = ((double)expected)/result;
  2486. TEST_ASSERT (true, (ratio > 1/ratio_limit && ratio < ratio_limit));
  2487. printf (
  2488. "Performance numbers for simple sum over numbers, expected:%lld, result:%lld, ratio_limit:%f, ratio:%f\n"
  2489. , expected
  2490. , result
  2491. , ratio_limit
  2492. , ratio
  2493. );
  2494. }
  2495. bool is_prime (int i)
  2496. {
  2497. if (i < 2)
  2498. {
  2499. return false;
  2500. }
  2501. else if (i == 2)
  2502. {
  2503. return true;
  2504. }
  2505. else
  2506. {
  2507. auto r = std::ceil (std::sqrt (i));
  2508. for (auto iter = 2; iter <= r; ++iter)
  2509. {
  2510. if (i % iter == 0)
  2511. {
  2512. return false;
  2513. }
  2514. }
  2515. return true;
  2516. }
  2517. }
  2518. void test_performance_is_prime ()
  2519. {
  2520. using namespace cpplinq;
  2521. TEST_PRELUDE ();
  2522. #if _DEBUG
  2523. int const test_repeat = 25 ;
  2524. #else
  2525. int const test_repeat = 100 ;
  2526. #endif
  2527. int const test_size = 10000 ;
  2528. auto expected_complete_sum = 0 ;
  2529. auto result_complete_sum = 0 ;
  2530. auto expected = execute_testruns (
  2531. test_repeat
  2532. , [&] ()
  2533. {
  2534. auto iter = 3;
  2535. auto count = 0;
  2536. auto expected_sum= 0;
  2537. while (count < test_size)
  2538. {
  2539. if (is_prime (iter))
  2540. {
  2541. expected_sum += iter;
  2542. ++count;
  2543. }
  2544. iter += 2;
  2545. }
  2546. expected_complete_sum += expected_sum;
  2547. }
  2548. );
  2549. auto result = execute_testruns (
  2550. test_repeat
  2551. , [&] ()
  2552. {
  2553. result_complete_sum +=
  2554. range (1, INT_MAX)
  2555. >> select ([] (int i) {return 2*i + 1;})
  2556. >> where (is_prime)
  2557. >> take (test_size)
  2558. >> sum ()
  2559. ;
  2560. }
  2561. );
  2562. TEST_ASSERT (expected_complete_sum, result_complete_sum);
  2563. auto ratio_limit = 1.25;
  2564. auto ratio = ((double)expected)/result;
  2565. TEST_ASSERT (true, (ratio > 1/ratio_limit && ratio < ratio_limit));
  2566. printf (
  2567. "Performance numbers for computing primes, expected:%lld, result:%lld, ratio_limit:%f, ratio:%f\n"
  2568. , expected
  2569. , result
  2570. , ratio_limit
  2571. , ratio
  2572. );
  2573. }
  2574. bool run_all_tests (bool run_perfomance_tests)
  2575. {
  2576. // -------------------------------------------------------------------------
  2577. test_opt ();
  2578. test_lookup ();
  2579. test_from ();
  2580. test_range ();
  2581. test_repeat ();
  2582. test_empty ();
  2583. test_singleton ();
  2584. test_generate ();
  2585. test_set ();
  2586. test_count ();
  2587. test_any ();
  2588. test_first ();
  2589. test_first_or_default ();
  2590. test_last_or_default ();
  2591. test_sum ();
  2592. test_avg ();
  2593. test_max ();
  2594. test_min ();
  2595. test_concatenate ();
  2596. test_all ();
  2597. test_for_each ();
  2598. test_to_vector ();
  2599. test_to_map ();
  2600. test_to_lookup ();
  2601. test_to_list ();
  2602. test_container ();
  2603. test_where ();
  2604. test_ref ();
  2605. test_select ();
  2606. test_select_many ();
  2607. test_join ();
  2608. test_orderby ();
  2609. test_reverse ();
  2610. test_take ();
  2611. test_skip ();
  2612. test_take_while ();
  2613. test_skip_while ();
  2614. test_contains ();
  2615. test_element_at_or_default ();
  2616. test_aggregate ();
  2617. test_distinct ();
  2618. test_union_with ();
  2619. test_intersect_with ();
  2620. test_except ();
  2621. test_concat ();
  2622. test_sequence_equal ();
  2623. test_pairwise ();
  2624. test_zip_with ();
  2625. // -------------------------------------------------------------------------
  2626. if (run_perfomance_tests)
  2627. {
  2628. #ifdef _MSC_VER
  2629. // In order to make performance number more predictable
  2630. SetPriorityClass (GetCurrentProcess (), HIGH_PRIORITY_CLASS);
  2631. #endif
  2632. test_performance_range_sum ();
  2633. test_performance_sum ();
  2634. test_performance_is_prime ();
  2635. }
  2636. // -------------------------------------------------------------------------
  2637. if (errors == 0)
  2638. {
  2639. printf ("PASS\n");
  2640. }
  2641. else
  2642. {
  2643. printf ("FAIL\n");
  2644. }
  2645. // -------------------------------------------------------------------------
  2646. return errors > 0;
  2647. // -------------------------------------------------------------------------
  2648. }
  2649. }
  2650. // ----------------------------------------------------------------------------------------------