Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

935 righe
24 KiB

  1. #include <vector>
  2. #include <gtest/gtest.h>
  3. #include <cpputils/misc/linq.h>
  4. namespace linq_tests
  5. {
  6. struct test_data
  7. {
  8. int value;
  9. test_data() :
  10. value(0)
  11. { }
  12. test_data(int v) :
  13. value(v)
  14. { }
  15. };
  16. struct TestData2
  17. {
  18. int value;
  19. std::string name;
  20. TestData2() :
  21. value(0)
  22. { }
  23. TestData2(int v, const std::string& s) :
  24. value(v),
  25. name (s)
  26. { }
  27. };
  28. struct TestDataMany
  29. {
  30. std::vector<int> values;
  31. TestDataMany(const std::vector<int>& v) :
  32. values(v)
  33. { }
  34. };
  35. struct MoveOnlyData
  36. {
  37. int value;
  38. MoveOnlyData() :
  39. value(0)
  40. { LINQ_CTOR(); }
  41. MoveOnlyData(int v) :
  42. value(v)
  43. { LINQ_CTOR(); }
  44. MoveOnlyData(MoveOnlyData&& o) :
  45. value(0)
  46. { std::swap(value, o.value); LINQ_MOVE_CTOR(); }
  47. MoveOnlyData(const MoveOnlyData&) = delete;
  48. ~MoveOnlyData()
  49. { LINQ_DTOR(); }
  50. };
  51. }
  52. using namespace ::utl;
  53. using namespace ::utl::linq;
  54. using namespace ::linq_tests;
  55. TEST(LinqTest, from_iterator)
  56. {
  57. std::vector<int> data({ 4, 5, 6, 7, 8 });
  58. auto range = from_iterator(data.begin(), data.end());
  59. ASSERT_TRUE (range.next());
  60. ASSERT_EQ (&data.at(0), &range.front());
  61. ASSERT_EQ (4, range.front());
  62. ASSERT_TRUE (range.next());
  63. ASSERT_EQ (&data.at(1), &range.front());
  64. ASSERT_EQ (5, range.front());
  65. ASSERT_TRUE (range.next());
  66. ASSERT_EQ (&data.at(2), &range.front());
  67. ASSERT_EQ (6, range.front());
  68. ASSERT_TRUE (range.next());
  69. ASSERT_EQ (&data.at(3), &range.front());
  70. ASSERT_EQ (7, range.front());
  71. ASSERT_TRUE (range.next());
  72. ASSERT_EQ (&data.at(4), &range.front());
  73. ASSERT_EQ (8, range.front());
  74. ASSERT_FALSE(range.next());
  75. }
  76. TEST(LinqTest, from_container)
  77. {
  78. std::vector<int> data;
  79. auto range = from_container(data);
  80. data.assign({ 4, 5, 6, 7, 8 });
  81. ASSERT_TRUE (range.next());
  82. ASSERT_EQ (&data.at(0), &range.front());
  83. ASSERT_EQ (4, range.front());
  84. ASSERT_TRUE (range.next());
  85. ASSERT_EQ (&data.at(1), &range.front());
  86. ASSERT_EQ (5, range.front());
  87. ASSERT_TRUE (range.next());
  88. ASSERT_EQ (&data.at(2), &range.front());
  89. ASSERT_EQ (6, range.front());
  90. ASSERT_TRUE (range.next());
  91. ASSERT_EQ (&data.at(3), &range.front());
  92. ASSERT_EQ (7, range.front());
  93. ASSERT_TRUE (range.next());
  94. ASSERT_EQ (&data.at(4), &range.front());
  95. ASSERT_EQ (8, range.front());
  96. ASSERT_FALSE(range.next());
  97. }
  98. TEST(LinqTest, from_array)
  99. {
  100. int data[] = { 4, 5, 6, 7, 8 };
  101. auto range = from_array(data);
  102. ASSERT_TRUE (range.next());
  103. ASSERT_EQ (&data[0], &range.front());
  104. ASSERT_EQ (4, range.front());
  105. ASSERT_TRUE (range.next());
  106. ASSERT_EQ (&data[1], &range.front());
  107. ASSERT_EQ (5, range.front());
  108. ASSERT_TRUE (range.next());
  109. ASSERT_EQ (&data[2], &range.front());
  110. ASSERT_EQ (6, range.front());
  111. ASSERT_TRUE (range.next());
  112. ASSERT_EQ (&data[3], &range.front());
  113. ASSERT_EQ (7, range.front());
  114. ASSERT_TRUE (range.next());
  115. ASSERT_EQ (&data[4], &range.front());
  116. ASSERT_EQ (8, range.front());
  117. ASSERT_FALSE(range.next());
  118. }
  119. TEST(LinqTest, from_generator)
  120. {
  121. size_t pos = 0;
  122. std::vector<int> data({ 4, 5, 6, 7, 8 });
  123. auto range = from_generator([&]{
  124. int* ret = nullptr;
  125. if (pos < data.size())
  126. {
  127. ret = &data.at(pos);
  128. ++pos;
  129. }
  130. return ret;
  131. });
  132. ASSERT_TRUE (range.next());
  133. ASSERT_EQ (&data[0], &range.front());
  134. ASSERT_EQ (4, range.front());
  135. ASSERT_TRUE (range.next());
  136. ASSERT_EQ (&data[1], &range.front());
  137. ASSERT_EQ (5, range.front());
  138. ASSERT_TRUE (range.next());
  139. ASSERT_EQ (&data[2], &range.front());
  140. ASSERT_EQ (6, range.front());
  141. ASSERT_TRUE (range.next());
  142. ASSERT_EQ (&data[3], &range.front());
  143. ASSERT_EQ (7, range.front());
  144. ASSERT_TRUE (range.next());
  145. ASSERT_EQ (&data[4], &range.front());
  146. ASSERT_EQ (8, range.front());
  147. ASSERT_FALSE(range.next());
  148. }
  149. TEST(LinqTest, where)
  150. {
  151. std::vector<int> data({ 4, 5, 6, 7, 8 });
  152. auto range = from_container(data)
  153. >> where([](int& i) {
  154. return (i & 1) == 0;
  155. });
  156. ASSERT_TRUE (range.next());
  157. ASSERT_EQ (&data[0], &range.front());
  158. ASSERT_EQ (4, range.front());
  159. ASSERT_TRUE (range.next());
  160. ASSERT_EQ (&data[2], &range.front());
  161. ASSERT_EQ (6, range.front());
  162. ASSERT_TRUE (range.next());
  163. ASSERT_EQ (&data[4], &range.front());
  164. ASSERT_EQ (8, range.front());
  165. ASSERT_FALSE(range.next());
  166. }
  167. TEST(LinqTest, select)
  168. {
  169. std::vector<test_data> data({ test_data(1), test_data(2), test_data(3) });
  170. auto range = from_container(data)
  171. >> select([](test_data& td)->int& {
  172. return td.value;
  173. });
  174. ASSERT_TRUE (range.next());
  175. ASSERT_EQ (&data[0].value, &range.front());
  176. ASSERT_EQ (1, range.front());
  177. ASSERT_TRUE (range.next());
  178. ASSERT_EQ (&data[1].value, &range.front());
  179. ASSERT_EQ (2, range.front());
  180. ASSERT_TRUE (range.next());
  181. ASSERT_EQ (&data[2].value, &range.front());
  182. ASSERT_EQ (3, range.front());
  183. ASSERT_FALSE(range.next());
  184. }
  185. TEST(LinqTest, select_many)
  186. {
  187. std::vector<TestDataMany> data({ TestDataMany({ 1, 2, 3, 4 }), TestDataMany({ }), TestDataMany({ 5, 6 }) });
  188. auto range = from_container(data)
  189. >> select_many([](TestDataMany& td)->std::vector<int>& {
  190. return td.values;
  191. });
  192. ASSERT_TRUE (range.next());
  193. ASSERT_EQ (&data[0].values[0], &range.front());
  194. ASSERT_EQ (1, range.front());
  195. ASSERT_TRUE (range.next());
  196. ASSERT_EQ (&data[0].values[1], &range.front());
  197. ASSERT_EQ (2, range.front());
  198. ASSERT_TRUE (range.next());
  199. ASSERT_EQ (&data[0].values[2], &range.front());
  200. ASSERT_EQ (3, range.front());
  201. ASSERT_TRUE (range.next());
  202. ASSERT_EQ (&data[0].values[3], &range.front());
  203. ASSERT_EQ (4, range.front());
  204. ASSERT_TRUE (range.next());
  205. ASSERT_EQ (&data[2].values[0], &range.front());
  206. ASSERT_EQ (5, range.front());
  207. ASSERT_TRUE (range.next());
  208. ASSERT_EQ (&data[2].values[1], &range.front());
  209. ASSERT_EQ (6, range.front());
  210. ASSERT_FALSE(range.next());
  211. }
  212. TEST(LinqTest, order_by)
  213. {
  214. std::vector<int> data({ 6, 3, 8, 5, 1 });
  215. auto range = from_container(data) >> order_by();
  216. ASSERT_TRUE (range.next());
  217. ASSERT_EQ (&data.at(4), &range.front());
  218. ASSERT_EQ (1, range.front());
  219. ASSERT_TRUE (range.next());
  220. ASSERT_EQ (&data.at(1), &range.front());
  221. ASSERT_EQ (3, range.front());
  222. ASSERT_TRUE (range.next());
  223. ASSERT_EQ (&data.at(3), &range.front());
  224. ASSERT_EQ (5, range.front());
  225. ASSERT_TRUE (range.next());
  226. ASSERT_EQ (&data.at(0), &range.front());
  227. ASSERT_EQ (6, range.front());
  228. ASSERT_TRUE (range.next());
  229. ASSERT_EQ (&data.at(2), &range.front());
  230. ASSERT_EQ (8, range.front());
  231. ASSERT_FALSE(range.next());
  232. }
  233. TEST(LinqTest, distinct)
  234. {
  235. std::vector<test_data> data({ test_data(1), test_data(2), test_data(3), test_data(1), test_data(2), test_data(4) });
  236. auto range = from_container(data)
  237. >> distinct([](test_data& l, test_data& r){
  238. return l.value < r.value;
  239. });
  240. ASSERT_TRUE (range.next());
  241. ASSERT_EQ (&data.at(0), &range.front());
  242. ASSERT_TRUE (range.next());
  243. ASSERT_EQ (&data.at(1), &range.front());
  244. ASSERT_TRUE (range.next());
  245. ASSERT_EQ (&data.at(2), &range.front());
  246. ASSERT_TRUE (range.next());
  247. ASSERT_EQ (&data.at(5), &range.front());
  248. ASSERT_FALSE(range.next());
  249. }
  250. TEST(LinqTest, default_if_empty)
  251. {
  252. std::vector<int> values0;
  253. auto e0 = from_container(values0) >> default_if_empty(5);
  254. ASSERT_TRUE (e0.next());
  255. ASSERT_EQ (5, e0.front());
  256. ASSERT_FALSE(e0.next());
  257. std::vector<int> values1({ 1, 2, 3 });
  258. auto e1 = from_container(values1) >> default_if_empty(5);
  259. ASSERT_TRUE (e1.next());
  260. ASSERT_EQ (1, e1.front());
  261. ASSERT_TRUE (e1.next());
  262. ASSERT_EQ (2, e1.front());
  263. ASSERT_TRUE (e1.next());
  264. ASSERT_EQ (3, e1.front());
  265. ASSERT_FALSE(e1.next());
  266. }
  267. TEST(LinqTest, count)
  268. {
  269. std::vector<int> data({ 4, 5, 6, 7, 8 });
  270. size_t cnt = from_container(data) >> count();
  271. ASSERT_EQ(5, cnt);
  272. }
  273. TEST(LinqTest, sum)
  274. {
  275. std::vector<int> data({ 4, 5, 6, 7, 8 });
  276. auto sum = from_container(data) >> linq::sum();
  277. ASSERT_EQ(30, sum);
  278. }
  279. TEST(LinqTest, min)
  280. {
  281. std::vector<int> data({ 4, 5, 6, 7, 8 });
  282. ASSERT_EQ(4, from_container(data) >> min());
  283. }
  284. TEST(LinqTest, max)
  285. {
  286. std::vector<int> data({ 4, 5, 6, 7, 8 });
  287. ASSERT_EQ(8, from_container(data) >> max());
  288. }
  289. TEST(LinqTest, any)
  290. {
  291. std::vector<int> data({ 4, 5, 6, 7, 8 });
  292. ASSERT_TRUE (from_container(data) >> any());
  293. data.clear();
  294. ASSERT_FALSE(from_container(data) >> any());
  295. }
  296. TEST(LinqTest, contains)
  297. {
  298. std::vector<int> data({ 4, 5, 6, 7, 8 });
  299. ASSERT_TRUE (from_container(data) >> contains(5));
  300. ASSERT_FALSE(from_container(data) >> contains(9));
  301. }
  302. TEST(LinqTest, single)
  303. {
  304. std::vector<int> data({ 4, 5, 6, 7, 8 });
  305. EXPECT_ANY_THROW(from_container(data) >> single());
  306. data.assign({ 9 });
  307. EXPECT_EQ(9, from_container(data) >> single());
  308. data.clear();
  309. EXPECT_ANY_THROW(from_container(data) >> single());
  310. }
  311. TEST(LinqTest, single_with_struct)
  312. {
  313. std::vector<TestData2> data({
  314. { 4, "name1" },
  315. });
  316. {
  317. auto d = from_container(data) >> single();
  318. EXPECT_EQ(4, d.value);
  319. EXPECT_EQ("name1", d.name);
  320. ASSERT_EQ(1, data.size());
  321. EXPECT_EQ(4, data[0].value);
  322. EXPECT_EQ("name1", data[0].name);
  323. }
  324. }
  325. TEST(LinqTest, single_or_default)
  326. {
  327. std::vector<int> data({ 4, 5, 6, 7, 8 });
  328. EXPECT_EQ(0, from_container(data) >> single_or_default());
  329. data.assign({ 9 });
  330. EXPECT_EQ(9, from_container(data) >> single_or_default());
  331. data.clear();
  332. EXPECT_EQ(0, from_container(data) >> single_or_default());
  333. }
  334. TEST(LinqTest, single_or_default_with_struct)
  335. {
  336. std::vector<TestData2> data({
  337. { 4, "name1" },
  338. });
  339. {
  340. auto d = from_container(data) >> single_or_default();
  341. EXPECT_EQ(4, d.value);
  342. EXPECT_EQ("name1", d.name);
  343. ASSERT_EQ(1, data.size());
  344. EXPECT_EQ(4, data[0].value);
  345. EXPECT_EQ("name1", data[0].name);
  346. }
  347. data.emplace_back(5, "name2");
  348. {
  349. auto d = from_container(data) >> single_or_default();
  350. EXPECT_EQ(0, d.value);
  351. EXPECT_EQ("", d.name);
  352. ASSERT_EQ(2, data.size());
  353. EXPECT_EQ(4, data[0].value);
  354. EXPECT_EQ("name1", data[0].name);
  355. }
  356. data.clear();
  357. {
  358. auto d = from_container(data) >> single_or_default();
  359. EXPECT_EQ(0, d.value);
  360. EXPECT_EQ("", d.name);
  361. }
  362. }
  363. TEST(LinqTest, first)
  364. {
  365. std::vector<int> data({ 4, 5, 6, 7, 8 });
  366. EXPECT_EQ(4, from_container(data) >> first());
  367. data.assign({ 9 });
  368. EXPECT_EQ(9, from_container(data) >> first());
  369. data.clear();
  370. EXPECT_ANY_THROW(from_container(data) >> first());
  371. }
  372. TEST(LinqTest, first_with_struct)
  373. {
  374. std::vector<TestData2> data({
  375. { 4, "name1" },
  376. { 5, "name2" },
  377. });
  378. {
  379. auto d = from_container(data) >> first();
  380. EXPECT_EQ(4, d.value);
  381. EXPECT_EQ("name1", d.name);
  382. ASSERT_EQ(2, data.size());
  383. EXPECT_EQ(4, data[0].value);
  384. EXPECT_EQ("name1", data[0].name);
  385. }
  386. }
  387. TEST(LinqTest, first_or_default)
  388. {
  389. std::vector<int> data({ 4, 5, 6, 7, 8 });
  390. EXPECT_EQ(4, from_container(data) >> first_or_default());
  391. data.assign({ 9 });
  392. EXPECT_EQ(9, from_container(data) >> first_or_default());
  393. data.clear();
  394. EXPECT_EQ(0, from_container(data) >> first_or_default());
  395. }
  396. TEST(LinqTest, first_or_default_with_struct)
  397. {
  398. std::vector<TestData2> data({
  399. { 4, "name1" },
  400. { 5, "name2" },
  401. });
  402. {
  403. auto d = from_container(data) >> first_or_default();
  404. EXPECT_EQ(4, d.value);
  405. EXPECT_EQ("name1", d.name);
  406. ASSERT_EQ(2, data.size());
  407. EXPECT_EQ(4, data[0].value);
  408. EXPECT_EQ("name1", data[0].name);
  409. }
  410. data.clear();
  411. {
  412. auto d = from_container(data) >> first_or_default();
  413. EXPECT_EQ(0, d.value);
  414. EXPECT_EQ("", d.name);
  415. }
  416. }
  417. TEST(LinqTest, last)
  418. {
  419. std::vector<int> data({ 4, 5, 6, 7, 8 });
  420. EXPECT_EQ(8, from_container(data) >> last());
  421. data.assign({ 9 });
  422. EXPECT_EQ(9, from_container(data) >> last());
  423. data.clear();
  424. EXPECT_ANY_THROW(from_container(data) >> last());
  425. }
  426. TEST(LinqTest, last_with_struct)
  427. {
  428. std::vector<TestData2> data({
  429. { 4, "name1" },
  430. { 5, "name2" },
  431. });
  432. {
  433. auto d = from_container(data) >> last();
  434. EXPECT_EQ(5, d.value);
  435. EXPECT_EQ("name2", d.name);
  436. ASSERT_EQ(2, data.size());
  437. EXPECT_EQ(5, data[1].value);
  438. EXPECT_EQ("name2", data[1].name);
  439. }
  440. }
  441. TEST(LinqTest, last_or_default)
  442. {
  443. std::vector<int> data({ 4, 5, 6, 7, 8 });
  444. EXPECT_EQ(8, from_container(data) >> last_or_default());
  445. data.assign({ 9 });
  446. EXPECT_EQ(9, from_container(data) >> last_or_default());
  447. data.clear();
  448. EXPECT_EQ(0, from_container(data) >> last_or_default());
  449. }
  450. TEST(LinqTest, last_or_default_with_struct)
  451. {
  452. std::vector<TestData2> data({
  453. { 4, "name1" },
  454. { 5, "name2" },
  455. });
  456. {
  457. auto d = from_container(data) >> last_or_default();
  458. EXPECT_EQ(5, d.value);
  459. EXPECT_EQ("name2", d.name);
  460. ASSERT_EQ(2, data.size());
  461. EXPECT_EQ(5, data[1].value);
  462. EXPECT_EQ("name2", data[1].name);
  463. }
  464. data.clear();
  465. {
  466. auto d = from_container(data) >> last_or_default();
  467. EXPECT_EQ(0, d.value);
  468. EXPECT_EQ("", d.name);
  469. }
  470. }
  471. TEST(LinqTest, to_vector)
  472. {
  473. int data[] = { 4, 5, 6, 7, 8 };
  474. auto vec = from_array(data) >> to_vector();
  475. ASSERT_EQ(5, vec.size());
  476. EXPECT_EQ(4, vec[0]);
  477. EXPECT_EQ(5, vec[1]);
  478. EXPECT_EQ(6, vec[2]);
  479. EXPECT_EQ(7, vec[3]);
  480. EXPECT_EQ(8, vec[4]);
  481. }
  482. TEST(LinqTest, to_list)
  483. {
  484. int data[] = { 4, 5, 6, 7, 8 };
  485. auto list = from_array(data) >> to_list();
  486. auto it = list.begin();
  487. ASSERT_NE(it, list.end());
  488. EXPECT_EQ(4, *it);
  489. ++it;
  490. ASSERT_NE(it, list.end());
  491. EXPECT_EQ(5, *it);
  492. ++it;
  493. ASSERT_NE(it, list.end());
  494. EXPECT_EQ(6, *it);
  495. ++it;
  496. ASSERT_NE(it, list.end());
  497. EXPECT_EQ(7, *it);
  498. ++it;
  499. ASSERT_NE(it, list.end());
  500. EXPECT_EQ(8, *it);
  501. ++it;
  502. ASSERT_EQ(it, list.end());
  503. }
  504. TEST(LinqTest, to_map)
  505. {
  506. using pair_type = std::pair<int, std::string>;
  507. using vector_type = std::vector<pair_type>;
  508. vector_type data({
  509. std::make_pair(1, "1"),
  510. std::make_pair(2, "2"),
  511. std::make_pair(3, "3")
  512. });
  513. auto map0 = from_container(data) >> to_map();
  514. auto it = map0.begin();
  515. ASSERT_NE(it, map0.end());
  516. EXPECT_EQ(1, it->first);
  517. EXPECT_EQ(std::string("1"), it->second);
  518. ++it;
  519. ASSERT_NE(it, map0.end());
  520. EXPECT_EQ(2, it->first);
  521. EXPECT_EQ(std::string("2"), it->second);
  522. ++it;
  523. ASSERT_NE(it, map0.end());
  524. EXPECT_EQ(3, it->first);
  525. EXPECT_EQ(std::string("3"), it->second);
  526. ++it;
  527. ASSERT_EQ(it, map0.end());
  528. data.emplace_back(3, "4");
  529. EXPECT_ANY_THROW(from_container(data) >> to_map());
  530. }
  531. TEST(LinqTest, for_each)
  532. {
  533. int index = 0;
  534. int data[] = { 4, 5, 6, 7, 8 };
  535. from_array(data) >> for_each([&](int& i){
  536. EXPECT_EQ(&data[index], &i);
  537. ++index;
  538. });
  539. }
  540. TEST(LinqTest, to_lookup)
  541. {
  542. using pair_type = std::pair<int, std::string>;
  543. using vector_type = std::vector<pair_type>;
  544. vector_type data({
  545. { 0, "Str0-0" },
  546. { 1, "Str1-0" },
  547. { 2, "Str2-0" },
  548. { 0, "Str0-1" },
  549. { 1, "Str1-1" },
  550. { 2, "Str2-1" },
  551. { 1, "Str1-2" },
  552. { 0, "Str0-2" },
  553. });
  554. auto lookup = from_container(data)
  555. >> to_lookup([](pair_type& p)->int&{
  556. return p.first;
  557. }, [](pair_type& p)->std::string&{
  558. return p.second;
  559. });
  560. auto range0 = lookup[0];
  561. ASSERT_TRUE (range0.next());
  562. ASSERT_EQ (&data.at(0).second, &range0.front());
  563. ASSERT_EQ (std::string("Str0-0"), range0.front());
  564. ASSERT_TRUE (range0.next());
  565. ASSERT_EQ (&data.at(3).second, &range0.front());
  566. ASSERT_EQ (std::string("Str0-1"), range0.front());
  567. ASSERT_TRUE (range0.next());
  568. ASSERT_EQ (&data.at(7).second, &range0.front());
  569. ASSERT_EQ (std::string("Str0-2"), range0.front());
  570. ASSERT_FALSE(range0.next());
  571. auto range1 = lookup[1];
  572. ASSERT_TRUE (range1.next());
  573. ASSERT_EQ (&data.at(1).second, &range1.front());
  574. ASSERT_EQ (std::string("Str1-0"), range1.front());
  575. ASSERT_TRUE (range1.next());
  576. ASSERT_EQ (&data.at(4).second, &range1.front());
  577. ASSERT_EQ (std::string("Str1-1"), range1.front());
  578. ASSERT_TRUE (range1.next());
  579. ASSERT_EQ (&data.at(6).second, &range1.front());
  580. ASSERT_EQ (std::string("Str1-2"), range1.front());
  581. ASSERT_FALSE(range1.next());
  582. auto range2 = lookup[2];
  583. ASSERT_TRUE (range2.next());
  584. ASSERT_EQ (&data.at(2).second, &range2.front());
  585. ASSERT_EQ (std::string("Str2-0"), range2.front());
  586. ASSERT_TRUE (range2.next());
  587. ASSERT_EQ (&data.at(5).second, &range2.front());
  588. ASSERT_EQ (std::string("Str2-1"), range2.front());
  589. ASSERT_FALSE(range2.next());
  590. using key_value_range_type = linq::lookup_key_value_range_type<int&, std::string&>;
  591. auto map = lookup
  592. >> to_map([](key_value_range_type::value_type v){
  593. return v.first;
  594. }, [](key_value_range_type::value_type v){
  595. return v.second >> to_vector();
  596. });
  597. using map_type = decltype(map);
  598. map_type expected({
  599. { 0, { "Str0-0", "Str0-1", "Str0-2" } },
  600. { 1, { "Str1-0", "Str1-1", "Str1-2" } },
  601. { 2, { "Str2-0", "Str2-1" } }
  602. });
  603. EXPECT_EQ(expected, map);
  604. }
  605. struct StationMock
  606. {
  607. uint32_t id;
  608. std::string name1;
  609. std::string name2;
  610. std::string name3;
  611. std::string name4;
  612. };
  613. struct op_select_names
  614. {
  615. using pair_type = std::pair<std::string, uint32_t>;
  616. using vector_type = std::vector<pair_type>;
  617. inline void addToVec(vector_type& vec, const std::string& name, uint32_t sID)
  618. {
  619. if (name.empty())
  620. return;
  621. bool exists = from_container(vec)
  622. >> select(op_select_key_default())
  623. >> contains(name);
  624. if (!exists)
  625. vec.emplace_back(name, sID);
  626. }
  627. inline vector_type operator()(StationMock& s)
  628. {
  629. vector_type ret;
  630. addToVec(ret, s.name1, s.id);
  631. addToVec(ret, s.name2, s.id);
  632. addToVec(ret, s.name3, s.id);
  633. addToVec(ret, s.name4, s.id);
  634. return ret;
  635. }
  636. };
  637. void checkMapEntry(std::map<std::string, std::vector<uint32_t>>& map, std::string name, std::vector<uint32_t> ids)
  638. {
  639. auto it = map.find(name);
  640. ASSERT_NE(it, map.end());
  641. EXPECT_EQ(name, it->first);
  642. EXPECT_EQ(ids, it->second);
  643. }
  644. TEST(LinqTest, to_lookup_2)
  645. {
  646. std::vector<StationMock> stations ({
  647. { 1, "sname11" , "sname12", "sname13", "sname14" },
  648. { 2, "sname21" , "sname21", "sname23", "sname24" },
  649. { 3, "sname11" , "sname31", "sname33", "sname34" },
  650. });
  651. using key_value_range_type = linq::lookup_key_value_range_type<std::string, uint32_t>;
  652. auto myMap = linq::from_container(stations)
  653. >> linq::select_many(op_select_names())
  654. >> linq::to_lookup()
  655. >> linq::to_map([](key_value_range_type::value_type p) {
  656. return p.first;
  657. }, [](key_value_range_type::value_type p) {
  658. return p.second >> linq::to_vector();
  659. });
  660. checkMapEntry(myMap, "sname11", { 1, 3 });
  661. checkMapEntry(myMap, "sname12", { 1 });
  662. checkMapEntry(myMap, "sname13", { 1 });
  663. checkMapEntry(myMap, "sname14", { 1 });
  664. checkMapEntry(myMap, "sname21", { 2 });
  665. checkMapEntry(myMap, "sname23", { 2 });
  666. checkMapEntry(myMap, "sname24", { 2 });
  667. checkMapEntry(myMap, "sname31", { 3 });
  668. checkMapEntry(myMap, "sname33", { 3 });
  669. checkMapEntry(myMap, "sname34", { 3 });
  670. }
  671. TEST(LinqTest, moveable_objects)
  672. {
  673. std::vector<MoveOnlyData> data;
  674. data.emplace_back(1);
  675. {
  676. data.at(0).value = 1;
  677. auto v = from_container(data)
  678. >> select([](MoveOnlyData& d) {
  679. return std::move(d);
  680. })
  681. >> first();
  682. EXPECT_EQ(1, v.value);
  683. EXPECT_EQ(0, data.at(0).value);
  684. }
  685. {
  686. data.at(0).value = 2;
  687. auto v = from_container(data)
  688. >> select([](MoveOnlyData& d) {
  689. return std::move(d);
  690. })
  691. >> first_or_default();
  692. EXPECT_EQ(2, v.value);
  693. EXPECT_EQ(0, data.at(0).value);
  694. }
  695. {
  696. data.at(0).value = 3;
  697. auto v = from_container(data)
  698. >> select([](MoveOnlyData& d) {
  699. return std::move(d);
  700. })
  701. >> last();
  702. EXPECT_EQ(3, v.value);
  703. EXPECT_EQ(0, data.at(0).value);
  704. }
  705. {
  706. data.at(0).value = 4;
  707. auto v = from_container(data)
  708. >> select([](MoveOnlyData& d) {
  709. return std::move(d);
  710. })
  711. >> last_or_default();
  712. EXPECT_EQ(4, v.value);
  713. EXPECT_EQ(0, data.at(0).value);
  714. }
  715. {
  716. data.at(0).value = 5;
  717. auto v = from_container(data)
  718. >> select([](MoveOnlyData& d) {
  719. return std::move(d);
  720. })
  721. >> single();
  722. EXPECT_EQ(5, v.value);
  723. EXPECT_EQ(0, data.at(0).value);
  724. }
  725. {
  726. data.at(0).value = 6;
  727. auto v = from_container(data)
  728. >> select([](MoveOnlyData& d) {
  729. return std::move(d);
  730. })
  731. >> single_or_default();
  732. EXPECT_EQ(6, v.value);
  733. EXPECT_EQ(0, data.at(0).value);
  734. }
  735. {
  736. data.at(0).value = 7;
  737. auto v = from_container(data)
  738. >> select([](MoveOnlyData& d) {
  739. return std::move(d);
  740. })
  741. >> to_vector();
  742. ASSERT_EQ(1, v.size());
  743. EXPECT_EQ(7, v.at(0).value);
  744. EXPECT_EQ(0, data.at(0).value);
  745. }
  746. {
  747. data.at(0).value = 8;
  748. auto v = from_container(data)
  749. >> select([](MoveOnlyData& d) {
  750. return std::move(d);
  751. })
  752. >> to_map([](MoveOnlyData& d){
  753. return 5;
  754. }, [](MoveOnlyData& d){
  755. return std::move(d);
  756. });
  757. auto it = v.find(5);
  758. ASSERT_NE(it, v.end());
  759. EXPECT_EQ(8, it->second.value);
  760. EXPECT_EQ(0, data.at(0).value);
  761. }
  762. {
  763. data.at(0).value = 9;
  764. auto v = from_container(data)
  765. >> select([](MoveOnlyData& d) {
  766. return std::move(d);
  767. })
  768. >> to_list();
  769. auto it = v.begin();
  770. ASSERT_NE(it, v.end());
  771. EXPECT_EQ(9, it->value);
  772. EXPECT_EQ(0, data.at(0).value);
  773. }
  774. }
  775. TEST(LinqTest, const_objects)
  776. {
  777. const test_data data[] = { test_data(1) };
  778. {
  779. auto v = from_array(data)
  780. >> select([](const test_data& d) {
  781. return d;
  782. })
  783. >> first();
  784. EXPECT_EQ(1, v.value);
  785. }
  786. {
  787. auto v = from_array(data)
  788. >> select([](const test_data& d) {
  789. return d;
  790. })
  791. >> first_or_default();
  792. EXPECT_EQ(1, v.value);
  793. }
  794. {
  795. auto v = from_array(data)
  796. >> select([](const test_data& d) {
  797. return std::move(d);
  798. })
  799. >> last();
  800. EXPECT_EQ(1, v.value);
  801. }
  802. {
  803. auto v = from_array(data)
  804. >> select([](const test_data& d) {
  805. return d;
  806. })
  807. >> last_or_default();
  808. EXPECT_EQ(1, v.value);
  809. }
  810. {
  811. auto v = from_array(data)
  812. >> select([](const test_data& d) {
  813. return d;
  814. })
  815. >> single();
  816. EXPECT_EQ(1, v.value);
  817. }
  818. {
  819. auto v = from_array(data)
  820. >> select([](const test_data& d) {
  821. return d;
  822. })
  823. >> single_or_default();
  824. EXPECT_EQ(1, v.value);
  825. }
  826. {
  827. auto v = from_array(data)
  828. >> select([](const test_data& d) {
  829. return d;
  830. })
  831. >> to_list();
  832. auto it = v.begin();
  833. ASSERT_NE(it, v.end());
  834. EXPECT_EQ(1, it->value);
  835. }
  836. }