You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1633 lines
58 KiB

  1. #pragma once
  2. #include <set>
  3. #include <map>
  4. #include <list>
  5. #include <vector>
  6. #include <cassert>
  7. #include <algorithm>
  8. #include <cpputils/mp/core.h>
  9. #include <cpputils/misc/exception.h>
  10. #include <cpputils/container/wrapper.h>
  11. #include <cpputils/container/nullable.h>
  12. // #define LINQ_DEBUG
  13. #ifdef LINQ_DEBUG
  14. #include <cpputils/misc/type_helper.h>
  15. #define LINQ_TYPE_NAME() utl::type_helper<decltype(*this)>::name()
  16. #define LINQ_CTOR() do { std::cout << "CTOR " << ++::utl::linq::__impl::ref_counter<decltype(*this)>::value() << "(this=" << this << ")" << LINQ_TYPE_NAME() << std::endl; } while(0)
  17. #define LINQ_COPY_CTOR() do { std::cout << "COPY " << ++::utl::linq::__impl::ref_counter<decltype(*this)>::value() << "(this=" << this << ")" << LINQ_TYPE_NAME() << std::endl; } while(0)
  18. #define LINQ_MOVE_CTOR() do { std::cout << "MOVE " << ++::utl::linq::__impl::ref_counter<decltype(*this)>::value() << "(this=" << this << ")" << LINQ_TYPE_NAME() << std::endl; } while(0)
  19. #define LINQ_DTOR() do { std::cout << "DTOR " << --::utl::linq::__impl::ref_counter<decltype(*this)>::value() << "(this=" << this << ")" << LINQ_TYPE_NAME() << std::endl; } while(0)
  20. #else
  21. #define LINQ_TYPE_NAME() while(0)
  22. #define LINQ_CTOR() while(0)
  23. #define LINQ_COPY_CTOR() while(0)
  24. #define LINQ_MOVE_CTOR() while(0)
  25. #define LINQ_DTOR() while(0)
  26. #endif
  27. namespace utl{
  28. namespace linq {
  29. namespace __impl
  30. {
  31. #ifdef LINQ_DEBUG
  32. template<typename... T>
  33. struct ref_counter
  34. {
  35. static inline size_t& value()
  36. {
  37. static size_t value = 0;
  38. return value;
  39. }
  40. };
  41. #endif
  42. struct tag_range { };
  43. struct tag_builder { };
  44. /* meta programming **********************************************************************/
  45. template<class TArray>
  46. struct mp_array_properties;
  47. template<class T, size_t N>
  48. struct mp_array_properties<T[N]>
  49. {
  50. using size = std::integral_constant<size_t, N>;
  51. using value_type = T;
  52. using iterator_type = T*;
  53. };
  54. template<class T>
  55. using mp_range_value_type = typename utl::mp::remove_ref<T>::value_type;
  56. /* helper types **************************************************************************/
  57. template<class T, class TPredicate>
  58. struct op_wrapper_less
  59. {
  60. using predicate_type = TPredicate;
  61. using value_type = utl::wrapper<T>;
  62. predicate_type predicate;
  63. inline bool operator()(const value_type& l, const value_type& r)
  64. { return predicate(*l, *r); }
  65. inline op_wrapper_less(const predicate_type& lp) :
  66. predicate(lp)
  67. { }
  68. inline op_wrapper_less(const op_wrapper_less& other) :
  69. predicate(other.predicate)
  70. { }
  71. inline op_wrapper_less(op_wrapper_less&& other) :
  72. predicate(std::move(other.predicate))
  73. { }
  74. };
  75. template<class TRange>
  76. struct range_wrapper
  77. {
  78. using range_type = TRange;
  79. using this_type = range_wrapper<range_type>;
  80. using value_type = mp_range_value_type<range_type>;
  81. range_type range;
  82. inline value_type& front()
  83. { return range.front(); }
  84. inline bool next()
  85. { return range.next(); }
  86. template<class TBuilder>
  87. inline auto operator >> (TBuilder&& builder) &
  88. { return builder.build(range); }
  89. template<class TBuilder>
  90. inline auto operator >> (TBuilder&& builder) &&
  91. { return builder.build(std::move(range)); }
  92. template<class... Args>
  93. range_wrapper(Args&&... args) :
  94. range(std::forward<Args>(args)...)
  95. { }
  96. range_wrapper(const this_type& other) :
  97. range(other.range)
  98. { }
  99. range_wrapper(this_type&& other) :
  100. range(std::move(other.range))
  101. { }
  102. };
  103. template<class TKey, class TValue>
  104. struct lookup
  105. {
  106. public:
  107. using key_type = TKey;
  108. using clean_key_type = utl::mp::remove_ref<key_type>;
  109. using value_type = TValue;
  110. using this_type = lookup<key_type, value_type>;
  111. using wrapped_key_type = utl::wrapper<key_type>;
  112. using wrapped_value_type = utl::wrapper<value_type>;
  113. using keys_value_type = std::pair<wrapped_key_type, size_t>;
  114. using keys_type = std::vector<keys_value_type>;
  115. using values_type = std::vector<wrapped_value_type>;
  116. using range_indices_type = std::pair<size_t, size_t>;
  117. struct lookup_range;
  118. struct lookup_key_value_range;
  119. using lookup_range_wrapper = range_wrapper<lookup_range>;
  120. using lookup_key_value_range_wrapper = range_wrapper<lookup_key_value_range>;
  121. struct lookup_range : public tag_range
  122. {
  123. using value_type = lookup::value_type;
  124. using state_type = enum class state
  125. {
  126. initialize,
  127. iterating,
  128. finished,
  129. };
  130. values_type& values;
  131. size_t current;
  132. size_t end;
  133. state_type state;
  134. inline value_type& front()
  135. {
  136. assert(state == state_type::iterating);
  137. assert(current < end);
  138. return *values[current];
  139. }
  140. inline bool next()
  141. {
  142. switch (state)
  143. {
  144. case state_type::iterating:
  145. {
  146. ++current;
  147. }
  148. case state_type::initialize:
  149. {
  150. auto hasElements = (current < end);
  151. state = (hasElements ? state_type::iterating : state_type::finished);
  152. return hasElements;
  153. }
  154. default:
  155. {
  156. return false;
  157. }
  158. }
  159. }
  160. inline lookup_range(values_type& v, size_t c, size_t e) :
  161. values (v),
  162. current (c),
  163. end (e),
  164. state (state_type::initialize)
  165. { LINQ_CTOR(); }
  166. inline lookup_range(const lookup_range& other) :
  167. values (other.values),
  168. current (other.current),
  169. end (other.end),
  170. state (other.state)
  171. { LINQ_COPY_CTOR(); }
  172. inline lookup_range(lookup_range&& other) :
  173. values (std::move(other).values),
  174. current (std::move(other).current),
  175. end (std::move(other).end),
  176. state (std::move(other).state)
  177. { LINQ_MOVE_CTOR(); }
  178. inline ~lookup_range()
  179. { LINQ_DTOR(); }
  180. };
  181. struct lookup_key_value_range : public tag_range
  182. {
  183. using value_type = std::pair<key_type, lookup_range_wrapper>;
  184. using iterator_type = typename keys_type::const_iterator;
  185. lookup container;
  186. bool initialized;
  187. range_indices_type range_indices;
  188. iterator_type current;
  189. iterator_type end;
  190. inline value_type front()
  191. {
  192. assert(initialized);
  193. assert(current != end);
  194. return value_type(
  195. *current->first,
  196. container.createRange(range_indices));
  197. }
  198. inline bool next()
  199. {
  200. if (!initialized)
  201. {
  202. initialized = true;
  203. current = container._keys.begin();
  204. end = container._keys.end();
  205. if (current == end)
  206. return false;
  207. }
  208. else
  209. {
  210. if (current == end)
  211. return false;
  212. ++current;
  213. if (current == end)
  214. return false;
  215. }
  216. range_indices = container.findKey(*current->first);
  217. return true;
  218. }
  219. template<class C>
  220. lookup_key_value_range(C&& c) :
  221. container (std::forward<C>(c)),
  222. initialized (false)
  223. { LINQ_CTOR(); }
  224. lookup_key_value_range(const lookup_key_value_range& other) :
  225. container (other.container),
  226. initialized (other.initialized),
  227. range_indices (other.range_indices),
  228. current (other.current),
  229. end (other.end)
  230. { LINQ_COPY_CTOR(); }
  231. lookup_key_value_range(lookup_key_value_range&& other) :
  232. container (std::move(other).container),
  233. initialized (std::move(other).initialized),
  234. range_indices (std::move(other).range_indices),
  235. current (std::move(other).current),
  236. end (std::move(other).end)
  237. { LINQ_MOVE_CTOR(); }
  238. ~lookup_key_value_range()
  239. { LINQ_DTOR(); }
  240. };
  241. struct op_compare_keys
  242. {
  243. bool operator()(
  244. const keys_value_type& l,
  245. const keys_value_type& r)
  246. { return *l.first < *r.first; }
  247. };
  248. private:
  249. keys_type _keys;
  250. values_type _values;
  251. inline range_indices_type findKey(const clean_key_type& key)
  252. {
  253. if (_values.empty())
  254. return std::make_pair<size_t, size_t>(0, 0);
  255. auto it = std::lower_bound(
  256. _keys.begin(),
  257. _keys.end(),
  258. typename keys_type::value_type (const_cast<clean_key_type&>(key), 0),
  259. op_compare_keys());
  260. if ( it == _keys.end()
  261. || *it->first != const_cast<clean_key_type&>(key))
  262. return std::make_pair<size_t, size_t>(0, 0);
  263. auto next = it + 1;
  264. range_indices_type ret;
  265. ret.first = it->second;
  266. ret.second = next == _keys.end()
  267. ? _values.size()
  268. : next->second;
  269. return ret;
  270. }
  271. inline lookup_range_wrapper createRange(const range_indices_type& indices)
  272. { return lookup_range_wrapper(_values, indices.first, indices.second); }
  273. public:
  274. inline lookup_range_wrapper operator[](const clean_key_type& key)
  275. { return createRange(findKey(key)); }
  276. template<class TBuilder>
  277. inline auto operator >> (TBuilder&& builder) &
  278. { return builder.build(lookup_key_value_range(*this)); }
  279. template<class TBuilder>
  280. inline auto operator >> (TBuilder&& builder) &&
  281. { return builder.build(lookup_key_value_range(std::move(*this))); }
  282. private:
  283. inline lookup(keys_type&& k, values_type&& v) :
  284. _keys (k),
  285. _values (v)
  286. { LINQ_CTOR(); }
  287. public:
  288. inline lookup()
  289. { LINQ_CTOR(); }
  290. inline lookup(const lookup& other) :
  291. _keys (other._keys),
  292. _values (other._values)
  293. { LINQ_COPY_CTOR(); }
  294. inline lookup(lookup&& other) :
  295. _keys (std::move(other)._keys),
  296. _values (std::move(other)._values)
  297. { LINQ_MOVE_CTOR(); }
  298. inline ~lookup()
  299. { LINQ_DTOR(); }
  300. public:
  301. template<class TRange, class TKeyPredicate, class TValuePredicate>
  302. static inline auto build(TRange& range, TKeyPredicate& kp, TValuePredicate& vp)
  303. {
  304. keys_type k;
  305. values_type v;
  306. size_t index = 0;
  307. while (range.next())
  308. {
  309. k.emplace_back(kp(range.front()), index);
  310. v.emplace_back(vp(range.front()));
  311. ++index;
  312. }
  313. if (v.empty())
  314. return lookup();
  315. std::sort(k.begin(), k.end(), op_compare_keys());
  316. keys_type keys;
  317. values_type values;
  318. keys.reserve (k.size());
  319. values.reserve(k.size());
  320. auto it = k.begin();
  321. auto end = k.end();
  322. index = 0;
  323. if (it != end)
  324. {
  325. keys.emplace_back(it->first, index);
  326. values.push_back(v.at(it->second));
  327. }
  328. auto prev = it;
  329. ++it;
  330. ++index;
  331. while (it != end)
  332. {
  333. values.push_back(v.at(it->second));
  334. if (*prev->first < *it->first)
  335. keys.push_back(std::make_pair(it->first, index));
  336. prev = it;
  337. ++it;
  338. ++index;
  339. }
  340. return lookup(std::move(keys), std::move(values));
  341. }
  342. };
  343. /* ranges ********************************************************************************/
  344. template<class TIterator>
  345. struct iterator_range : public tag_range
  346. {
  347. using iterator_type = TIterator;
  348. using this_type = iterator_range<iterator_type>;
  349. using value_type = decltype(*std::declval<iterator_type>());
  350. bool initialized;
  351. iterator_type current;
  352. iterator_type end;
  353. inline value_type& front()
  354. {
  355. assert(initialized);
  356. assert(current != end);
  357. return *current;
  358. }
  359. inline bool next()
  360. {
  361. if (!initialized)
  362. initialized = true;
  363. else if (current != end)
  364. ++current;
  365. return (current != end);
  366. }
  367. inline iterator_range(iterator_type b, iterator_type e) :
  368. initialized (false),
  369. current (b),
  370. end (e)
  371. { LINQ_CTOR(); }
  372. inline iterator_range(const this_type& other) :
  373. initialized (other.initialized),
  374. current (other.current),
  375. end (other.end)
  376. { LINQ_COPY_CTOR(); }
  377. inline iterator_range(this_type&& other) :
  378. initialized (std::move(other).initialized),
  379. current (std::move(other).current),
  380. end (std::move(other).end)
  381. { LINQ_MOVE_CTOR(); }
  382. inline ~iterator_range()
  383. { LINQ_DTOR(); }
  384. };
  385. template<class TIterator>
  386. using iterator_range_wrapper = range_wrapper<iterator_range<TIterator>>;
  387. template<class TContainer>
  388. struct container_range : public tag_range
  389. {
  390. using container_type = TContainer;
  391. using this_type = container_range<container_type>;
  392. using iterator_type = decltype(std::begin(std::declval<container_type>()));
  393. using value_type = decltype(*std::declval<iterator_type>());
  394. TContainer container;
  395. bool initialized;
  396. iterator_type current;
  397. inline value_type& front()
  398. {
  399. assert(initialized);
  400. assert(current != std::end(container));
  401. return *current;
  402. }
  403. inline bool next()
  404. {
  405. if (!initialized)
  406. {
  407. initialized = true;
  408. current = std::begin(container);
  409. }
  410. else if (current != std::end(container))
  411. {
  412. ++current;
  413. }
  414. return (current != std::end(container));
  415. }
  416. template<class C>
  417. inline container_range(C&& c) noexcept :
  418. container (std::forward<C>(c)),
  419. initialized (false)
  420. { LINQ_CTOR(); }
  421. inline container_range(const this_type& other) noexcept :
  422. container (other.container),
  423. initialized (other.initialized),
  424. current (other.current)
  425. { LINQ_COPY_CTOR(); }
  426. inline container_range(this_type&& other) noexcept :
  427. container (std::move(other).container),
  428. initialized (std::move(other).initialized),
  429. current (std::move(other).current)
  430. { LINQ_MOVE_CTOR(); }
  431. inline ~container_range()
  432. { LINQ_DTOR(); }
  433. };
  434. template<class TContainer>
  435. using container_range_wrapper = range_wrapper<container_range<TContainer>>;
  436. template<class TPredicate>
  437. struct generator_range : public tag_range
  438. {
  439. using predicate_type = TPredicate;
  440. using this_type = generator_range<predicate_type>;
  441. using predicate_value_type = decltype(std::declval<predicate_type>()());
  442. using value_type = decltype(*std::declval<predicate_value_type>());
  443. predicate_type predicate;
  444. predicate_value_type value;
  445. inline value_type& front()
  446. {
  447. assert(static_cast<bool>(value));
  448. return *value;
  449. }
  450. inline bool next()
  451. {
  452. value = predicate();
  453. return static_cast<bool>(value);
  454. }
  455. inline generator_range(predicate_type p) :
  456. predicate (p)
  457. { LINQ_CTOR(); }
  458. inline generator_range(const this_type& other) :
  459. predicate (other.predicate),
  460. value (other.value)
  461. { LINQ_COPY_CTOR(); }
  462. inline generator_range(this_type&& other) :
  463. predicate (std::move(other).predicate),
  464. value (std::move(other).value)
  465. { LINQ_MOVE_CTOR(); }
  466. inline ~generator_range()
  467. { LINQ_DTOR(); }
  468. };
  469. template<class TPredicate>
  470. using generator_range_wrapper = range_wrapper<generator_range<TPredicate>>;
  471. template<class TRange, class TPredicate>
  472. struct where_range : public tag_range
  473. {
  474. using range_type = TRange;
  475. using predicate_type = TPredicate;
  476. using this_type = where_range<range_type, predicate_type>;
  477. using value_type = mp_range_value_type<range_type>;
  478. range_type range;
  479. predicate_type predicate;
  480. inline value_type& front()
  481. { return range.front(); }
  482. inline bool next()
  483. {
  484. while (range.next())
  485. {
  486. if (predicate(range.front()))
  487. return true;
  488. }
  489. return false;
  490. }
  491. template<class R, class P>
  492. inline where_range(R&& r, P&& p) :
  493. range (std::forward<R>(r)),
  494. predicate (std::forward<P>(p))
  495. { LINQ_CTOR(); }
  496. inline where_range(const this_type& other) :
  497. range (other.range),
  498. predicate (other.predicate)
  499. { LINQ_COPY_CTOR(); }
  500. inline where_range(this_type&& other) :
  501. range (std::move(other).range),
  502. predicate (std::move(other).predicate)
  503. { LINQ_MOVE_CTOR(); }
  504. inline ~where_range()
  505. { LINQ_DTOR(); }
  506. };
  507. template<class TRange, class TPredicate>
  508. using where_range_wrapper = range_wrapper<where_range<TRange, TPredicate>>;
  509. template<class TRange, class TPredicate>
  510. struct select_range : public tag_range
  511. {
  512. using range_type = TRange;
  513. using predicate_type = TPredicate;
  514. using this_type = select_range<range_type, predicate_type>;
  515. using range_value_type = mp_range_value_type<range_type>;
  516. using value_type = decltype(std::declval<predicate_type>()(std::declval<range_value_type>()));
  517. using cache_type = utl::nullable<value_type>;
  518. predicate_type predicate;
  519. range_type range;
  520. cache_type cache;
  521. inline value_type& front()
  522. {
  523. assert(static_cast<bool>(cache));
  524. return *cache;
  525. }
  526. inline bool next()
  527. {
  528. if (range.next())
  529. {
  530. cache = predicate(range.front());
  531. return true;
  532. }
  533. cache.reset();
  534. return false;
  535. }
  536. template<class R, class P>
  537. inline select_range(R&& r, P&& p) :
  538. range (std::forward<R>(r)),
  539. predicate (std::forward<P>(p))
  540. { LINQ_CTOR(); }
  541. inline select_range(const this_type& other) :
  542. range (other.range),
  543. predicate (other.predicate)
  544. { LINQ_COPY_CTOR(); }
  545. inline select_range(this_type&& other) :
  546. range (std::move(other).range),
  547. predicate (std::move(other).predicate)
  548. { LINQ_MOVE_CTOR(); }
  549. inline ~select_range()
  550. { LINQ_DTOR(); }
  551. };
  552. template<class TRange, class TPredicate>
  553. using select_range_wrapper = range_wrapper<select_range<TRange, TPredicate>>;
  554. template<class TRange, class TPredicate>
  555. struct select_many_range : public tag_range
  556. {
  557. template<class T>
  558. struct __impl_make_inner_range
  559. {
  560. using container_type = T;
  561. using type = container_range<container_type>;
  562. };
  563. template<class T>
  564. using mp_make_inner_range = typename __impl_make_inner_range<T>::type;
  565. using range_type = TRange;
  566. using predicate_type = TPredicate;
  567. using this_type = where_range<range_type, predicate_type>;
  568. using range_value_type = mp_range_value_type<range_type>;
  569. using predicate_return_type = decltype(std::declval<predicate_type>()(std::declval<range_value_type>()));
  570. using inner_range_type = utl::mp::eval_if_t<
  571. std::is_base_of<tag_range, predicate_return_type>,
  572. predicate_return_type,
  573. mp_make_inner_range, predicate_return_type>;
  574. using value_type = mp_range_value_type<inner_range_type>;
  575. using inner_range_cache_type = utl::nullable<inner_range_type>;
  576. predicate_type predicate;
  577. range_type range;
  578. inner_range_cache_type inner_range;
  579. template<class T>
  580. inline typename std::enable_if<std::is_base_of<tag_range, T>::value>::type
  581. build_inner_range(T&& value)
  582. { inner_range = value; }
  583. template<class T>
  584. inline typename std::enable_if<!std::is_base_of<tag_range, T>::value>::type
  585. build_inner_range(T&& value)
  586. { inner_range = inner_range_type(std::forward<T>(value)); }
  587. inline value_type& front()
  588. {
  589. assert(inner_range);
  590. return inner_range->front();
  591. }
  592. inline bool next()
  593. {
  594. if (inner_range && inner_range->next())
  595. return true;
  596. while (range.next())
  597. {
  598. inner_range.reset();
  599. build_inner_range<predicate_return_type>(predicate(range.front()));
  600. if (inner_range && inner_range->next())
  601. return true;
  602. }
  603. inner_range.reset();
  604. return false;
  605. }
  606. template<class R, class P>
  607. inline select_many_range(R&& r, P&& p) :
  608. range (std::forward<R>(r)),
  609. predicate (std::forward<P>(p))
  610. { LINQ_CTOR(); }
  611. inline select_many_range(const this_type& other) :
  612. range (other.range),
  613. predicate (other.predicate),
  614. inner_range (other.inner_range)
  615. { LINQ_COPY_CTOR(); }
  616. inline select_many_range(this_type&& other) :
  617. range (std::move(other).range),
  618. predicate (std::move(other).predicate),
  619. inner_range (std::move(other).inner_range)
  620. { LINQ_MOVE_CTOR(); }
  621. inline ~select_many_range()
  622. { LINQ_DTOR(); }
  623. };
  624. template<class TRange, class TPredicate>
  625. using select_many_range_wrapper = range_wrapper<select_many_range<TRange, TPredicate>>;
  626. template<class TRange, class TSelectPredicate, class TLessPredicate>
  627. struct order_by_range : public tag_range
  628. {
  629. using range_type = TRange;
  630. using select_predicate_type = TSelectPredicate;
  631. using less_predicate_type = TLessPredicate;
  632. using this_type = order_by_range<range_type, select_predicate_type, less_predicate_type>;
  633. using value_type = mp_range_value_type<range_type>;
  634. using wrapped_value_type = utl::wrapper<value_type>;
  635. using vector_type = std::vector<wrapped_value_type>;
  636. range_type range;
  637. select_predicate_type select_predicate;
  638. less_predicate_type less_predicate;
  639. ssize_t current;
  640. vector_type values;
  641. inline value_type& front()
  642. {
  643. assert(current >= 0 && static_cast<size_t>(current) < values.size());
  644. return *values.at(static_cast<typename vector_type::size_type>(current));
  645. }
  646. inline bool next()
  647. {
  648. if (current < 0)
  649. {
  650. values.clear();
  651. while (range.next())
  652. values.emplace_back(range.front());
  653. if (values.empty())
  654. return false;
  655. std::sort(
  656. values.begin(),
  657. values.end(),
  658. [this](wrapped_value_type& l, wrapped_value_type& r) {
  659. return this->less_predicate(
  660. this->select_predicate(*l),
  661. this->select_predicate(*r));
  662. });
  663. current = 0;
  664. return true;
  665. }
  666. if (current < static_cast<ssize_t>(values.size()))
  667. ++current;
  668. return (current < static_cast<ssize_t>(values.size()));
  669. }
  670. template<class R, class SP, class LP>
  671. inline order_by_range(R&& r, SP&& sp, LP&& lp) :
  672. range (std::forward<R>(r)),
  673. select_predicate(std::forward<SP>(sp)),
  674. less_predicate (std::forward<LP>(lp)),
  675. current (-1)
  676. { LINQ_CTOR(); }
  677. inline order_by_range(const this_type& other) :
  678. range (other.range),
  679. select_predicate(other.select_predicate),
  680. less_predicate (other.less_predicate),
  681. current (other.current)
  682. { LINQ_COPY_CTOR(); }
  683. inline order_by_range(this_type&& other) :
  684. range (std::move(other).range),
  685. select_predicate(std::move(other).select_predicate),
  686. less_predicate (std::move(other).less_predicate),
  687. current (std::move(other).current)
  688. { LINQ_MOVE_CTOR(); }
  689. inline ~order_by_range()
  690. { LINQ_DTOR(); }
  691. };
  692. template<class TRange, class TSelectPredicate, class TLessPredicate>
  693. using order_by_range_wrapper = range_wrapper<order_by_range<TRange, TSelectPredicate, TLessPredicate>>;
  694. template<class TRange, class TLessPredicate>
  695. struct distinct_range : public tag_range
  696. {
  697. using range_type = TRange;
  698. using less_predicate_type = TLessPredicate;
  699. using this_type = distinct_range<range_type, less_predicate_type>;
  700. using value_type = mp_range_value_type<range_type>;
  701. using set_value_type = utl::wrapper<value_type>;
  702. using set_less_type = op_wrapper_less<value_type, less_predicate_type>;
  703. using set_type = std::set<set_value_type, set_less_type>;
  704. range_type range;
  705. set_type set;
  706. inline value_type& front()
  707. { return range.front(); }
  708. inline bool next()
  709. {
  710. while(range.next())
  711. {
  712. if (set.emplace(range.front()).second)
  713. return true;
  714. }
  715. return false;
  716. }
  717. template<class R, class LP>
  718. inline distinct_range(R&& r, LP&& lp) :
  719. range (std::forward<R>(r)),
  720. set (std::forward<LP>(lp))
  721. { LINQ_CTOR(); }
  722. inline distinct_range(const this_type& other) :
  723. range (other.range),
  724. set (other.set)
  725. { LINQ_COPY_CTOR(); }
  726. inline distinct_range(this_type&& other) :
  727. range (std::move(other).range),
  728. set (std::move(other).set)
  729. { LINQ_MOVE_CTOR(); }
  730. inline ~distinct_range()
  731. { LINQ_DTOR(); }
  732. };
  733. template<class TRange, class TLessPredicate>
  734. using distinct_range_wrapper = range_wrapper<distinct_range<TRange, TLessPredicate>>;
  735. template<class TRange, class T>
  736. struct default_if_empty_range : public tag_range
  737. {
  738. using value_type = T;
  739. using range_type = TRange;
  740. using this_type = default_if_empty_range<range_type, value_type>;
  741. using state_type = enum class state
  742. {
  743. init,
  744. iterate,
  745. empty,
  746. finish,
  747. };
  748. range_type range;
  749. value_type value;
  750. state_type state;
  751. inline value_type& front()
  752. {
  753. assert(state != state_type::init && state != state_type::finish);
  754. return (state == state_type::empty
  755. ? value
  756. : range.front());
  757. }
  758. inline bool next()
  759. {
  760. switch(state)
  761. {
  762. case state_type::init:
  763. state = range.next()
  764. ? state_type::iterate
  765. : state_type::empty;
  766. return true;
  767. case state_type::iterate:
  768. if (!range.next())
  769. {
  770. state = state_type::finish;
  771. return false;
  772. }
  773. return true;
  774. case state_type::empty:
  775. state = state_type::finish;
  776. /* fall through */
  777. default:
  778. return false;
  779. }
  780. }
  781. template<class R, class X>
  782. inline default_if_empty_range(R&& r, X&& t) :
  783. range(std::forward<R>(r)),
  784. value(t),
  785. state(state_type::init)
  786. { LINQ_CTOR(); }
  787. inline default_if_empty_range(const default_if_empty_range& other) :
  788. range(other.range),
  789. value(other.value),
  790. state(other.state)
  791. { LINQ_COPY_CTOR(); }
  792. inline default_if_empty_range(default_if_empty_range&& other) :
  793. range(std::move(other).range),
  794. value(std::move(other).value),
  795. state(std::move(other).state)
  796. { LINQ_MOVE_CTOR(); }
  797. inline ~default_if_empty_range()
  798. { LINQ_DTOR(); }
  799. };
  800. template<class TRange, class T>
  801. using default_if_empty_range_wrapper = range_wrapper<default_if_empty_range<TRange, T>>;
  802. /* builder *******************************************************************************/
  803. template<template<class> class TOuterRange>
  804. struct builder : public tag_builder
  805. {
  806. template<class R>
  807. using outer_range_type = TOuterRange<R>;
  808. using this_type = builder<outer_range_type>;
  809. template<class TRange>
  810. inline auto build(TRange&& range)
  811. {
  812. // CAUTION: we want no reference to a range here, because the passed range may be destroyed before used in outer_range_type
  813. using range_type = utl::mp::remove_ref<TRange>;
  814. return outer_range_type<range_type>(std::forward<TRange>(range));
  815. }
  816. inline builder()
  817. { LINQ_CTOR(); }
  818. inline builder(this_type&& other)
  819. { LINQ_MOVE_CTOR(); }
  820. inline builder(const this_type&) = delete;
  821. inline ~builder()
  822. { LINQ_DTOR(); }
  823. };
  824. template<class TPredicate, template<class, class> class TOuterRange>
  825. struct predicate_builder : public tag_builder
  826. {
  827. template<class R, class P>
  828. using outer_range_type = TOuterRange<R, P>;
  829. using predicate_type = TPredicate;
  830. using this_type = predicate_builder<predicate_type, outer_range_type>;
  831. predicate_type predicate;
  832. template<class TRange>
  833. inline auto build(TRange&& range)
  834. {
  835. // CAUTION: we want no reference to a range here, because the passed range may be destroyed before used in outer_range_type
  836. using range_type = utl::mp::remove_ref<TRange>;
  837. return outer_range_type<range_type, predicate_type>(std::forward<TRange>(range), std::move(predicate));
  838. }
  839. inline predicate_builder(const predicate_type& p) :
  840. predicate(p)
  841. { LINQ_CTOR(); }
  842. inline predicate_builder(this_type&& other) :
  843. predicate(std::move(other).predicate)
  844. { LINQ_MOVE_CTOR(); }
  845. inline predicate_builder(const this_type&) = delete;
  846. inline ~predicate_builder()
  847. { LINQ_DTOR(); }
  848. };
  849. template<class TPredicate0, class TPredicate1, template<class, class, class> class TOuterRange>
  850. struct dual_predicate_builder : public tag_builder
  851. {
  852. template<class R, class P0, class P1>
  853. using outer_range_type = TOuterRange<R, P0, P1>;
  854. using predicate_0_type = TPredicate0;
  855. using predicate_1_type = TPredicate1;
  856. using this_type = dual_predicate_builder<predicate_0_type, predicate_1_type, outer_range_type>;
  857. predicate_0_type predicate0;
  858. predicate_1_type predicate1;
  859. template<class TRange>
  860. inline auto build(TRange&& range)
  861. {
  862. // CAUTION: we want no reference to a range here, because the passed range may be destroyed before used in outer_range_type
  863. using range_type = utl::mp::remove_ref<TRange>;
  864. return outer_range_type<range_type, predicate_0_type, predicate_1_type>(std::forward<range_type>(range), std::move(predicate0), std::move(predicate1));
  865. }
  866. inline dual_predicate_builder(const predicate_0_type& p0, const predicate_1_type& p1) :
  867. predicate0(p0),
  868. predicate1(p1)
  869. { LINQ_CTOR(); }
  870. inline dual_predicate_builder(this_type&& other) :
  871. predicate0(std::move(other).predicate0),
  872. predicate1(std::move(other).predicate1)
  873. { LINQ_MOVE_CTOR(); }
  874. inline dual_predicate_builder(const this_type&) = delete;
  875. inline ~dual_predicate_builder()
  876. { LINQ_DTOR(); }
  877. };
  878. template <class T>
  879. struct default_if_empty_builder : public tag_builder
  880. {
  881. using value_type = T;
  882. using this_type = default_if_empty_builder<value_type>;
  883. value_type value;
  884. template<class TRange>
  885. inline auto build(TRange&& range) const
  886. {
  887. // CAUTION: we want no reference to a range here, because the passed range may be destroyed before used in outer_range_type
  888. using range_type = utl::mp::remove_ref<TRange>;
  889. return default_if_empty_range_wrapper<range_type, T>(std::forward<range_type>(range), value);
  890. }
  891. default_if_empty_builder(T&& t) :
  892. value(t)
  893. { }
  894. default_if_empty_builder(const this_type& other) :
  895. value(other.value)
  896. { }
  897. default_if_empty_builder(this_type&& other) :
  898. value(std::move(other).value)
  899. { }
  900. };
  901. struct count_builder : public tag_builder
  902. {
  903. template<class TRange>
  904. inline auto build(TRange&& range)
  905. {
  906. size_t ret = 0;
  907. while (range.next())
  908. ++ret;
  909. return ret;
  910. }
  911. };
  912. struct sum_builder : public tag_builder
  913. {
  914. template<class TRange>
  915. inline auto build(TRange&& range)
  916. {
  917. using value_type = mp_range_value_type<TRange>;
  918. using return_type = utl::mp::clean_type<value_type>;
  919. return_type sum = return_type();
  920. while (range.next())
  921. sum += range.front();
  922. return sum;
  923. }
  924. };
  925. struct min_builder : public tag_builder
  926. {
  927. template<class TRange>
  928. inline auto build(TRange&& range)
  929. {
  930. using value_type = mp_range_value_type<TRange>;
  931. using return_type = utl::mp::clean_type<value_type>;
  932. return_type ret = std::numeric_limits<return_type>::max();
  933. while (range.next())
  934. {
  935. if (ret > range.front())
  936. ret = range.front();
  937. }
  938. return ret;
  939. }
  940. };
  941. struct max_builder : public tag_builder
  942. {
  943. template<class TRange>
  944. inline auto build(TRange&& range)
  945. {
  946. using value_type = mp_range_value_type<TRange>;
  947. using return_type = utl::mp::clean_type<value_type>;
  948. return_type ret = std::numeric_limits<return_type>::min();
  949. while (range.next())
  950. {
  951. if (ret < range.front())
  952. ret = range.front();
  953. }
  954. return ret;
  955. }
  956. };
  957. struct any_builder : public tag_builder
  958. {
  959. template<class TRange>
  960. inline auto build(TRange&& range)
  961. { return range.next(); }
  962. };
  963. template <class T, class TPredicate>
  964. struct contains_builder : public tag_builder
  965. {
  966. using comperator_type = T;
  967. using predicate_type = TPredicate;
  968. using this_type = contains_builder<comperator_type, predicate_type>;
  969. comperator_type comperator;
  970. predicate_type predicate;
  971. template<class TRange>
  972. inline auto build(TRange&& range)
  973. {
  974. while(range.next())
  975. {
  976. if (predicate(comperator, range.front()))
  977. return true;
  978. }
  979. return false;
  980. }
  981. inline contains_builder(comperator_type&& c, predicate_type&& p) :
  982. comperator(c),
  983. predicate (p)
  984. { }
  985. };
  986. struct single_builder : public tag_builder
  987. {
  988. template<class TRange>
  989. inline auto build(TRange&& range)
  990. {
  991. using range_value_type = mp_range_value_type<TRange>;
  992. if (!range.next())
  993. throw utl::exception("range is empty");
  994. auto ret = std::forward<range_value_type>(range.front());
  995. if (range.next())
  996. throw utl::exception("range contains more than one value");
  997. return ret;
  998. }
  999. };
  1000. struct single_or_default_builder : public tag_builder
  1001. {
  1002. template<class TRange>
  1003. inline auto build(TRange&& range)
  1004. {
  1005. using range_value_type = mp_range_value_type<TRange>;
  1006. using value_type = utl::mp::remove_ref<range_value_type>;
  1007. if (!range.next())
  1008. return value_type();
  1009. auto ret = std::forward<range_value_type>(range.front());
  1010. if (range.next())
  1011. return value_type();
  1012. return ret;
  1013. }
  1014. };
  1015. struct first_builder : public tag_builder
  1016. {
  1017. template<class TRange>
  1018. inline auto build(TRange&& range)
  1019. {
  1020. using range_value_type = mp_range_value_type<TRange>;
  1021. if (!range.next())
  1022. throw utl::exception("range is empty");
  1023. return std::forward<range_value_type>(range.front());
  1024. }
  1025. };
  1026. struct first_or_default_builder : public tag_builder
  1027. {
  1028. template<class TRange>
  1029. inline auto build(TRange&& range)
  1030. {
  1031. using range_value_type = mp_range_value_type<TRange>;
  1032. using value_type = utl::mp::remove_ref<range_value_type>;
  1033. if (!range.next())
  1034. return value_type();
  1035. return std::forward<range_value_type>(range.front());
  1036. }
  1037. };
  1038. struct last_builder_base
  1039. {
  1040. template<class T>
  1041. struct cache
  1042. {
  1043. std::unique_ptr<T> value;
  1044. template<class X>
  1045. inline cache& operator=(X&& x)
  1046. { value.reset(new T(std::forward<X>(x))); return *this; }
  1047. inline T& operator*()
  1048. { return *value; }
  1049. inline operator bool()
  1050. { return static_cast<bool>(value); }
  1051. inline cache()
  1052. { }
  1053. };
  1054. template<class T>
  1055. struct cache<T&>
  1056. {
  1057. T* value;
  1058. inline cache& operator=(T& t)
  1059. { value = &t; return *this; }
  1060. inline T& operator*()
  1061. { return *value; }
  1062. inline operator bool()
  1063. { return static_cast<bool>(value); }
  1064. inline cache() :
  1065. value(nullptr)
  1066. { }
  1067. };
  1068. };
  1069. struct last_builder : public tag_builder, public last_builder_base
  1070. {
  1071. template<class TRange>
  1072. inline auto build(TRange&& range)
  1073. {
  1074. using range_value_type = mp_range_value_type<TRange>;
  1075. using cache_type = cache<range_value_type>;
  1076. cache_type tmp;
  1077. while(range.next())
  1078. tmp = std::forward<range_value_type>(range.front());
  1079. if (!static_cast<bool>(tmp))
  1080. throw utl::exception("range is empty");
  1081. return std::forward<range_value_type>(*tmp);
  1082. }
  1083. };
  1084. struct last_or_default_builder : public tag_builder, public last_builder_base
  1085. {
  1086. template<class TRange>
  1087. inline auto build(TRange&& range)
  1088. {
  1089. using range_value_type = mp_range_value_type<TRange>;
  1090. using value_type = utl::mp::remove_ref<range_value_type>;
  1091. using cache_type = cache<value_type>;
  1092. cache_type tmp;
  1093. while(range.next())
  1094. tmp = std::forward<range_value_type>(range.front());
  1095. if (!static_cast<bool>(tmp))
  1096. return value_type();
  1097. return std::forward<range_value_type>(*tmp);
  1098. }
  1099. };
  1100. struct to_vector_builder : public tag_builder
  1101. {
  1102. size_t capacity;
  1103. template<class TRange>
  1104. inline auto build(TRange&& range)
  1105. {
  1106. using range_value_type = mp_range_value_type<TRange>;
  1107. using value_type = utl::mp::remove_const<utl::mp::remove_ref<range_value_type>>;
  1108. using vector_type = std::vector<value_type>;
  1109. vector_type ret;
  1110. ret.reserve(capacity);
  1111. while (range.next())
  1112. ret.emplace_back(std::forward<range_value_type>(range.front()));
  1113. return ret;
  1114. }
  1115. inline to_vector_builder(size_t cap = 16) :
  1116. capacity(cap)
  1117. { }
  1118. };
  1119. struct to_list_builder : public tag_builder
  1120. {
  1121. template<class TRange>
  1122. inline auto build(TRange&& range)
  1123. {
  1124. using range_value_type = mp_range_value_type<TRange>;
  1125. using value_type = utl::mp::remove_ref<range_value_type>;
  1126. using list_type = std::list<value_type>;
  1127. list_type ret;
  1128. while (range.next())
  1129. ret.emplace_back(std::forward<range_value_type>(range.front()));
  1130. return ret;
  1131. }
  1132. };
  1133. template<class TKeyPredicate, class TValuePredicate>
  1134. struct to_map_builder : public tag_builder
  1135. {
  1136. using key_predicate_type = TKeyPredicate;
  1137. using value_predicate_type = TValuePredicate;
  1138. using this_type = to_map_builder<key_predicate_type, value_predicate_type>;
  1139. key_predicate_type key_predicate;
  1140. value_predicate_type value_predicate;
  1141. template<class TRange>
  1142. inline auto build(TRange&& range)
  1143. {
  1144. using range_type = TRange;
  1145. using range_value_type = mp_range_value_type<range_type>;
  1146. using key_type = decltype(std::declval<key_predicate_type>()(std::declval<range_value_type&>()));
  1147. using value_type = decltype(std::declval<value_predicate_type>()(std::declval<range_value_type&>()));
  1148. using map_type = std::map<utl::mp::remove_ref<key_type>, value_type>;
  1149. map_type map;
  1150. while (range.next())
  1151. {
  1152. auto ret = map.emplace(
  1153. key_predicate(range.front()),
  1154. value_predicate(range.front()));
  1155. if (!ret.second)
  1156. throw utl::exception("duplicate key in range");
  1157. }
  1158. return map;
  1159. }
  1160. inline to_map_builder(const key_predicate_type& kp, const value_predicate_type& vp) :
  1161. key_predicate (kp),
  1162. value_predicate (vp)
  1163. { LINQ_CTOR(); }
  1164. };
  1165. template<class TPredicate>
  1166. struct for_each_builder : public tag_builder
  1167. {
  1168. using predicate_type = TPredicate;
  1169. using this_type = for_each_builder<predicate_type>;
  1170. predicate_type predicate;
  1171. template<class TRange>
  1172. inline auto build(TRange&& range)
  1173. {
  1174. while(range.next())
  1175. predicate(range.front());
  1176. }
  1177. inline for_each_builder(const predicate_type& p) :
  1178. predicate(p)
  1179. { }
  1180. };
  1181. template<class TKeyPredicate, class TValuePredicate>
  1182. struct to_lookup_builder : public tag_builder
  1183. {
  1184. using key_predicate_type = TKeyPredicate;
  1185. using value_predicate_type = TValuePredicate;
  1186. using this_type = to_lookup_builder<key_predicate_type, value_predicate_type>;
  1187. key_predicate_type key_predicate;
  1188. value_predicate_type value_predicate;
  1189. template<class TRange>
  1190. inline auto build(TRange&& range)
  1191. {
  1192. using range_type = TRange;
  1193. using range_value_type = mp_range_value_type<range_type>;
  1194. using key_type = decltype(std::declval<key_predicate_type>()(std::declval<range_value_type>()));
  1195. using value_type = decltype(std::declval<value_predicate_type>()(std::declval<range_value_type>()));
  1196. using lookup_type = lookup<key_type, value_type>;
  1197. return lookup_type::build(range, key_predicate, value_predicate);
  1198. }
  1199. inline to_lookup_builder(const key_predicate_type& kp, const value_predicate_type& vp) :
  1200. key_predicate (kp),
  1201. value_predicate (vp)
  1202. { LINQ_CTOR(); }
  1203. };
  1204. }
  1205. /* default operations ********************************************************************/
  1206. struct op_select_default
  1207. {
  1208. template<class T>
  1209. inline T operator()(T t)
  1210. { return t; }
  1211. };
  1212. struct op_less_default
  1213. {
  1214. template<class L, class R>
  1215. inline bool operator()(L&& l, R&& r) const
  1216. { return (l < r); }
  1217. };
  1218. struct op_compare_default
  1219. {
  1220. template<class L, class R>
  1221. inline bool operator()(L&& l, R&& r) const
  1222. { return (l == r); }
  1223. };
  1224. struct op_select_key_default
  1225. {
  1226. template<class TKey, class TValue>
  1227. inline auto operator()(std::pair<TKey, TValue> p)
  1228. { return p.first; }
  1229. template<class TKey, class TValue>
  1230. inline auto operator()(std::tuple<TKey, TValue> t)
  1231. { return std::get<0>(t); }
  1232. template<class T>
  1233. inline auto operator()(T& t)
  1234. { return t; }
  1235. };
  1236. struct op_select_value_default
  1237. {
  1238. template<class TKey, class TValue>
  1239. inline auto operator()(std::pair<TKey, TValue> p)
  1240. { return p.second; }
  1241. template<class TKey, class TValue>
  1242. inline auto operator()(std::tuple<TKey, TValue> t)
  1243. { return std::get<1>(t); }
  1244. template<class T>
  1245. inline auto operator()(T&& t)
  1246. { return std::forward<T>(t); }
  1247. };
  1248. /* constructors ******************************************************************************/
  1249. template<class TIterator>
  1250. inline auto from_iterator(TIterator&& beg, TIterator&& end)
  1251. { return __impl::iterator_range_wrapper<TIterator>(std::forward<TIterator>(beg), std::forward<TIterator>(end)); }
  1252. template<class TContainer>
  1253. inline auto from_container(TContainer&& container)
  1254. { return __impl::container_range_wrapper<TContainer>(std::forward<TContainer>(container)); }
  1255. template<class TPredicate>
  1256. inline auto from_generator(TPredicate&& predicate)
  1257. { return __impl::generator_range_wrapper<TPredicate>(std::forward<TPredicate>(predicate)); }
  1258. template<class TArray>
  1259. inline auto from_array(TArray&& array)
  1260. {
  1261. using array_type = typename std::remove_reference<TArray>::type;
  1262. using array_size = typename __impl::mp_array_properties<array_type>::size;
  1263. return from_iterator(&array[0], &array[array_size::value]);
  1264. }
  1265. /* filter ************************************************************************************/
  1266. template<class TPredicate>
  1267. inline auto where(TPredicate&& predicate)
  1268. { return __impl::predicate_builder<TPredicate, __impl::where_range_wrapper>(std::forward<TPredicate>(predicate)); }
  1269. template<class TPredicate>
  1270. inline auto select(TPredicate&& predicate)
  1271. { return __impl::predicate_builder<TPredicate, __impl::select_range_wrapper>(std::forward<TPredicate>(predicate)); }
  1272. template<class TPredicate>
  1273. inline auto select_many(TPredicate&& predicate)
  1274. { return __impl::predicate_builder<TPredicate, __impl::select_many_range_wrapper>(std::forward<TPredicate>(predicate)); }
  1275. template<class TSelectPredicate, class TLessPredicate>
  1276. inline auto order_by(TSelectPredicate&& sp, TLessPredicate&& lp)
  1277. { return __impl::dual_predicate_builder<TSelectPredicate, TLessPredicate, __impl::order_by_range_wrapper>(std::forward<TSelectPredicate>(sp), std::forward<TLessPredicate>(lp)); }
  1278. template<class TSelectPredicate>
  1279. inline auto order_by(TSelectPredicate&& sp)
  1280. { return order_by(std::forward(sp), op_less_default()); }
  1281. inline auto order_by()
  1282. { return order_by(op_select_default(), op_less_default()); }
  1283. template<class TLessPredicate>
  1284. inline auto distinct(TLessPredicate&& lp)
  1285. { return __impl::predicate_builder<TLessPredicate, __impl::distinct_range_wrapper>(std::forward<TLessPredicate>(lp)); }
  1286. inline auto distinct()
  1287. { return distinct(op_less_default()); }
  1288. template<class T>
  1289. inline auto default_if_empty(T&& t)
  1290. { return __impl::default_if_empty_builder<T>(std::forward<T>(t)); }
  1291. /* result generators */
  1292. inline auto count()
  1293. { return __impl::count_builder(); }
  1294. inline auto sum()
  1295. { return __impl::sum_builder(); }
  1296. inline auto min()
  1297. { return __impl::min_builder(); }
  1298. inline auto max()
  1299. { return __impl::max_builder(); }
  1300. inline auto any()
  1301. { return __impl::any_builder(); }
  1302. template<class T, class TPredicate>
  1303. inline auto contains(T&& t, TPredicate&& p)
  1304. { return __impl::contains_builder<T, TPredicate>(std::forward<T>(t), std::forward<TPredicate>(p)); }
  1305. template<class T>
  1306. inline auto contains(T&& t)
  1307. { return contains(std::forward<T>(t), op_compare_default()); }
  1308. inline auto single()
  1309. { return __impl::single_builder(); }
  1310. inline auto single_or_default()
  1311. { return __impl::single_or_default_builder(); }
  1312. inline auto first()
  1313. { return __impl::first_builder(); }
  1314. inline auto first_or_default()
  1315. { return __impl::first_or_default_builder(); }
  1316. inline auto last()
  1317. { return __impl::last_builder(); }
  1318. inline auto last_or_default()
  1319. { return __impl::last_or_default_builder(); }
  1320. inline auto to_vector(size_t capacity = 16)
  1321. { return __impl::to_vector_builder(capacity); }
  1322. inline auto to_list()
  1323. { return __impl::to_list_builder(); }
  1324. template<class TKeyPredicate, class TValuePredicate>
  1325. inline auto to_map(TKeyPredicate&& kp, TValuePredicate&& vp)
  1326. { return __impl::to_map_builder<TKeyPredicate, TValuePredicate>(std::forward<TKeyPredicate>(kp), std::forward<TValuePredicate>(vp)); }
  1327. template<class TKeyPredicate>
  1328. inline auto to_map(TKeyPredicate&& kp)
  1329. { return to_map(std::forward<TKeyPredicate>(kp), op_select_value_default()); }
  1330. inline auto to_map()
  1331. { return to_map(op_select_key_default(), op_select_value_default()); }
  1332. template<class TPredicate>
  1333. inline auto for_each(TPredicate&& p)
  1334. { return __impl::for_each_builder<TPredicate>(std::forward<TPredicate>(p)); }
  1335. template<class TKeyPredicate, class TValuePredicate>
  1336. inline auto to_lookup(TKeyPredicate&& kp, TValuePredicate&& vp)
  1337. { return __impl::to_lookup_builder<TKeyPredicate, TValuePredicate>(std::forward<TKeyPredicate>(kp), std::forward<TValuePredicate>(vp)); }
  1338. template<class TKeyPredicate>
  1339. inline auto to_lookup(TKeyPredicate&& kp)
  1340. { return to_lookup(std::forward<TKeyPredicate>(kp), op_select_value_default()); }
  1341. inline auto to_lookup()
  1342. { return to_lookup(op_select_key_default(), op_select_value_default()); }
  1343. template <class TKey, class TValue>
  1344. using lookup_value_range_type = typename __impl::lookup<TKey, TValue>::lookup_range_wrapper;
  1345. template <class TKey, class TValue>
  1346. using lookup_key_value_range_type = typename __impl::lookup<TKey, TValue>::lookup_key_value_range_wrapper;
  1347. }
  1348. }