14 #ifndef COVEO_LINQ_DETAIL_H 15 #define COVEO_LINQ_DETAIL_H 17 #include <coveo/seq/detail/enumerable_detail.h> 18 #include <coveo/seq/sequence_util.h> 22 #include <forward_list> 29 #include <type_traits> 48 template<
typename Pred>
52 const typename std::decay<Pred>::type* ppred_;
55 explicit proxy_cmp(
const Pred& pred)
56 : ppred_(std::addressof(pred)) { }
58 template<
typename T,
typename U>
59 auto operator()(T&& left, U&& right)
const ->
decltype((*ppred_)(std::forward<T>(left), std::forward<U>(right))) {
60 return (*ppred_)(std::forward<T>(left), std::forward<U>(right));
74 template<
typename Pred>
81 explicit deref_cmp(Pred&& pred)
82 : pred_(std::forward<Pred>(pred)) { }
84 template<
typename T,
typename U>
85 auto operator()(T*
const pleft, U*
const pright)
const ->
decltype(pred_(*pleft, *pright)) {
86 return pred_(*pleft, *pright);
101 template<
typename Selector>
102 class indexless_selector_proxy
108 explicit indexless_selector_proxy(Selector&& sel)
109 : sel_(std::forward<Selector>(sel)) { }
112 auto operator()(T&& element, std::size_t) ->
decltype(sel_(std::forward<T>(element))) {
113 return sel_(std::forward<T>(element));
130 template<
typename Seq>
131 class deref_next_impl
134 using iterator_type =
typename seq_traits<Seq>::iterator_type;
142 explicit deref_info(Seq&& seq)
143 : seq_(std::forward<Seq>(seq)),
144 iend_(std::end(seq_)) { }
147 deref_info(
const deref_info&) =
delete;
148 deref_info& operator=(
const deref_info&) =
delete;
150 using deref_info_sp = std::shared_ptr<deref_info>;
152 deref_info_sp spinfo_;
156 explicit deref_next_impl(Seq&& seq)
157 : spinfo_(std::make_shared<deref_info>(std::forward<Seq>(seq))),
158 icur_(std::begin(spinfo_->seq_)) { }
160 auto operator()() ->
typename seq_traits<Seq>::value_type {
161 typename seq_traits<Seq>::value_type pobj =
nullptr;
162 if (icur_ != spinfo_->iend_) {
183 template<
typename Seq>
184 auto make_deref_next_impl(Seq&& seq) -> deref_next_impl<Seq> {
185 return deref_next_impl<Seq>(std::forward<Seq>(seq));
197 template<
typename =
void>
200 auto operator()(T&& obj)
const ->
decltype(std::forward<T>(obj)) {
201 return std::forward<T>(obj);
212 template<
typename =
void>
214 template<
typename T,
typename U>
215 auto operator()(T&& obj1, U&& obj2)
const -> std::pair<T, U> {
216 return std::pair<T, U>(std::forward<T>(obj1), std::forward<U>(obj2));
228 template<
typename =
void>
230 template<
typename T,
typename U>
231 auto operator()(T&& left, U&& right)
const ->
decltype(std::forward<T>(left) < std::forward<U>(right)) {
232 return std::forward<T>(left) < std::forward<U>(right);
244 template<
typename =
void>
246 template<
typename T,
typename U>
247 auto operator()(T&& left, U&& right)
const ->
decltype(std::forward<T>(left) > std::forward<U>(right)) {
248 return std::forward<T>(left) > std::forward<U>(right);
265 template<
typename T,
typename... Args>
266 auto make_unique(Args&&... args) -> std::unique_ptr<T> {
267 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
284 class aggregate_impl_1
290 explicit aggregate_impl_1(
const F& agg_f)
293 template<
typename Seq>
294 auto operator()(Seq&& seq) ->
typename std::decay<
decltype(*std::begin(seq))>::type {
295 auto it = std::begin(seq);
296 auto end = std::end(seq);
298 throw_linq_empty_sequence();
301 for (++it; it != end; ++it) {
302 aggregate = agg_f_(aggregate, *it);
320 template<
typename Acc,
typename F>
321 class aggregate_impl_2
328 aggregate_impl_2(
const Acc& seed,
const F& agg_f)
329 : seed_(seed), agg_f_(agg_f) { }
331 template<
typename Seq>
332 auto operator()(Seq&& seq) -> Acc {
333 Acc aggregate(seed_);
334 for (
auto&& element : seq) {
335 aggregate = agg_f_(aggregate, element);
355 template<
typename Acc,
typename F,
typename RF>
356 class aggregate_impl_3 :
public aggregate_impl_2<Acc, F>
362 aggregate_impl_3(
const Acc& seed,
const F& agg_f,
const RF& result_f)
363 : aggregate_impl_2<Acc, F>(seed, agg_f), result_f_(result_f) { }
365 template<
typename Seq>
366 auto operator()(Seq&& seq) ->
decltype(result_f_(std::declval<Acc>())) {
367 return result_f_(aggregate_impl_2<Acc, F>::operator()(seq));
381 template<
typename Pred>
388 explicit all_impl(
const Pred& pred)
391 template<
typename Seq>
392 auto operator()(Seq&& seq) ->
bool {
393 return std::all_of(std::begin(seq), std::end(seq), pred_);
407 template<
typename =
void>
411 template<
typename Seq>
412 auto operator()(Seq&& seq) ->
bool {
413 return std::begin(seq) != std::end(seq);
428 template<
typename Pred>
435 explicit any_impl_1(
const Pred& pred)
438 template<
typename Seq>
439 auto operator()(Seq&& seq) ->
bool {
440 return std::any_of(std::begin(seq), std::end(seq), pred_);
461 explicit average_impl(
const F& num_f)
464 template<
typename Seq>
465 auto operator()(Seq&& seq)
466 ->
typename std::decay<
decltype(num_f_(*std::begin(seq)))>::type
468 auto it = std::begin(seq);
469 auto end = std::end(seq);
471 throw_linq_empty_sequence();
473 auto total = num_f_(*it);
474 decltype(total) count = 1;
475 for (++it; it != end; ++it) {
476 total += num_f_(*it);
479 return total / count;
499 auto operator()(T&& obj)
const -> U {
500 return static_cast<U>(obj);
515 template<
typename Seq2>
520 template<
typename Seq1>
526 using enum_type =
typename std::conditional<std::is_const<
typename seq_traits<Seq1>::value_type>::value ||
527 std::is_const<
typename seq_traits<Seq2>::value_type>::value,
535 using first_iterator_type =
typename seq_traits<Seq1>::iterator_type;
536 using second_iterator_type =
typename seq_traits<Seq2>::iterator_type;
543 first_iterator_type iend1_;
545 second_iterator_type iend2_;
548 concat_info(Seq1&& seq1, Seq2&& seq2)
549 : seq1_(std::forward<Seq1>(seq1)),
550 iend1_(std::end(seq1_)),
551 seq2_(std::forward<Seq2>(seq2)),
552 iend2_(std::end(seq2_)) { }
555 concat_info(
const concat_info&) =
delete;
556 concat_info& operator=(
const concat_info&) =
delete;
558 first_iterator_type first_begin() {
559 return std::begin(seq1_);
561 second_iterator_type second_begin() {
562 return std::begin(seq2_);
566 auto get_next(first_iterator_type& icur1, second_iterator_type& icur2) -> enum_pointer {
568 enum_pointer pobj =
nullptr;
569 if (icur1 != iend1_) {
570 enum_reference robj = *icur1;
571 pobj = std::addressof(robj);
573 }
else if (icur2 != iend2_) {
574 enum_reference robj = *icur2;
575 pobj = std::addressof(robj);
581 using concat_info_sp = std::shared_ptr<concat_info>;
583 concat_info_sp spinfo_;
584 first_iterator_type icur1_;
585 second_iterator_type icur2_;
588 next_impl(Seq1&& seq1, Seq2&& seq2)
589 : spinfo_(std::make_shared<concat_info>(std::forward<Seq1>(seq1), std::forward<Seq2>(seq2))),
590 icur1_(spinfo_->first_begin()), icur2_(spinfo_->second_begin()) { }
592 auto operator()() ->
decltype(spinfo_->get_next(icur1_, icur2_)) {
593 return spinfo_->get_next(icur1_, icur2_);
601 explicit concat_impl(Seq2&& seq2)
602 : seq2_(std::forward<Seq2>(seq2)) { }
605 concat_impl(
const concat_impl&) =
delete;
606 concat_impl(concat_impl&&) =
default;
607 concat_impl& operator=(
const concat_impl&) =
delete;
608 concat_impl& operator=(concat_impl&&) =
default;
610 template<
typename Seq1>
611 auto operator()(Seq1&& seq1)
612 ->
enumerable<
typename next_impl<Seq1>::enum_type>
614 auto siz1 = try_get_size_delegate(seq1);
615 auto siz2 = try_get_size_delegate(seq2_);
616 typename enumerable<
typename next_impl<Seq1>::enum_type>::size_delegate siz;
617 if (siz1 !=
nullptr && siz2 !=
nullptr) {
618 std::size_t size = siz1() + siz2();
619 siz = [size]() -> std::size_t {
return size; };
621 return { next_impl<Seq1>(std::forward<Seq1>(seq1), std::forward<Seq2>(seq2_)),
638 class contains_impl_1
644 explicit contains_impl_1(
const T& obj)
647 template<
typename Seq>
648 auto operator()(Seq&& seq) ->
bool {
650 for (
auto&& element : seq) {
651 if (element == obj_) {
672 template<
typename T,
typename Pred>
673 class contains_impl_2
680 contains_impl_2(
const T& obj,
const Pred& pred)
681 : obj_(obj), pred_(pred) { }
683 template<
typename Seq>
684 auto operator()(Seq&& seq) ->
bool {
686 for (
auto&& element : seq) {
687 if (pred_(element, obj_)) {
706 template<
typename =
void>
711 template<
typename Seq,
712 typename =
typename std::enable_if<coveo::detail::has_size_const_method<
typename std::decay<Seq>::type>::value,
void>::type>
713 auto impl(Seq&& seq) -> std::size_t {
718 template<
typename Seq,
719 typename _V =
typename std::enable_if<!coveo::detail::has_size_const_method<
typename std::decay<Seq>::type>::value,
void*>::type>
720 auto impl(Seq&& seq, _V =
nullptr) -> std::size_t {
721 return static_cast<std::size_t>(std::distance(std::begin(seq), std::end(seq)));
725 template<
typename Seq>
726 auto operator()(Seq&& seq) -> std::size_t {
727 return impl(std::forward<Seq>(seq));
742 template<
typename Pred>
749 explicit count_impl_1(
const Pred& pred)
752 template<
typename Seq>
753 auto operator()(Seq&& seq) -> std::size_t {
754 return static_cast<std::size_t>(std::count_if(std::begin(seq), std::end(seq), pred_));
768 template<
typename =
void>
769 class default_if_empty_impl_0
772 template<
typename Seq>
773 auto operator()(Seq&& seq)
776 enumerable<
typename seq_traits<Seq>::const_value_type> e;
777 if (any_impl_0<>()(std::forward<Seq>(seq))) {
778 e = enumerate_container(std::forward<Seq>(seq));
780 e = enumerate_one(
typename seq_traits<Seq>::raw_value_type());
798 class default_if_empty_impl_1
804 explicit default_if_empty_impl_1(
const T& obj)
807 template<
typename Seq>
808 auto operator()(Seq&& seq)
811 enumerable<
typename seq_traits<Seq>::const_value_type> e;
812 if (any_impl_0<>()(std::forward<Seq>(seq))) {
813 e = enumerate_container(std::forward<Seq>(seq));
815 e = enumerate_one(
typename seq_traits<Seq>::raw_value_type(obj_));
831 template<
typename Pred>
836 template<
typename Seq>
841 using iterator_type =
typename seq_traits<Seq>::iterator_type;
844 using seen_elements_set = std::set<
typename seq_traits<Seq>::const_pointer, deref_cmp<proxy_cmp<Pred>>>;
855 distinct_info(Seq&& seq, Pred&& pred)
856 : seq_(std::forward<Seq>(seq)),
857 iend_(std::end(seq_)),
858 pred_(std::forward<Pred>(pred)) { }
861 distinct_info(
const distinct_info&) =
delete;
862 distinct_info& operator=(
const distinct_info&) =
delete;
864 iterator_type seq_begin() {
865 return std::begin(seq_);
867 seen_elements_set init_seen_elements() {
868 return seen_elements_set(deref_cmp<proxy_cmp<Pred>>(proxy_cmp<Pred>(pred_)));
872 auto get_next(iterator_type& icur, seen_elements_set& seen)
875 typename seq_traits<Seq>::pointer pobj =
nullptr;
876 for (; pobj ==
nullptr && icur != iend_; ++icur) {
877 typename seq_traits<Seq>::reference robjtmp = *icur;
878 auto pobjtmp = std::addressof(robjtmp);
879 if (seen.emplace(pobjtmp).second) {
887 using distinct_info_sp = std::shared_ptr<distinct_info>;
889 distinct_info_sp spinfo_;
891 seen_elements_set seen_;
894 next_impl(Seq&& seq, Pred&& pred)
895 : spinfo_(std::make_shared<distinct_info>(std::forward<Seq>(seq), std::forward<Pred>(pred))),
896 icur_(spinfo_->seq_begin()), seen_(spinfo_->init_seen_elements()) { }
898 auto operator()() ->
decltype(spinfo_->get_next(icur_, seen_)) {
899 return spinfo_->get_next(icur_, seen_);
907 explicit distinct_impl(Pred&& pred)
908 : pred_(std::forward<Pred>(pred)) { }
911 distinct_impl(
const distinct_impl&) =
delete;
912 distinct_impl(distinct_impl&&) =
default;
913 distinct_impl& operator=(
const distinct_impl&) =
delete;
914 distinct_impl& operator=(distinct_impl&&) =
default;
916 template<
typename Seq>
917 auto operator()(Seq&& seq)
920 return next_impl<Seq>(std::forward<Seq>(seq), std::forward<Pred>(pred_));
933 template<
typename =
void>
934 class element_at_impl
941 template<
typename Seq>
942 auto impl(Seq&& seq, std::random_access_iterator_tag) ->
decltype(*std::begin(seq)) {
943 auto icur = std::begin(seq);
944 auto iend = std::end(seq);
945 if (
static_cast<std::size_t>(iend - icur) <= n_) {
946 throw_linq_out_of_range();
953 template<
typename Seq>
954 auto impl(Seq&& seq, std::input_iterator_tag) ->
decltype(*std::begin(seq)) {
955 auto icur = std::begin(seq);
956 auto iend = std::end(seq);
957 for (std::size_t i = 0; i < n_ && icur != iend; ++i, ++icur) {
960 throw_linq_out_of_range();
966 explicit element_at_impl(std::size_t n)
969 template<
typename Seq>
970 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
971 return impl(std::forward<Seq>(seq),
972 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
985 template<
typename =
void>
986 class element_at_or_default_impl
993 template<
typename Seq>
994 auto impl(Seq&& seq, std::random_access_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
995 auto icur = std::begin(seq);
996 auto iend = std::end(seq);
997 return static_cast<std::size_t>(iend - icur) > n_ ? *(icur + n_)
998 :
typename seq_traits<Seq>::raw_value_type();
1002 template<
typename Seq>
1003 auto impl(Seq&& seq, std::input_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
1004 auto icur = std::begin(seq);
1005 auto iend = std::end(seq);
1006 for (std::size_t i = 0; i < n_ && icur != iend; ++i, ++icur) {
1008 return icur != iend ? *icur
1009 :
typename seq_traits<Seq>::raw_value_type();
1013 element_at_or_default_impl(std::size_t n)
1016 template<
typename Seq>
1017 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
1018 return impl(std::forward<Seq>(seq),
1019 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
1034 template<
typename Seq2,
typename Pred>
1039 template<
typename Seq1>
1044 using elements_to_filter_v = std::vector<
typename seq_traits<Seq2>::const_pointer>;
1047 using first_iterator_type =
typename seq_traits<Seq1>::iterator_type;
1054 first_iterator_type iend1_;
1056 deref_cmp<Pred> pred_;
1057 elements_to_filter_v v_to_filter_;
1058 bool init_called_ =
false;
1061 try_reserve(v_to_filter_, seq2_);
1062 auto icur2 = std::begin(seq2_);
1063 auto iend2 = std::end(seq2_);
1064 for (; icur2 != iend2; ++icur2) {
1065 typename seq_traits<Seq2>::const_reference robjtmp = *icur2;
1066 v_to_filter_.emplace_back(std::addressof(robjtmp));
1068 std::sort(v_to_filter_.begin(), v_to_filter_.end(), pred_);
1069 init_called_ =
true;
1073 filter_info(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
1074 : seq1_(std::forward<Seq1>(seq1)), iend1_(std::end(seq1_)),
1075 seq2_(std::forward<Seq2>(seq2)), pred_(std::forward<Pred>(pred)) { }
1078 filter_info(
const filter_info&) =
delete;
1079 filter_info& operator=(
const filter_info&) =
delete;
1081 first_iterator_type first_begin() {
1082 return std::begin(seq1_);
1085 bool filtered(
const typename seq_traits<Seq1>::pointer pobj) {
1086 if (!init_called_) {
1090 return std::binary_search(v_to_filter_.cbegin(), v_to_filter_.cend(), pobj, pred_);
1094 auto get_next(first_iterator_type& icur1) ->
typename seq_traits<Seq1>::pointer {
1095 typename seq_traits<Seq1>::pointer pobj =
nullptr;
1096 for (; pobj ==
nullptr && icur1 != iend1_; ++icur1) {
1097 typename seq_traits<Seq1>::reference robjtmp = *icur1;
1098 auto pobjtmp = std::addressof(robjtmp);
1099 if (!filtered(pobjtmp)) {
1106 using filter_info_sp = std::shared_ptr<filter_info>;
1108 filter_info_sp spfilter_;
1109 first_iterator_type icur_;
1112 next_impl(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
1113 : spfilter_(std::make_shared<filter_info>(std::forward<Seq1>(seq1),
1114 std::forward<Seq2>(seq2),
1115 std::forward<Pred>(pred))),
1116 icur_(spfilter_->first_begin()) { }
1118 auto operator()() ->
decltype(spfilter_->get_next(icur_)) {
1119 return spfilter_->get_next(icur_);
1128 except_impl(Seq2&& seq2, Pred&& pred)
1129 : seq2_(std::forward<Seq2>(seq2)), pred_(std::forward<Pred>(pred)) { }
1132 except_impl(
const except_impl&) =
delete;
1133 except_impl(except_impl&&) =
default;
1134 except_impl& operator=(
const except_impl&) =
delete;
1135 except_impl& operator=(except_impl&&) =
default;
1137 template<
typename Seq1>
1138 auto operator()(Seq1&& seq1)
1141 return next_impl<Seq1>(std::forward<Seq1>(seq1),
1142 std::forward<Seq2>(seq2_),
1143 std::forward<Pred>(pred_));
1157 template<
typename =
void>
1161 template<
typename Seq>
1162 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
1163 auto icur = std::begin(seq);
1164 if (icur == std::end(seq)) {
1165 throw_linq_empty_sequence();
1182 template<
typename Pred>
1189 explicit first_impl_1(
const Pred& pred)
1192 template<
typename Seq>
1193 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
1194 auto icur = std::begin(seq);
1195 auto iend = std::end(seq);
1197 throw_linq_empty_sequence();
1199 auto ifound = std::find_if(icur, iend, pred_);
1200 if (ifound == iend) {
1201 throw_linq_out_of_range();
1217 template<
typename =
void>
1218 class first_or_default_impl_0
1221 template<
typename Seq>
1222 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
1223 auto icur = std::begin(seq);
1224 return icur != std::end(seq) ? *icur
1225 :
typename seq_traits<Seq>::raw_value_type();
1240 template<
typename Pred>
1241 class first_or_default_impl_1
1247 explicit first_or_default_impl_1(
const Pred& pred)
1250 template<
typename Seq>
1251 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
1252 auto iend = std::end(seq);
1253 auto ifound = std::find_if(std::begin(seq), iend, pred_);
1254 return ifound != iend ? *ifound
1255 :
typename seq_traits<Seq>::raw_value_type();
1278 template<
typename KeySelector,
1279 typename ValueSelector,
1280 typename ResultSelector,
1286 template<
typename Seq>
1291 using key =
decltype(std::declval<KeySelector>()(std::declval<
typename seq_traits<Seq>::reference>()));
1292 using value =
decltype(std::declval<ValueSelector>()(std::declval<
typename seq_traits<Seq>::reference>()));
1295 using value_v = std::vector<
typename std::decay<value>::type>;
1296 using values =
decltype(enumerate_container(std::declval<value_v&&>()));
1299 using values_by_key_m = std::map<
typename std::decay<key>::type, value_v, proxy_cmp<Pred>>;
1302 using result =
decltype(std::declval<ResultSelector>()(std::declval<key>(), std::declval<values>()));
1305 using result_v = std::vector<
typename std::decay<result>::type>;
1313 KeySelector key_sel_;
1314 ValueSelector value_sel_;
1315 ResultSelector result_sel_;
1318 bool init_called_ =
false;
1322 values_by_key_m groups{proxy_cmp<Pred>(pred_)};
1323 for (
auto&& obj : seq_) {
1324 groups[key_sel_(obj)].emplace_back(value_sel_(obj));
1330 results_.reserve(groups.size());
1331 for (
auto&& group_pair : groups) {
1332 results_.emplace_back(result_sel_(group_pair.first,
1333 enumerate_container(std::move(group_pair.second))));
1336 init_called_ =
true;
1340 groups_info(Seq&& seq, KeySelector&& key_sel, ValueSelector&& value_sel,
1341 ResultSelector&& result_sel, Pred&& pred)
1342 : seq_(std::forward<Seq>(seq)),
1343 key_sel_(std::forward<KeySelector>(key_sel)),
1344 value_sel_(std::forward<ValueSelector>(value_sel)),
1345 result_sel_(std::forward<ResultSelector>(result_sel)),
1346 pred_(std::forward<Pred>(pred)) { }
1349 groups_info(
const groups_info&) =
delete;
1350 groups_info& operator=(
const groups_info&) =
delete;
1352 const result_v& get_results() {
1353 if (!init_called_) {
1359 using groups_info_sp = std::shared_ptr<groups_info>;
1361 groups_info_sp spgroups_;
1362 typename result_v::const_iterator icurr_{};
1363 typename result_v::const_iterator iendr_{};
1364 bool init_called_ =
false;
1367 const auto& results = spgroups_->get_results();
1368 icurr_ = std::begin(results);
1369 iendr_ = std::end(results);
1370 init_called_ =
true;
1374 next_impl(Seq&& seq, KeySelector&& key_sel, ValueSelector&& value_sel,
1375 ResultSelector&& result_sel, Pred&& pred)
1376 : spgroups_(std::make_shared<groups_info>(std::forward<Seq>(seq),
1377 std::forward<KeySelector>(key_sel),
1378 std::forward<ValueSelector>(value_sel),
1379 std::forward<ResultSelector>(result_sel),
1380 std::forward<Pred>(pred))) { }
1382 auto operator()() ->
typename seq_traits<result_v>::const_pointer {
1384 if (!init_called_) {
1387 typename seq_traits<result_v>::const_pointer pobj =
nullptr;
1388 if (icurr_ != iendr_) {
1389 typename seq_traits<result_v>::const_reference robj = *icurr_;
1390 pobj = std::addressof(robj);
1398 KeySelector key_sel_;
1399 ValueSelector value_sel_;
1400 ResultSelector result_sel_;
1404 group_by_impl(KeySelector&& key_sel, ValueSelector&& value_sel,
1405 ResultSelector&& result_sel, Pred&& pred)
1406 : key_sel_(std::forward<KeySelector>(key_sel)),
1407 value_sel_(std::forward<ValueSelector>(value_sel)),
1408 result_sel_(std::forward<ResultSelector>(result_sel)),
1409 pred_(std::forward<Pred>(pred)) { }
1412 group_by_impl(
const group_by_impl&) =
delete;
1413 group_by_impl(group_by_impl&&) =
default;
1414 group_by_impl& operator=(
const group_by_impl&) =
delete;
1415 group_by_impl& operator=(group_by_impl&&) =
default;
1417 template<
typename Seq>
1418 auto operator()(Seq&& seq)
1421 return next_impl<Seq>(std::forward<Seq>(seq),
1422 std::forward<KeySelector>(key_sel_),
1423 std::forward<ValueSelector>(value_sel_),
1424 std::forward<ResultSelector>(result_sel_),
1425 std::forward<Pred>(pred_));
1448 template<
typename InnerSeq,
1449 typename OuterKeySelector,
1450 typename InnerKeySelector,
1451 typename ResultSelector,
1453 class group_join_impl
1457 template<
typename OuterSeq>
1462 using key =
decltype(std::declval<OuterKeySelector>()(std::declval<
typename seq_traits<OuterSeq>::reference>()));
1465 using inner_element_v = std::vector<
typename seq_traits<InnerSeq>::pointer>;
1469 using result =
decltype(std::declval<ResultSelector>()(std::declval<
typename seq_traits<OuterSeq>::reference>(),
1470 std::declval<inner_elements>()));
1473 using result_v = std::vector<
typename std::decay<result>::type>;
1480 OuterSeq outer_seq_;
1481 InnerSeq inner_seq_;
1482 OuterKeySelector outer_key_sel_;
1483 InnerKeySelector inner_key_sel_;
1484 ResultSelector result_sel_;
1487 bool init_called_ =
false;
1491 using groups_m = std::map<
typename std::decay<key>::type, inner_element_v, proxy_cmp<Pred>>;
1492 groups_m keyed_inner_elems{proxy_cmp<Pred>(pred_)};
1493 for (
auto&& inner_elem : inner_seq_) {
1494 typename seq_traits<InnerSeq>::reference robj = inner_elem;
1495 keyed_inner_elems[inner_key_sel_(inner_elem)].emplace_back(std::addressof(robj));
1500 try_reserve(results_, outer_seq_);
1501 const auto iendki = keyed_inner_elems.end();
1502 for (
auto&& outer_elem : outer_seq_) {
1503 const key outer_key = outer_key_sel_(outer_elem);
1504 const auto icurki = keyed_inner_elems.find(outer_key);
1505 inner_elements inner_elems;
1506 if (icurki != iendki) {
1507 const std::size_t inner_size = icurki->second.size();
1508 inner_elems = inner_elements(make_deref_next_impl(icurki->second),
1509 [inner_size]() -> std::size_t {
return inner_size; });
1511 results_.emplace_back(result_sel_(outer_elem, inner_elems));
1514 init_called_ =
true;
1518 groups_info(OuterSeq&& outer_seq, InnerSeq&& inner_seq,
1519 OuterKeySelector&& outer_key_sel, InnerKeySelector&& inner_key_sel,
1520 ResultSelector&& result_sel, Pred&& pred)
1521 : outer_seq_(std::forward<OuterSeq>(outer_seq)),
1522 inner_seq_(std::forward<InnerSeq>(inner_seq)),
1523 outer_key_sel_(std::forward<OuterKeySelector>(outer_key_sel)),
1524 inner_key_sel_(std::forward<InnerKeySelector>(inner_key_sel)),
1525 result_sel_(std::forward<ResultSelector>(result_sel)),
1526 pred_(std::forward<Pred>(pred)) { }
1529 groups_info(
const groups_info&) =
delete;
1530 groups_info& operator=(
const groups_info&) =
delete;
1532 const result_v& get_results() {
1533 if (!init_called_) {
1539 using groups_info_sp = std::shared_ptr<groups_info>;
1541 groups_info_sp spgroups_;
1542 typename result_v::const_iterator icurr_{};
1543 typename result_v::const_iterator iendr_{};
1544 bool init_called_ =
false;
1547 const auto& results = spgroups_->get_results();
1548 icurr_ = std::begin(results);
1549 iendr_ = std::end(results);
1550 init_called_ =
true;
1554 next_impl(OuterSeq&& outer_seq, InnerSeq&& inner_seq,
1555 OuterKeySelector&& outer_key_sel, InnerKeySelector&& inner_key_sel,
1556 ResultSelector&& result_sel, Pred&& pred)
1557 : spgroups_(std::make_shared<groups_info>(std::forward<OuterSeq>(outer_seq),
1558 std::forward<InnerSeq>(inner_seq),
1559 std::forward<OuterKeySelector>(outer_key_sel),
1560 std::forward<InnerKeySelector>(inner_key_sel),
1561 std::forward<ResultSelector>(result_sel),
1562 std::forward<Pred>(pred))) { }
1564 auto operator()() ->
typename seq_traits<result_v>::const_pointer {
1566 if (!init_called_) {
1569 typename seq_traits<result_v>::const_pointer pobj =
nullptr;
1570 if (icurr_ != iendr_) {
1571 typename seq_traits<result_v>::const_reference robj = *icurr_;
1572 pobj = std::addressof(robj);
1580 InnerSeq inner_seq_;
1581 OuterKeySelector outer_key_sel_;
1582 InnerKeySelector inner_key_sel_;
1583 ResultSelector result_sel_;
1587 group_join_impl(InnerSeq&& inner_seq,
1588 OuterKeySelector&& outer_key_sel,
1589 InnerKeySelector&& inner_key_sel,
1590 ResultSelector&& result_sel,
1592 : inner_seq_(std::forward<InnerSeq>(inner_seq)),
1593 outer_key_sel_(std::forward<OuterKeySelector>(outer_key_sel)),
1594 inner_key_sel_(std::forward<InnerKeySelector>(inner_key_sel)),
1595 result_sel_(std::forward<ResultSelector>(result_sel)),
1596 pred_(std::forward<Pred>(pred)) { }
1599 group_join_impl(
const group_join_impl&) =
delete;
1600 group_join_impl(group_join_impl&&) =
default;
1601 group_join_impl& operator=(
const group_join_impl&) =
delete;
1602 group_join_impl& operator=(group_join_impl&&) =
default;
1604 template<
typename OuterSeq>
1605 auto operator()(OuterSeq&& outer_seq)
1608 return next_impl<OuterSeq>(std::forward<OuterSeq>(outer_seq),
1609 std::forward<InnerSeq>(inner_seq_),
1610 std::forward<OuterKeySelector>(outer_key_sel_),
1611 std::forward<InnerKeySelector>(inner_key_sel_),
1612 std::forward<ResultSelector>(result_sel_),
1613 std::forward<Pred>(pred_));
1629 template<
typename Seq2,
typename Pred>
1630 class intersect_impl
1634 template<
typename Seq1>
1639 using seq2_element_v = std::vector<
typename seq_traits<Seq2>::pointer>;
1642 using first_iterator_type =
typename seq_traits<Seq1>::iterator_type;
1645 class intersect_info
1649 first_iterator_type iend1_;
1651 deref_cmp<Pred> pred_;
1652 seq2_element_v v_in_seq2_;
1653 bool init_called_ =
false;
1657 try_reserve(v_in_seq2_, seq2_);
1658 auto icur2 = std::begin(seq2_);
1659 auto iend2 = std::end(seq2_);
1660 for (; icur2 != iend2; ++icur2) {
1661 typename seq_traits<Seq2>::reference robjtmp = *icur2;
1662 v_in_seq2_.emplace_back(std::addressof(robjtmp));
1664 std::sort(v_in_seq2_.begin(), v_in_seq2_.end(), pred_);
1665 init_called_ =
true;
1669 intersect_info(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
1670 : seq1_(std::forward<Seq1>(seq1)),
1671 iend1_(std::end(seq1_)),
1672 seq2_(std::forward<Seq2>(seq2)),
1673 pred_(std::forward<Pred>(pred)) { }
1676 intersect_info(
const intersect_info&) =
delete;
1677 intersect_info& operator=(
const intersect_info&) =
delete;
1679 first_iterator_type first_begin() {
1680 return std::begin(seq1_);
1683 bool is_in_seq2(
const typename seq_traits<Seq1>::pointer pobj) {
1684 if (!init_called_) {
1687 return std::binary_search(v_in_seq2_.cbegin(), v_in_seq2_.cend(), pobj, pred_);
1691 auto get_next(first_iterator_type& icur1) ->
typename seq_traits<Seq1>::pointer {
1692 typename seq_traits<Seq1>::pointer pobj =
nullptr;
1693 for (; pobj ==
nullptr && icur1 != iend1_; ++icur1) {
1694 typename seq_traits<Seq1>::reference robjtmp = *icur1;
1695 auto pobjtmp = std::addressof(robjtmp);
1696 if (is_in_seq2(pobjtmp)) {
1703 using intersect_info_sp = std::shared_ptr<intersect_info>;
1705 intersect_info_sp spint_info_;
1706 first_iterator_type icur_;
1709 next_impl(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
1710 : spint_info_(std::make_shared<intersect_info>(std::forward<Seq1>(seq1),
1711 std::forward<Seq2>(seq2),
1712 std::forward<Pred>(pred))),
1713 icur_(spint_info_->first_begin()) { }
1715 auto operator()() ->
decltype(spint_info_->get_next(icur_)) {
1716 return spint_info_->get_next(icur_);
1725 intersect_impl(Seq2&& seq2, Pred&& pred)
1726 : seq2_(std::forward<Seq2>(seq2)),
1727 pred_(std::forward<Pred>(pred)) { }
1730 intersect_impl(
const intersect_impl&) =
delete;
1731 intersect_impl(intersect_impl&&) =
default;
1732 intersect_impl& operator=(
const intersect_impl&) =
delete;
1733 intersect_impl& operator=(intersect_impl&&) =
default;
1735 template<
typename Seq1>
1736 auto operator()(Seq1&& seq1)
1739 return next_impl<Seq1>(std::forward<Seq1>(seq1),
1740 std::forward<Seq2>(seq2_),
1741 std::forward<Pred>(pred_));
1764 template<
typename InnerSeq,
1765 typename OuterKeySelector,
1766 typename InnerKeySelector,
1767 typename ResultSelector,
1773 template<
typename OuterSeq>
1778 using key =
decltype(std::declval<OuterKeySelector>()(std::declval<
typename seq_traits<OuterSeq>::reference>()));
1781 using inner_element_v = std::vector<
typename seq_traits<InnerSeq>::pointer>;
1784 using result =
decltype(std::declval<ResultSelector>()(std::declval<
typename seq_traits<OuterSeq>::reference>(),
1785 std::declval<
typename seq_traits<InnerSeq>::reference>()));
1788 using result_v = std::vector<
typename std::decay<result>::type>;
1795 OuterSeq outer_seq_;
1796 InnerSeq inner_seq_;
1797 OuterKeySelector outer_key_sel_;
1798 InnerKeySelector inner_key_sel_;
1799 ResultSelector result_sel_;
1802 bool init_called_ =
false;
1806 using groups_m = std::map<
typename std::decay<key>::type, inner_element_v, proxy_cmp<Pred>>;
1807 groups_m keyed_inner_elems{proxy_cmp<Pred>(pred_)};
1808 for (
auto&& inner_elem : inner_seq_) {
1809 typename seq_traits<InnerSeq>::reference robj = inner_elem;
1810 keyed_inner_elems[inner_key_sel_(inner_elem)].emplace_back(std::addressof(robj));
1815 try_reserve(results_, inner_seq_);
1816 const auto iendki = keyed_inner_elems.end();
1817 for (
auto&& outer_elem : outer_seq_) {
1818 const key outer_key = outer_key_sel_(outer_elem);
1819 const auto icurki = keyed_inner_elems.find(outer_key);
1820 if (icurki != iendki) {
1821 for (
auto* pinner_elem : icurki->second) {
1822 results_.emplace_back(result_sel_(outer_elem, *pinner_elem));
1827 init_called_ =
true;
1831 join_info(OuterSeq&& outer_seq, InnerSeq&& inner_seq,
1832 OuterKeySelector&& outer_key_sel, InnerKeySelector&& inner_key_sel,
1833 ResultSelector&& result_sel, Pred&& pred)
1834 : outer_seq_(std::forward<OuterSeq>(outer_seq)),
1835 inner_seq_(std::forward<InnerSeq>(inner_seq)),
1836 outer_key_sel_(std::forward<OuterKeySelector>(outer_key_sel)),
1837 inner_key_sel_(std::forward<InnerKeySelector>(inner_key_sel)),
1838 result_sel_(std::forward<ResultSelector>(result_sel)),
1839 pred_(std::forward<Pred>(pred)) { }
1842 join_info(
const join_info&) =
delete;
1843 join_info& operator=(
const join_info&) =
delete;
1845 const result_v& get_results() {
1846 if (!init_called_) {
1852 using join_info_sp = std::shared_ptr<join_info>;
1854 join_info_sp spjoin_info_;
1855 typename result_v::const_iterator icurr_{};
1856 typename result_v::const_iterator iendr_{};
1857 bool init_called_ =
false;
1860 const auto& results = spjoin_info_->get_results();
1861 icurr_ = std::begin(results);
1862 iendr_ = std::end(results);
1863 init_called_ =
true;
1867 next_impl(OuterSeq&& outer_seq, InnerSeq&& inner_seq,
1868 OuterKeySelector&& outer_key_sel, InnerKeySelector&& inner_key_sel,
1869 ResultSelector&& result_sel, Pred&& pred)
1870 : spjoin_info_(std::make_shared<join_info>(std::forward<OuterSeq>(outer_seq),
1871 std::forward<InnerSeq>(inner_seq),
1872 std::forward<OuterKeySelector>(outer_key_sel),
1873 std::forward<InnerKeySelector>(inner_key_sel),
1874 std::forward<ResultSelector>(result_sel),
1875 std::forward<Pred>(pred))) { }
1877 auto operator()() ->
typename seq_traits<result_v>::const_pointer {
1879 if (!init_called_) {
1882 typename seq_traits<result_v>::const_pointer pobj =
nullptr;
1883 if (icurr_ != iendr_) {
1884 typename seq_traits<result_v>::const_reference robj = *icurr_;
1885 pobj = std::addressof(robj);
1893 InnerSeq inner_seq_;
1894 OuterKeySelector outer_key_sel_;
1895 InnerKeySelector inner_key_sel_;
1896 ResultSelector result_sel_;
1900 join_impl(InnerSeq&& inner_seq,
1901 OuterKeySelector&& outer_key_sel,
1902 InnerKeySelector&& inner_key_sel,
1903 ResultSelector&& result_sel,
1905 : inner_seq_(std::forward<InnerSeq>(inner_seq)),
1906 outer_key_sel_(std::forward<OuterKeySelector>(outer_key_sel)),
1907 inner_key_sel_(std::forward<InnerKeySelector>(inner_key_sel)),
1908 result_sel_(std::forward<ResultSelector>(result_sel)),
1909 pred_(std::forward<Pred>(pred)) { }
1912 join_impl(
const join_impl&) =
delete;
1913 join_impl(join_impl&&) =
default;
1914 join_impl& operator=(
const join_impl&) =
delete;
1915 join_impl& operator=(join_impl&&) =
default;
1917 template<
typename OuterSeq>
1918 auto operator()(OuterSeq&& outer_seq)
1921 return next_impl<OuterSeq>(std::forward<OuterSeq>(outer_seq),
1922 std::forward<InnerSeq>(inner_seq_),
1923 std::forward<OuterKeySelector>(outer_key_sel_),
1924 std::forward<InnerKeySelector>(inner_key_sel_),
1925 std::forward<ResultSelector>(result_sel_),
1926 std::forward<Pred>(pred_));
1940 template<
typename =
void>
1945 template<
typename Seq>
1946 auto impl(Seq&& seq, std::bidirectional_iterator_tag) ->
decltype(*std::begin(seq)) {
1947 auto ricur = seq.rbegin();
1948 if (ricur == seq.rend()) {
1949 throw_linq_empty_sequence();
1955 template<
typename Seq>
1956 auto impl(Seq&& seq, std::input_iterator_tag) ->
decltype(*std::begin(seq)) {
1957 auto icur = std::begin(seq);
1958 auto iend = std::end(seq);
1960 throw_linq_empty_sequence();
1962 decltype(icur) iprev;
1963 while (icur != iend) {
1971 template<
typename Seq>
1972 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
1973 return impl(std::forward<Seq>(seq),
1974 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
1989 template<
typename Pred>
1997 template<
typename Seq>
1998 auto impl(Seq&& seq, std::bidirectional_iterator_tag) ->
decltype(*std::begin(seq)) {
1999 auto ricur = seq.rbegin();
2000 auto riend = seq.rend();
2001 if (ricur == riend) {
2002 throw_linq_empty_sequence();
2004 auto rifound = std::find_if(ricur, riend, pred_);
2005 if (rifound == riend) {
2006 throw_linq_out_of_range();
2012 template<
typename Seq>
2013 auto impl(Seq&& seq, std::input_iterator_tag) ->
decltype(*std::begin(seq)) {
2014 auto icur = std::begin(seq);
2015 auto iend = std::end(seq);
2017 throw_linq_empty_sequence();
2020 while (icur != iend) {
2026 if (ifound == iend) {
2027 throw_linq_out_of_range();
2033 explicit last_impl_1(
const Pred& pred)
2036 template<
typename Seq>
2037 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
2038 return impl(std::forward<Seq>(seq),
2039 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
2053 template<
typename =
void>
2054 class last_or_default_impl_0
2058 template<
typename Seq>
2059 auto impl(Seq&& seq, std::bidirectional_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
2060 auto ricur = seq.rbegin();
2061 return ricur != seq.rend() ? *ricur
2062 :
typename seq_traits<Seq>::raw_value_type();
2066 template<
typename Seq>
2067 auto impl(Seq&& seq, std::input_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
2068 auto icur = std::begin(seq);
2069 auto iend = std::end(seq);
2071 while (icur != iend) {
2075 return iprev != iend ? *iprev
2076 :
typename seq_traits<Seq>::raw_value_type();
2080 template<
typename Seq>
2081 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
2082 return impl(std::forward<Seq>(seq),
2083 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
2098 template<
typename Pred>
2099 class last_or_default_impl_1
2106 template<
typename Seq>
2107 auto impl(Seq&& seq, std::bidirectional_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
2108 auto riend = seq.rend();
2109 auto rifound = std::find_if(seq.rbegin(), riend, pred_);
2110 return rifound != riend ? *rifound
2111 :
typename seq_traits<Seq>::raw_value_type();
2115 template<
typename Seq>
2116 auto impl(Seq&& seq, std::input_iterator_tag) ->
typename seq_traits<Seq>::raw_value_type {
2117 auto icur = std::begin(seq);
2118 auto iend = std::end(seq);
2120 while (icur != iend) {
2126 return ifound != iend ? *ifound
2127 :
typename seq_traits<Seq>::raw_value_type();
2131 explicit last_or_default_impl_1(
const Pred& pred)
2134 template<
typename Seq>
2135 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
2136 return impl(std::forward<Seq>(seq),
2137 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
2151 template<
typename =
void>
2155 template<
typename Seq>
2156 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
2157 auto iend = std::end(seq);
2158 auto imax = std::max_element(std::begin(seq), iend);
2160 throw_linq_empty_sequence();
2177 template<
typename Selector>
2181 const Selector& sel_;
2184 explicit max_impl_1(
const Selector& sel)
2187 template<
typename Seq>
2188 auto operator()(Seq&& seq) ->
typename std::decay<
decltype(sel_(*std::begin(seq)))>::type {
2189 auto icur = std::begin(seq);
2190 auto iend = std::end(seq);
2192 throw_linq_empty_sequence();
2194 auto max_val = sel_(*icur);
2195 while (++icur != iend) {
2196 max_val = std::max(max_val, sel_(*icur));
2212 template<
typename =
void>
2216 template<
typename Seq>
2217 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
2218 auto iend = std::end(seq);
2219 auto imin = std::min_element(std::begin(seq), iend);
2221 throw_linq_empty_sequence();
2238 template<
typename Selector>
2242 const Selector& sel_;
2245 explicit min_impl_1(
const Selector& sel)
2248 template<
typename Seq>
2249 auto operator()(Seq&& seq) ->
typename std::decay<
decltype(sel_(*std::begin(seq)))>::type {
2250 auto icur = std::begin(seq);
2251 auto iend = std::end(seq);
2253 throw_linq_empty_sequence();
2255 auto min_val = sel_(*icur);
2256 while (++icur != iend) {
2257 min_val = std::min(min_val, sel_(*icur));
2272 template<
typename Pred>
2279 explicit none_impl(
const Pred& pred)
2282 template<
typename Seq>
2283 auto operator()(Seq&& seq) ->
bool {
2284 return std::none_of(std::begin(seq), std::end(seq), pred_);
2311 template<
typename KeySelector,
2314 int _LessValue = Descending ? 1 : -1>
2315 class order_by_comparator
2318 KeySelector key_sel_;
2322 order_by_comparator(KeySelector&& key_sel, Pred&& pred)
2323 : key_sel_(std::forward<KeySelector>(key_sel)), pred_(std::forward<Pred>(pred)) { }
2326 order_by_comparator(
const order_by_comparator&) =
delete;
2327 order_by_comparator& operator=(
const order_by_comparator&) =
delete;
2330 template<
typename T1,
typename T2>
2331 int operator()(T1&& left, T2&& right)
const {
2332 decltype(key_sel_(left)) leftk = key_sel_(left);
2333 decltype(key_sel_(right)) rightk = key_sel_(right);
2335 if (pred_(leftk, rightk)) {
2337 }
else if (pred_(rightk, leftk)) {
2366 template<
typename Cmp1,
typename Cmp2>
2367 class dual_order_by_comparator
2370 std::unique_ptr<Cmp1> upcmp1_;
2371 std::unique_ptr<Cmp2> upcmp2_;
2374 dual_order_by_comparator(std::unique_ptr<Cmp1>&& upcmp1, std::unique_ptr<Cmp2>&& upcmp2)
2375 : upcmp1_(std::move(upcmp1)), upcmp2_(std::move(upcmp2)) { }
2378 dual_order_by_comparator(
const dual_order_by_comparator&) =
delete;
2379 dual_order_by_comparator& operator=(
const dual_order_by_comparator&) =
delete;
2382 template<
typename T1,
typename T2>
2383 int operator()(T1&& left, T2&& right)
const {
2384 int cmp = (*upcmp1_)(left, right);
2386 cmp = (*upcmp2_)(left, right);
2395 template<
typename Cmp>
class order_by_impl;
2423 template<
typename Seq,
typename Cmp>
2424 class order_by_impl_with_seq
2427 template<
typename>
friend class order_by_impl;
2431 std::unique_ptr<Cmp> upcmp_;
2433 bool init_called_ =
false;
2437 std::vector<
typename seq_traits<Seq>::pointer> ordered;
2438 try_reserve(ordered, seq_);
2439 for (
auto&& elem : seq_) {
2440 typename seq_traits<Seq>::reference robj = elem;
2441 ordered.push_back(std::addressof(robj));
2443 std::stable_sort(ordered.begin(),
2445 [
this](
typename seq_traits<Seq>::pointer pleft,
2446 typename seq_traits<Seq>::pointer pright) {
2447 return (*upcmp_)(*pleft, *pright) < 0;
2449 const std::size_t num_ordered = ordered.size();
2450 enum_ = { make_deref_next_impl(std::move(ordered)),
2451 [num_ordered]() -> std::size_t {
return num_ordered; } };
2452 init_called_ =
true;
2458 using const_iterator =
typename enumerable<
typename seq_traits<Seq>::value_type>::const_iterator;
2461 order_by_impl_with_seq(Seq&& seq, std::unique_ptr<Cmp>&& upcmp)
2462 : seq_(std::forward<Seq>(seq)), upcmp_(std::move(upcmp)) { }
2465 order_by_impl_with_seq(
const order_by_impl_with_seq&) =
delete;
2466 order_by_impl_with_seq(order_by_impl_with_seq&&) =
default;
2467 order_by_impl_with_seq& operator=(
const order_by_impl_with_seq&) =
delete;
2468 order_by_impl_with_seq& operator=(order_by_impl_with_seq&&) =
default;
2471 iterator begin()
const {
2472 if (!init_called_) {
2473 const_cast<order_by_impl_with_seq<Seq, Cmp>*>(
this)->init();
2475 return enum_.begin();
2477 iterator end()
const {
2478 if (!init_called_) {
2479 const_cast<order_by_impl_with_seq<Seq, Cmp>*>(
this)->init();
2483 iterator cbegin()
const {
2486 iterator cend()
const {
2491 bool has_fast_size()
const {
2492 if (!init_called_) {
2493 const_cast<order_by_impl_with_seq<Seq, Cmp>*>(
this)->init();
2495 return enum_.has_fast_size();
2497 std::size_t size()
const {
2498 if (!init_called_) {
2499 const_cast<order_by_impl_with_seq<Seq, Cmp>*>(
this)->init();
2501 return enum_.size();
2529 template<
typename Cmp>
2533 std::unique_ptr<Cmp> upcmp_;
2536 explicit order_by_impl(std::unique_ptr<Cmp>&& upcmp)
2537 : upcmp_(std::move(upcmp)) { }
2540 order_by_impl(
const order_by_impl&) =
delete;
2541 order_by_impl(order_by_impl&&) =
default;
2542 order_by_impl& operator=(
const order_by_impl&) =
delete;
2543 order_by_impl& operator=(order_by_impl&&) =
default;
2546 template<
typename Seq>
2547 auto operator()(Seq&& seq) -> order_by_impl_with_seq<Seq, Cmp> {
2548 return order_by_impl_with_seq<Seq, Cmp>(std::forward<Seq>(seq), std::move(upcmp_));
2552 template<
typename ImplSeq,
typename ImplCmp>
2553 auto operator()(order_by_impl_with_seq<ImplSeq, ImplCmp>&& impl)
2554 -> order_by_impl_with_seq<ImplSeq, dual_order_by_comparator<ImplCmp, Cmp>>
2556 using dual_comparator = dual_order_by_comparator<ImplCmp, Cmp>;
2557 auto new_upcmp = detail::make_unique<dual_comparator>(std::move(impl.upcmp_), std::move(upcmp_));
2558 return order_by_impl_with_seq<ImplSeq, dual_comparator>(std::forward<ImplSeq>(impl.seq_), std::move(new_upcmp));
2571 template<
typename =
void>
2576 template<
typename Seq>
2577 class next_impl_fast
2581 using reverse_iterator =
typename std::decay<
decltype(std::declval<Seq>().rbegin())>::type;
2584 struct reverse_info {
2586 reverse_iterator irend_;
2588 explicit reverse_info(Seq&& seq)
2589 : seq_(std::forward<Seq>(seq)),
2590 irend_(seq_.rend()) { }
2593 reverse_info(
const reverse_info&) =
delete;
2594 reverse_info& operator=(
const reverse_info&) =
delete;
2596 using reverse_info_sp = std::shared_ptr<reverse_info>;
2598 reverse_info_sp spinfo_;
2599 reverse_iterator ircur_;
2602 explicit next_impl_fast(Seq&& seq)
2603 : spinfo_(std::make_shared<reverse_info>(std::forward<Seq>(seq))),
2604 ircur_(spinfo_->seq_.rbegin()) { }
2606 auto operator()() ->
typename seq_traits<Seq>::pointer {
2607 typename seq_traits<Seq>::pointer pobj =
nullptr;
2608 if (ircur_ != spinfo_->irend_) {
2609 typename seq_traits<Seq>::reference robj = *ircur_;
2610 pobj = std::addressof(robj);
2618 template<
typename Seq>
2619 class next_impl_slow
2623 using pelems_v = std::vector<
typename seq_traits<Seq>::pointer>;
2624 using pelems_v_reverse_iterator =
typename pelems_v::reverse_iterator;
2627 struct reverse_info {
2630 pelems_v_reverse_iterator virend_;
2632 explicit reverse_info(Seq&& seq)
2633 : seq_(std::forward<Seq>(seq))
2636 try_reserve(vpelems_, seq_);
2637 for (
auto&& elem : seq_) {
2638 typename seq_traits<Seq>::reference robj = elem;
2639 vpelems_.push_back(std::addressof(robj));
2643 virend_ = vpelems_.rend();
2647 reverse_info(
const reverse_info&) =
delete;
2648 reverse_info& operator=(
const reverse_info&) =
delete;
2650 using reverse_info_sp = std::shared_ptr<reverse_info>;
2652 reverse_info_sp spinfo_;
2653 pelems_v_reverse_iterator vircur_;
2656 explicit next_impl_slow(Seq&& seq)
2657 : spinfo_(std::make_shared<reverse_info>(std::forward<Seq>(seq))),
2658 vircur_(spinfo_->vpelems_.rbegin()) { }
2660 auto operator()() ->
typename seq_traits<Seq>::pointer {
2661 typename seq_traits<Seq>::pointer pobj =
nullptr;
2662 if (vircur_ != spinfo_->virend_) {
2670 std::size_t size()
const {
2671 return spinfo_->vpelems_.size();
2676 template<
typename Seq>
2677 auto impl(Seq&& seq, std::bidirectional_iterator_tag)
2680 auto siz = try_get_size_delegate(seq);
2681 return enumerable<
typename seq_traits<Seq>::value_type>(next_impl_fast<Seq>(std::forward<Seq>(seq)),
2686 template<
typename Seq>
2687 auto impl(Seq&& seq, std::input_iterator_tag)
2690 next_impl_slow<Seq> next_impl(std::forward<Seq>(seq));
2691 const std::size_t size = next_impl.size();
2692 auto siz = [size]() -> std::size_t {
return size; };
2693 return enumerable<
typename seq_traits<Seq>::value_type>(std::move(next_impl),
2698 template<
typename Seq>
2699 auto operator()(Seq&& seq)
2702 return impl(std::forward<Seq>(seq),
2703 typename std::iterator_traits<
typename seq_traits<Seq>::iterator_type>::iterator_category());
2719 template<
typename Selector>
2724 template<
typename Seq,
typename CU,
typename RU>
2729 using iterator_type =
typename seq_traits<Seq>::iterator_type;
2732 using transformed_v = std::vector<RU>;
2733 using transformed_l = std::forward_list<RU>;
2734 using transformed_l_iterator =
typename transformed_l::iterator;
2737 struct select_info {
2739 iterator_type icur_;
2740 iterator_type iend_;
2742 transformed_v vtransformed_;
2743 transformed_l ltransformed_;
2744 transformed_l_iterator llast_;
2748 select_info(Seq&& seq, Selector&& sel)
2749 : seq_(std::forward<Seq>(seq)),
2750 icur_(std::begin(seq_)),
2751 iend_(std::end(seq_)),
2752 sel_(std::forward<Selector>(sel)),
2755 llast_(ltransformed_.before_begin()),
2757 use_vector_(try_reserve(vtransformed_, seq_)) { }
2760 select_info(
const select_info&) =
delete;
2761 select_info& operator=(
const select_info&) =
delete;
2763 auto get_next_in_vector(std::size_t& vncur) -> CU* {
2764 while (vtransformed_.size() <= vncur && icur_ != iend_) {
2765 vtransformed_.emplace_back(sel_(*icur_, vtransformed_.size()));
2768 return vtransformed_.size() > vncur ? std::addressof(vtransformed_[vncur++])
2772 auto get_next_in_list(transformed_l_iterator& licur) -> CU* {
2773 while (licur == llast_ && icur_ != iend_) {
2774 llast_ = ltransformed_.emplace_after(llast_, sel_(*icur_, lsize_++));
2777 return licur != llast_ ? std::addressof(*++licur)
2781 auto get_next(std::size_t& vncur, transformed_l_iterator& licur) -> CU* {
2782 return use_vector_ ? get_next_in_vector(vncur)
2783 : get_next_in_list(licur);
2786 using select_info_sp = std::shared_ptr<select_info>;
2788 select_info_sp spinfo_;
2790 transformed_l_iterator licur_;
2793 next_impl(Seq&& seq, Selector&& sel)
2794 : spinfo_(std::make_shared<select_info>(std::forward<Seq>(seq),
2795 std::forward<Selector>(sel))),
2797 licur_(spinfo_->ltransformed_.before_begin()) { }
2799 auto operator()() -> CU* {
2800 return spinfo_->get_next(vncur_, licur_);
2808 explicit select_impl(Selector&& sel)
2809 : sel_(std::forward<Selector>(sel)) { }
2811 template<
typename Seq,
2812 typename _SelectorRes =
decltype(std::declval<Selector>()(std::declval<
typename seq_traits<Seq>::reference>(), std::declval<std::size_t>())),
2815 auto operator()(Seq&& seq) ->
enumerable<_CU> {
2816 auto siz = try_get_size_delegate(seq);
2817 return enumerable<_CU>(next_impl<Seq, _CU, _RU>(std::forward<Seq>(seq), std::forward<Selector>(sel_)),
2834 template<
typename Selector>
2835 class select_many_impl
2839 template<
typename Seq,
typename CU,
typename RU>
2844 using iterator_type =
typename seq_traits<Seq>::iterator_type;
2847 using transformed_l = std::forward_list<RU>;
2848 using transformed_l_iterator =
typename transformed_l::iterator;
2851 struct select_info {
2853 iterator_type icur_;
2855 iterator_type iend_;
2857 transformed_l ltransformed_;
2858 transformed_l_iterator llast_;
2860 select_info(Seq&& seq, Selector&& sel)
2861 : seq_(std::forward<Seq>(seq)),
2862 icur_(std::begin(seq_)),
2864 iend_(std::end(seq_)),
2865 sel_(std::forward<Selector>(sel)),
2867 llast_(ltransformed_.before_begin()) { }
2870 select_info(
const select_info&) =
delete;
2871 select_info& operator=(
const select_info&) =
delete;
2873 auto get_next(transformed_l_iterator& licur) -> CU* {
2874 while (licur == llast_ && icur_ != iend_) {
2875 auto new_elements = sel_(*icur_, idx_++);
2876 llast_ = ltransformed_.insert_after(llast_, std::begin(new_elements), std::end(new_elements));
2879 return licur != llast_ ? std::addressof(*++licur)
2883 using select_info_sp = std::shared_ptr<select_info>;
2885 select_info_sp spinfo_;
2886 transformed_l_iterator licur_;
2889 next_impl(Seq&& seq, Selector&& sel)
2890 : spinfo_(std::make_shared<select_info>(std::forward<Seq>(seq),
2891 std::forward<Selector>(sel))),
2892 licur_(spinfo_->ltransformed_.before_begin()) { }
2894 auto operator()() -> CU* {
2895 return spinfo_->get_next(licur_);
2903 explicit select_many_impl(Selector&& sel)
2904 : sel_(std::forward<Selector>(sel)) { }
2906 template<
typename Seq,
2907 typename _SelectorSeqRes =
decltype(std::declval<Selector>()(std::declval<
typename seq_traits<Seq>::const_reference>(), std::declval<std::size_t>())),
2908 typename _CU =
typename seq_traits<_SelectorSeqRes>::const_value_type,
2909 typename _RU =
typename seq_traits<_SelectorSeqRes>::raw_value_type>
2910 auto operator()(Seq&& seq) ->
enumerable<_CU> {
2911 return next_impl<Seq, _CU, _RU>(std::forward<Seq>(seq), std::forward<Selector>(sel_));
2927 template<
typename Seq2>
2928 class sequence_equal_impl_1
2934 explicit sequence_equal_impl_1(
const Seq2& seq2)
2937 template<
typename Seq1>
2938 auto operator()(Seq1&& seq1) ->
bool {
2939 auto icur1 = std::begin(seq1);
2940 auto iend1 = std::end(seq1);
2941 auto icur2 = std::begin(seq2_);
2942 auto iend2 = std::end(seq2_);
2943 bool is_equal =
true;
2944 for (; is_equal && icur1 != iend1 && icur2 != iend2; ++icur1, ++icur2) {
2945 is_equal = *icur1 == *icur2;
2947 return is_equal && icur1 == iend1 && icur2 == iend2;
2964 template<
typename Seq2,
typename Pred>
2965 class sequence_equal_impl_2
2972 sequence_equal_impl_2(
const Seq2& seq2,
const Pred& pred)
2973 : seq2_(seq2), pred_(pred) { }
2975 template<
typename Seq1>
2976 auto operator()(Seq1&& seq1) ->
bool {
2977 auto icur1 = std::begin(seq1);
2978 auto iend1 = std::end(seq1);
2979 auto icur2 = std::begin(seq2_);
2980 auto iend2 = std::end(seq2_);
2981 bool is_equal =
true;
2982 for (; is_equal && icur1 != iend1 && icur2 != iend2; ++icur1, ++icur2) {
2983 is_equal = pred_(*icur1, *icur2);
2985 return is_equal && icur1 == iend1 && icur2 == iend2;
2999 template<
typename =
void>
3003 template<
typename Seq>
3004 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
3005 auto ifirst = std::begin(seq);
3006 auto iend = std::end(seq);
3007 if (ifirst == iend) {
3008 throw_linq_empty_sequence();
3010 auto inext = ifirst;
3012 if (inext != iend) {
3013 throw_linq_out_of_range();
3030 template<
typename Pred>
3037 explicit single_impl_1(
const Pred& pred)
3040 template<
typename Seq>
3041 auto operator()(Seq&& seq) ->
decltype(*std::begin(seq)) {
3042 auto ibeg = std::begin(seq);
3043 auto iend = std::end(seq);
3045 throw_linq_empty_sequence();
3047 auto ifound = std::find_if(ibeg, iend, pred_);
3048 if (ifound == iend) {
3049 throw_linq_out_of_range();
3051 auto inext = ifound;
3053 auto ifoundagain = std::find_if(inext, iend, pred_);
3054 if (ifoundagain != iend) {
3055 throw_linq_out_of_range();
3071 template<
typename =
void>
3072 class single_or_default_impl_0
3075 template<
typename Seq>
3076 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
3077 auto icur = std::begin(seq);
3078 auto iend = std::end(seq);
3082 if (inext != iend) {
3086 return icur != iend ? *icur
3087 :
typename seq_traits<Seq>::raw_value_type();
3102 template<
typename Pred>
3103 class single_or_default_impl_1
3109 explicit single_or_default_impl_1(
const Pred& pred)
3112 template<
typename Seq>
3113 auto operator()(Seq&& seq) ->
typename seq_traits<Seq>::raw_value_type {
3114 auto iend = std::end(seq);
3115 auto ifound = std::find_if(std::begin(seq), iend, pred_);
3116 if (ifound != iend) {
3117 auto inext = ifound;
3119 auto ifoundagain = std::find_if(inext, iend, pred_);
3120 if (ifoundagain != iend) {
3124 return ifound != iend ? *ifound
3125 :
typename seq_traits<Seq>::raw_value_type();
3140 template<
typename =
void>
3147 explicit skip_n_pred(std::size_t n)
3150 template<
typename T>
3151 auto operator()(T&&, std::size_t idx) ->
bool {
3170 template<
typename Pred>
3175 template<
typename Seq>
3180 using iterator_type =
typename seq_traits<Seq>::iterator_type;
3185 iterator_type iend_;
3188 skip_info(Seq&& seq, Pred&& pred)
3189 : seq_(std::forward<Seq>(seq)),
3190 iend_(std::end(seq_)),
3191 pred_(std::forward<Pred>(pred)) { }
3194 skip_info(
const skip_info&) =
delete;
3195 skip_info& operator=(
const skip_info&) =
delete;
3197 using skip_info_sp = std::shared_ptr<skip_info>;
3199 skip_info_sp spinfo_;
3200 iterator_type icur_;
3201 bool init_called_ =
false;
3204 icur_ = std::begin(spinfo_->seq_);
3206 while (icur_ != spinfo_->iend_ && spinfo_->pred_(*icur_, n++)) {
3209 init_called_ =
true;
3213 next_impl(Seq&& seq, Pred&& pred)
3214 : spinfo_(std::make_shared<skip_info>(std::forward<Seq>(seq),
3215 std::forward<Pred>(pred))) { }
3217 auto operator()() ->
typename seq_traits<Seq>::pointer {
3219 if (!init_called_) {
3222 typename seq_traits<Seq>::pointer pobj =
nullptr;
3223 if (icur_ != spinfo_->iend_) {
3224 typename seq_traits<Seq>::reference robj = *icur_;
3225 pobj = std::addressof(robj);
3237 skip_impl(Pred&& pred, std::size_t n)
3238 : pred_(std::forward<Pred>(pred)),
3241 template<
typename Seq>
3242 auto operator()(Seq&& seq)
3245 typename enumerable<
typename seq_traits<Seq>::value_type>::size_delegate siz;
3246 if (n_ !=
static_cast<std::size_t>(-1)) {
3247 auto seq_siz = try_get_size_delegate(seq);
3248 if (seq_siz !=
nullptr) {
3249 const std::size_t seq_size = seq_siz();
3250 const std::size_t size = seq_size > n_ ? seq_size - n_ : 0;
3251 siz = [size]() -> std::size_t {
return size; };
3254 return enumerable<
typename seq_traits<Seq>::value_type>(next_impl<Seq>(std::forward<Seq>(seq),
3255 std::forward<Pred>(pred_)),
3270 template<
typename F>
3277 explicit sum_impl(
const F& num_f)
3280 template<
typename Seq>
3281 auto operator()(Seq&& seq) ->
typename std::decay<
decltype(num_f_(*std::begin(seq)))>::type {
3282 auto it = std::begin(seq);
3283 auto end = std::end(seq);
3285 throw_linq_empty_sequence();
3287 auto total = num_f_(*it);
3288 for (++it; it != end; ++it) {
3289 total += num_f_(*it);
3309 template<
typename Pred>
3314 template<
typename Seq>
3319 using iterator_type =
typename seq_traits<Seq>::iterator_type;
3324 iterator_type iend_;
3327 take_info(Seq&& seq, Pred&& pred)
3328 : seq_(std::forward<Seq>(seq)),
3329 iend_(std::end(seq_)),
3330 pred_(std::forward<Pred>(pred)) { }
3333 take_info(
const take_info&) =
delete;
3334 take_info& operator=(
const take_info&) =
delete;
3336 using take_info_sp = std::shared_ptr<take_info>;
3338 take_info_sp spinfo_;
3339 iterator_type icur_;
3344 next_impl(Seq&& seq, Pred&& pred)
3345 : spinfo_(std::make_shared<take_info>(std::forward<Seq>(seq),
3346 std::forward<Pred>(pred))),
3347 icur_(std::begin(spinfo_->seq_)) { }
3349 auto operator()() ->
typename seq_traits<Seq>::pointer {
3350 typename seq_traits<Seq>::pointer pobj =
nullptr;
3352 if (icur_ != spinfo_->iend_ && spinfo_->pred_(*icur_, n_++)) {
3353 typename seq_traits<Seq>::reference robj = *icur_;
3354 pobj = std::addressof(robj);
3369 take_impl(Pred&& pred, std::size_t n)
3370 : pred_(std::forward<Pred>(pred)),
3373 template<
typename Seq>
3374 auto operator()(Seq&& seq)
3377 typename enumerable<
typename seq_traits<Seq>::value_type>::size_delegate siz;
3378 if (n_ !=
static_cast<std::size_t>(-1)) {
3379 auto seq_siz = try_get_size_delegate(seq);
3380 if (seq_siz !=
nullptr) {
3381 const std::size_t size = std::min(n_, seq_siz());
3382 siz = [size]() -> std::size_t {
return size; };
3385 return enumerable<
typename seq_traits<Seq>::value_type>(next_impl<Seq>(std::forward<Seq>(seq),
3386 std::forward<Pred>(pred_)),
3401 template<
typename Container>
3405 template<
typename Seq>
3406 auto operator()(Seq&& seq) -> Container {
3407 return Container(std::begin(std::forward<Seq>(seq)), std::end(std::forward<Seq>(seq)));
3420 template<
typename =
void>
3421 class to_vector_impl
3424 template<
typename Seq>
3425 auto operator()(Seq&& seq) -> std::vector<
typename seq_traits<Seq>::raw_value_type> {
3426 std::vector<
typename seq_traits<Seq>::raw_value_type> v;
3427 try_reserve(v, seq);
3428 v.insert(v.end(), std::begin(std::forward<Seq>(seq)), std::end(std::forward<Seq>(seq)));
3445 template<
typename Container,
typename KeySelector>
3446 class to_associative_impl_1
3449 const KeySelector& key_sel_;
3452 explicit to_associative_impl_1(
const KeySelector& key_sel)
3453 : key_sel_(key_sel) { }
3455 template<
typename Seq>
3456 auto operator()(Seq&& seq) -> Container {
3458 for (
auto&& elem : seq) {
3459 auto key = key_sel_(elem);
3460 auto emplace_res = c.emplace(key, elem);
3461 if (!emplace_res.second) {
3462 emplace_res.first->second = elem;
3482 template<
typename Container,
typename KeySelector,
typename ElementSelector>
3483 class to_associative_impl_2
3486 const KeySelector& key_sel_;
3487 const ElementSelector& elem_sel_;
3490 to_associative_impl_2(
const KeySelector& key_sel,
const ElementSelector& elem_sel)
3491 : key_sel_(key_sel), elem_sel_(elem_sel) { }
3493 template<
typename Seq>
3494 auto operator()(Seq&& seq) -> Container {
3496 for (
auto&& elem : seq) {
3497 auto key = key_sel_(elem);
3498 auto mapped = elem_sel_(elem);
3499 auto emplace_res = c.emplace(key, mapped);
3500 if (!emplace_res.second) {
3501 emplace_res.first->second = mapped;
3519 template<
typename KeySelector>
3523 const KeySelector& key_sel_;
3526 explicit to_map_impl_1(
const KeySelector& key_sel)
3527 : key_sel_(key_sel) { }
3529 template<
typename Seq>
3530 auto operator()(Seq&& seq)
3531 -> std::map<
typename std::decay<
decltype(key_sel_(*std::begin(seq)))>::type,
3534 std::map<
typename std::decay<
decltype(key_sel_(*std::begin(seq)))>::type,
3535 typename seq_traits<Seq>::raw_value_type> m;
3536 for (
auto&& elem : seq) {
3537 auto key = key_sel_(elem);
3538 auto emplace_res = m.emplace(key, elem);
3539 if (!emplace_res.second) {
3540 emplace_res.first->second = elem;
3559 template<
typename KeySelector,
typename ElementSelector>
3563 const KeySelector& key_sel_;
3564 const ElementSelector& elem_sel_;
3567 to_map_impl_2(
const KeySelector& key_sel,
const ElementSelector& elem_sel)
3568 : key_sel_(key_sel), elem_sel_(elem_sel) { }
3570 template<
typename Seq>
3571 auto operator()(Seq&& seq)
3572 -> std::map<
typename std::decay<
decltype(key_sel_(*std::begin(seq)))>::type,
3573 typename std::decay<
decltype(elem_sel_(*std::begin(seq)))>::type>
3575 std::map<
typename std::decay<
decltype(key_sel_(*std::begin(seq)))>::type,
3576 typename std::decay<
decltype(elem_sel_(*std::begin(seq)))>::type> m;
3577 for (
auto&& elem : seq) {
3578 auto key = key_sel_(elem);
3579 auto mapped = elem_sel_(elem);
3580 auto emplace_res = m.emplace(key, mapped);
3581 if (!emplace_res.second) {
3582 emplace_res.first->second = mapped;
3600 template<
typename Seq2,
typename Pred>
3605 template<
typename Seq1>
3611 using enum_type =
typename std::conditional<std::is_const<
typename seq_traits<Seq1>::value_type>::value ||
3612 std::is_const<
typename seq_traits<Seq2>::value_type>::value,
3614 typename seq_traits<Seq1>::value_type>::type;
3620 using first_iterator_type =
typename seq_traits<Seq1>::iterator_type;
3621 using second_iterator_type =
typename seq_traits<Seq2>::iterator_type;
3624 using seen_elements_set = std::set<enum_ptr_type, deref_cmp<proxy_cmp<Pred>>>;
3631 first_iterator_type iend1_;
3633 second_iterator_type iend2_;
3636 template<
typename It>
3637 auto get_next_in_seq(It& icur,
const It& iend, seen_elements_set& seen) -> enum_ptr_type {
3638 enum_ptr_type pobj =
nullptr;
3639 for (; pobj ==
nullptr && icur != iend; ++icur) {
3640 enum_ref_type robjtmp = *icur;
3641 auto pobjtmp = std::addressof(robjtmp);
3642 if (seen.emplace(pobjtmp).second) {
3651 union_info(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
3652 : seq1_(std::forward<Seq1>(seq1)),
3653 iend1_(std::end(seq1_)),
3654 seq2_(std::forward<Seq2>(seq2)),
3655 iend2_(std::end(seq2_)),
3656 pred_(std::forward<Pred>(pred)) { }
3659 union_info(
const union_info&) =
delete;
3660 union_info& operator=(
const union_info&) =
delete;
3662 first_iterator_type first_begin() {
3663 return std::begin(seq1_);
3665 second_iterator_type second_begin() {
3666 return std::begin(seq2_);
3668 seen_elements_set init_seen_elements() {
3669 return seen_elements_set(deref_cmp<proxy_cmp<Pred>>(proxy_cmp<Pred>(pred_)));
3673 auto get_next(first_iterator_type& icur1, second_iterator_type& icur2, seen_elements_set& seen) -> enum_ptr_type {
3675 enum_ptr_type pobj = get_next_in_seq(icur1, iend1_, seen);
3678 if (pobj ==
nullptr) {
3679 pobj = get_next_in_seq(icur2, iend2_, seen);
3685 using union_info_sp = std::shared_ptr<union_info>;
3687 union_info_sp spinfo_;
3688 first_iterator_type icur1_;
3689 second_iterator_type icur2_;
3690 seen_elements_set seen_;
3693 next_impl(Seq1&& seq1, Seq2&& seq2, Pred&& pred)
3694 : spinfo_(std::make_shared<union_info>(std::forward<Seq1>(seq1),
3695 std::forward<Seq2>(seq2),
3696 std::forward<Pred>(pred))),
3697 icur1_(spinfo_->first_begin()),
3698 icur2_(spinfo_->second_begin()),
3699 seen_(spinfo_->init_seen_elements()) { }
3701 auto operator()() ->
decltype(spinfo_->get_next(icur1_, icur2_, seen_)) {
3702 return spinfo_->get_next(icur1_, icur2_, seen_);
3711 explicit union_impl(Seq2&& seq2, Pred&& pred)
3712 : seq2_(std::forward<Seq2>(seq2)),
3713 pred_(std::forward<Pred>(pred)) { }
3716 union_impl(
const union_impl&) =
delete;
3717 union_impl(union_impl&&) =
default;
3718 union_impl& operator=(
const union_impl&) =
delete;
3719 union_impl& operator=(union_impl&&) =
default;
3721 template<
typename Seq1>
3722 auto operator()(Seq1&& seq1)
3723 ->
enumerable<
typename next_impl<Seq1>::enum_type>
3725 return next_impl<Seq1>(std::forward<Seq1>(seq1),
3726 std::forward<Seq2>(seq2_),
3727 std::forward<Pred>(pred_));
3743 template<
typename Pred>
3748 template<
typename Seq>
3753 using iterator_type =
typename seq_traits<Seq>::iterator_type;
3758 iterator_type iend_;
3761 where_info(Seq&& seq, Pred&& pred)
3762 : seq_(std::forward<Seq>(seq)),
3763 iend_(std::end(seq_)),
3764 pred_(std::forward<Pred>(pred)) { }
3767 where_info(
const where_info&) =
delete;
3768 where_info& operator=(
const where_info&) =
delete;
3770 using where_info_sp = std::shared_ptr<where_info>;
3772 where_info_sp spinfo_;
3773 iterator_type icur_;
3777 next_impl(Seq&& seq, Pred&& pred)
3778 : spinfo_(std::make_shared<where_info>(std::forward<Seq>(seq),
3779 std::forward<Pred>(pred))),
3780 icur_(std::begin(spinfo_->seq_)), idx_(0) { }
3782 auto operator()() ->
typename seq_traits<Seq>::pointer {
3783 typename seq_traits<Seq>::pointer pobj =
nullptr;
3784 for (; pobj ==
nullptr && icur_ != spinfo_->iend_; ++icur_, ++idx_) {
3785 typename seq_traits<Seq>::reference robjtmp = *icur_;
3786 auto pobjtmp = std::addressof(robjtmp);
3787 if (spinfo_->pred_(*pobjtmp, idx_)) {
3800 explicit where_impl(Pred&& pred)
3801 : pred_(std::forward<Pred>(pred)) { }
3804 where_impl(
const where_impl&) =
delete;
3805 where_impl(where_impl&&) =
default;
3806 where_impl& operator=(
const where_impl&) =
delete;
3807 where_impl& operator=(where_impl&&) =
default;
3809 template<
typename Seq>
3810 auto operator()(Seq&& seq)
3813 return next_impl<Seq>(std::forward<Seq>(seq), std::forward<Pred>(pred_));
3829 template<
typename Seq2,
typename ResultSelector>
3834 template<
typename Seq1,
typename CU,
typename RU>
3839 using first_iterator_type =
typename seq_traits<Seq1>::iterator_type;
3840 using second_iterator_type =
typename seq_traits<Seq2>::iterator_type;
3843 using zipped_v = std::vector<RU>;
3844 using zipped_l = std::forward_list<RU>;
3845 using zipped_l_iterator =
typename zipped_l::iterator;
3850 first_iterator_type icur1_;
3851 first_iterator_type iend1_;
3853 second_iterator_type icur2_;
3854 second_iterator_type iend2_;
3855 ResultSelector result_sel_;
3858 zipped_l_iterator llast_;
3861 zip_info(Seq1&& seq1, Seq2&& seq2, ResultSelector&& result_sel,
3862 const typename enumerable<CU>::size_delegate& siz)
3863 : seq1_(std::forward<Seq1>(seq1)),
3864 icur1_(std::begin(seq1_)),
3865 iend1_(std::end(seq1_)),
3866 seq2_(std::forward<Seq2>(seq2)),
3867 icur2_(std::begin(seq2_)),
3868 iend2_(std::end(seq2_)),
3869 result_sel_(std::forward<ResultSelector>(result_sel)),
3872 llast_(lzipped_.before_begin()),
3873 use_vector_(siz !=
nullptr)
3875 if (siz !=
nullptr) {
3876 vzipped_.reserve(siz());
3881 zip_info(
const zip_info&) =
delete;
3882 zip_info& operator=(
const zip_info&) =
delete;
3884 auto get_next_in_vector(std::size_t& vncur) -> CU* {
3885 while (vzipped_.size() <= vncur && icur1_ != iend1_ && icur2_ != iend2_) {
3886 vzipped_.emplace_back(result_sel_(*icur1_, *icur2_));
3890 return vzipped_.size() > vncur ? std::addressof(vzipped_[vncur++])
3894 auto get_next_in_list(zipped_l_iterator& licur) -> CU* {
3895 while (licur == llast_ && icur1_ != iend1_ && icur2_ != iend2_) {
3896 llast_ = lzipped_.emplace_after(llast_, result_sel_(*icur1_, *icur2_));
3900 return licur != llast_ ? std::addressof(*++licur)
3904 auto get_next(std::size_t& vncur, zipped_l_iterator& licur) -> CU* {
3905 return use_vector_ ? get_next_in_vector(vncur)
3906 : get_next_in_list(licur);
3909 using zip_info_sp = std::shared_ptr<zip_info>;
3911 zip_info_sp spinfo_;
3913 zipped_l_iterator licur_;
3916 next_impl(Seq1&& seq1, Seq2&& seq2, ResultSelector&& result_sel,
3917 const typename enumerable<CU>::size_delegate& siz)
3918 : spinfo_(std::make_shared<zip_info>(std::forward<Seq1>(seq1),
3919 std::forward<Seq2>(seq2),
3920 std::forward<ResultSelector>(result_sel),
3923 licur_(spinfo_->lzipped_.before_begin()) { }
3925 auto operator()() -> CU* {
3926 return spinfo_->get_next(vncur_, licur_);
3932 ResultSelector result_sel_;
3935 zip_impl(Seq2&& seq2, ResultSelector&& result_sel)
3936 : seq2_(std::forward<Seq2>(seq2)),
3937 result_sel_(std::forward<ResultSelector>(result_sel)) { }
3940 zip_impl(
const zip_impl&) =
delete;
3941 zip_impl(zip_impl&&) =
default;
3942 zip_impl& operator=(
const zip_impl&) =
delete;
3943 zip_impl& operator=(zip_impl&&) =
default;
3945 template<
typename Seq1,
3946 typename _SelectorRes =
decltype(std::declval<ResultSelector>()(std::declval<
typename seq_traits<Seq1>::reference>(),
3947 std::declval<
typename seq_traits<Seq2>::reference>())),
3950 auto operator()(Seq1&& seq1) ->
enumerable<_CU> {
3951 auto siz1 = try_get_size_delegate(seq1);
3952 auto siz2 = try_get_size_delegate(seq2_);
3953 typename enumerable<_CU>::size_delegate siz;
3954 if (siz1 !=
nullptr && siz2 !=
nullptr) {
3955 const std::size_t min_size = std::min(siz1(), siz2());
3956 siz = [min_size]() -> std::size_t {
return min_size; };
3958 return enumerable<_CU>(next_impl<Seq1, _CU, _RU>(std::forward<Seq1>(seq1),
3959 std::forward<Seq2>(seq2_),
3960 std::forward<ResultSelector>(result_sel_),
Traits class for a sequence.
Definition: sequence_util.h:113
Type-erased sequence wrapper.
Definition: enumerable.h:62
Traits class for elements in a sequence.
Definition: sequence_util.h:40