1 #pragma once 2 3 #include <limits.h> 4 5 #include <functional> 6 #include <tuple> 7 8 #include <algorithm> 9 #include <deque> 10 #include <iostream> 11 #include <iterator> 12 #include <list> 13 #include <set> 14 #include <unordered_set> 15 #include <vector> 16 17 // 18 19 namespace boolinq { 20 21 struct LinqEndException {}; 22 23 enum BytesDirection { 24 BytesFirstToLast, 25 BytesLastToFirst, 26 }; 27 28 enum BitsDirection { 29 BitsHighToLow, 30 BitsLowToHigh, 31 }; 32 33 template<typename S, typename T> 34 class Linq { 35 std::function<T(S&)> nextFunc; 36 S storage; 37 38 public: 39 typedef T value_type; 40 41 Linq() : nextFunc(), storage() 42 {} 43 44 Linq(S storage, std::function<T(S&)> nextFunc) : nextFunc(nextFunc), storage(storage) 45 {} 46 47 T next() 48 { 49 return nextFunc(storage); 50 } 51 52 void for_each_i(std::function<void(T, int)> apply) const 53 { 54 Linq<S, T> linq = *this; 55 56 try { 57 for (int i = 0; ; i++) { 58 apply(linq.next(), i); 59 } 60 } 61 catch (LinqEndException&) {} 62 } 63 64 void for_each(std::function<void(T)> apply) const 65 { 66 return for_each_i([apply](T value, int) { 67 return apply(value); 68 }); 69 } 70 71 Linq<std::tuple<Linq<S, T>, int>, T> where_i(std::function<bool(T, int)> filter) const 72 { 73 return Linq<std::tuple<Linq<S, T>, int>, T>( 74 std::make_tuple(*this, 0), 75 [filter](std::tuple<Linq<S, T>, int>& tuple) { 76 Linq<S, T>& linq = std::get<0>(tuple); 77 int& index = std::get<1>(tuple); 78 79 while (true) { 80 T ret = linq.next(); 81 if (filter(ret, index++)) { 82 return ret; 83 } 84 } 85 } 86 ); 87 } 88 89 Linq<std::tuple<Linq<S, T>, int>, T> where(std::function<bool(T)> filter) const 90 { 91 return where_i([filter](T value, int) { 92 return filter(value); 93 }); 94 } 95 96 Linq<std::tuple<Linq<S, T>, int>, T> take(int count) const 97 { 98 return where_i([count](T /*value*/, int i) { 99 if (i == count) { 100 throw LinqEndException(); 101 } 102 103 return true; 104 }); 105 } 106 107 Linq<std::tuple<Linq<S, T>, int>, T> takeWhile_i(std::function<bool(T, int)> predicate) const 108 { 109 return where_i([predicate](T value, int i) { 110 if (!predicate(value, i)) { 111 throw LinqEndException(); 112 } 113 114 return true; 115 }); 116 } 117 118 Linq<std::tuple<Linq<S, T>, int>, T> takeWhile(std::function<bool(T)> predicate) const 119 { 120 return takeWhile_i([predicate](T value, int /*i*/) { 121 return predicate(value); 122 }); 123 } 124 125 Linq<std::tuple<Linq<S, T>, int>, T> skip(int count) const 126 { 127 return where_i([count](T, int i) { 128 return i >= count; 129 }); 130 } 131 132 Linq<std::tuple<Linq<S, T>, int, bool>, T> skipWhile_i(std::function<bool(T, int)> predicate) const 133 { 134 return Linq<std::tuple<Linq<S, T>, int, bool>, T>( 135 std::make_tuple(*this, 0, false), 136 [predicate](std::tuple<Linq<S, T>, int, bool>& tuple) { 137 Linq<S, T>& linq = std::get<0>(tuple); 138 int& index = std::get<1>(tuple); 139 bool& flag = std::get<2>(tuple); 140 141 if (flag) { 142 return linq.next(); 143 } 144 145 while (true) { 146 T ret = linq.next(); 147 if (!predicate(ret, index++)) { 148 flag = true; 149 return ret; 150 } 151 } 152 } 153 ); 154 } 155 156 Linq<std::tuple<Linq<S, T>, int, bool>, T> skipWhile(std::function<bool(T)> predicate) const 157 { 158 return skipWhile_i([predicate](T value, int /*i*/) { 159 return predicate(value); 160 }); 161 } 162 163 template<typename ... Types> 164 Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T> append(Types ... newValues) const 165 { 166 return Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T>( 167 std::make_tuple(*this, std::vector<T>{ newValues ... }, -1), 168 [](std::tuple<Linq<S, T>, std::vector<T>, int>& tuple) { 169 Linq<S, T>& linq = std::get<0>(tuple); 170 std::vector<T>& values = std::get<1>(tuple); 171 int& index = std::get<2>(tuple); 172 173 if (index == -1) { 174 try { 175 return linq.next(); 176 } 177 catch (LinqEndException&) { 178 index = 0; 179 } 180 } 181 182 if (index < values.size()) { 183 return values[index++]; 184 } 185 186 throw LinqEndException(); 187 } 188 ); 189 } 190 191 template<typename ... Types> 192 Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T> prepend(Types ... newValues) const 193 { 194 return Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T>( 195 std::make_tuple(*this, std::vector<T>{ newValues ... }, 0), 196 [](std::tuple<Linq<S, T>, std::vector<T>, int>& tuple) { 197 Linq<S, T>& linq = std::get<0>(tuple); 198 std::vector<T>& values = std::get<1>(tuple); 199 int& index = std::get<2>(tuple); 200 201 if (index < values.size()) { 202 return values[index++]; 203 } 204 205 return linq.next(); 206 } 207 ); 208 } 209 210 template<typename F, typename _TRet = typename std::result_of<F(T, int)>::type> 211 Linq<std::tuple<Linq<S, T>, int>, _TRet> select_i(F apply) const 212 { 213 return Linq<std::tuple<Linq<S, T>, int>, _TRet>( 214 std::make_tuple(*this, 0), 215 [apply](std::tuple<Linq<S, T>, int>& tuple) { 216 Linq<S, T>& linq = std::get<0>(tuple); 217 int& index = std::get<1>(tuple); 218 219 return apply(linq.next(), index++); 220 } 221 ); 222 } 223 224 template<typename F, typename _TRet = typename std::result_of<F(T)>::type> 225 Linq<std::tuple<Linq<S, T>, int>, _TRet> select(F apply) const 226 { 227 return select_i([apply](T value, int /*index*/) { 228 return apply(value); 229 }); 230 } 231 232 template<typename TRet> 233 Linq<std::tuple<Linq<S, T>, int>, TRet> cast() const 234 { 235 return select_i([](T value, int /*i*/) { 236 return TRet(value); 237 }); 238 } 239 240 template<typename S2, typename T2> 241 Linq<std::tuple<Linq<S, T>, Linq<S2, T2>, bool>, T> concat(const Linq<S2, T2>& rhs) const 242 { 243 return Linq<std::tuple<Linq<S, T>, Linq<S2, T2>, bool>, T>( 244 std::make_tuple(*this, rhs, false), 245 [](std::tuple<Linq<S, T>, Linq<S2, T2>, bool>& tuple) { 246 Linq<S, T>& first = std::get<0>(tuple); 247 Linq<S2, T2>& second = std::get<1>(tuple); 248 bool& flag = std::get<2>(tuple); 249 250 if (!flag) { 251 try { 252 return first.next(); 253 } 254 catch (LinqEndException&) {} 255 } 256 257 return second.next(); 258 } 259 ); 260 } 261 262 template< 263 typename F, 264 typename _TRet = typename std::result_of<F(T, int)>::type, 265 typename _TRetVal = typename _TRet::value_type 266 > 267 Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const 268 { 269 return Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal>( 270 std::make_tuple(*this, _TRet(), 0, true), 271 [apply](std::tuple<Linq<S, T>, _TRet, int, bool>& tuple) { 272 Linq<S, T>& linq = std::get<0>(tuple); 273 _TRet& current = std::get<1>(tuple); 274 int& index = std::get<2>(tuple); 275 bool& finished = std::get<3>(tuple); 276 277 while (true) { 278 if (finished) { 279 current = apply(linq.next(), index++); 280 finished = false; 281 } 282 283 try { 284 return current.next(); 285 } 286 catch (LinqEndException&) { 287 finished = true; 288 } 289 } 290 } 291 ); 292 } 293 294 template< 295 typename F, 296 typename _TRet = typename std::result_of<F(T)>::type, 297 typename _TRetVal = typename _TRet::value_type 298 > 299 Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal> selectMany(F apply) const 300 { 301 return selectMany_i([apply](T value, int) { 302 return apply(value); 303 }); 304 } 305 306 template< 307 typename F, 308 typename _TKey = typename std::result_of<F(T)>::type, 309 typename _TValue = Linq<std::tuple<Linq<S, T>, int>, T> // where(predicate) 310 > 311 Linq<std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey>>, std::pair<_TKey, _TValue>> groupBy(F apply) const 312 { 313 return Linq<std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey>>, std::pair<_TKey, _TValue>>( 314 std::make_tuple(*this, *this, std::unordered_set<_TKey>()), 315 [apply](std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey>>& tuple) { 316 Linq<S, T>& linq = std::get<0>(tuple); 317 Linq<S, T>& linqCopy = std::get<1>(tuple); 318 std::unordered_set<_TKey>& set = std::get<2>(tuple); 319 320 while (true) { 321 _TKey key = apply(linq.next()); 322 if (set.insert(key).second) { 323 return std::make_pair(key, linqCopy.where([apply, key](T v) { 324 return apply(v) == key; 325 })); 326 } 327 } 328 } 329 ); 330 } 331 332 template<typename F, typename _TRet = typename std::result_of<F(T)>::type> 333 Linq<std::tuple<Linq<S, T>, std::unordered_set<_TRet>>, T> distinct(F transform) const 334 { 335 return Linq<std::tuple<Linq<S, T>, std::unordered_set<_TRet>>, T>( 336 std::make_tuple(*this, std::unordered_set<_TRet>()), 337 [transform](std::tuple<Linq<S, T>, std::unordered_set<_TRet>>& tuple) { 338 Linq<S, T>& linq = std::get<0>(tuple); 339 std::unordered_set<_TRet>& set = std::get<1>(tuple); 340 341 while (true) { 342 T value = linq.next(); 343 if (set.insert(transform(value)).second) { 344 return value; 345 } 346 } 347 } 348 ); 349 } 350 351 Linq<std::tuple<Linq<S, T>, std::unordered_set<T>>, T> distinct() const 352 { 353 return distinct([](T value) { 354 return value; 355 }); 356 } 357 358 template<typename F, typename _TIter = typename std::vector<T>::const_iterator> 359 Linq<std::tuple<std::vector<T>, _TIter, bool>, T> orderBy(F transform) const 360 { 361 std::vector<T> items = toStdVector(); 362 363 std::sort(items.begin(), items.end(), [transform](const T& a, const T& b) { 364 return transform(a) < transform(b); 365 }); 366 367 return Linq<std::tuple<std::vector<T>, _TIter, bool>, T>( 368 std::make_tuple(items, _TIter(), false), 369 [](std::tuple<std::vector<T>, _TIter, bool>& tuple) { 370 std::vector<T>& vec = std::get<0>(tuple); 371 _TIter& it = std::get<1>(tuple); 372 bool& flag = std::get<2>(tuple); 373 374 if (!flag) { 375 flag = true; 376 it = vec.cbegin(); 377 } 378 379 if (it == vec.cend()) { 380 throw LinqEndException(); 381 } 382 383 return *(it++); 384 } 385 ); 386 } 387 388 Linq<std::tuple<std::vector<T>, typename std::vector<T>::const_iterator, bool>, T> orderBy() const 389 { 390 return orderBy([](T value) { 391 return value; 392 }); 393 } 394 395 template<typename _TIter = typename std::list<T>::const_reverse_iterator> 396 Linq<std::tuple<std::list<T>, _TIter, bool>, T> reverse() const 397 { 398 return Linq<std::tuple<std::list<T>, _TIter, bool>, T>( 399 std::make_tuple(toStdList(), _TIter(), false), 400 [](std::tuple<std::list<T>, _TIter, bool>& tuple) { 401 std::list<T>& list = std::get<0>(tuple); 402 _TIter& it = std::get<1>(tuple); 403 bool& flag = std::get<2>(tuple); 404 405 if (!flag) { 406 flag = true; 407 it = list.crbegin(); 408 } 409 410 if (it == list.crend()) { 411 throw LinqEndException(); 412 } 413 414 return *(it++); 415 } 416 ); 417 } 418 419 // Aggregators 420 421 template<typename TRet> 422 TRet aggregate(TRet start, std::function<TRet(TRet, T)> accumulate) const 423 { 424 Linq<S, T> linq = *this; 425 426 try { 427 while (true) { 428 start = accumulate(start, linq.next()); 429 } 430 } 431 catch (LinqEndException&) {} 432 433 return start; 434 } 435 436 template<typename F, typename _TRet = typename std::result_of<F(T)>::type> 437 _TRet sum(F transform) const 438 { 439 return aggregate<_TRet>(_TRet(), [transform](_TRet accumulator, T value) { 440 return accumulator + transform(value); 441 }); 442 } 443 444 template<typename TRet = T> 445 TRet sum() const 446 { 447 return sum([](T value) { 448 return TRet(value); 449 }); 450 } 451 452 template<typename F, typename _TRet = typename std::result_of<F(T)>::type> 453 _TRet avg(F transform) const 454 { 455 int count = 0; 456 _TRet res = sum([transform, &count](T value) { 457 count++; 458 return transform(value); 459 }); 460 461 return res / count; 462 } 463 464 template<typename TRet = T> 465 TRet avg() const 466 { 467 return avg([](T value) { 468 return TRet(value); 469 }); 470 } 471 472 int count() const 473 { 474 int index = 0; 475 476 for_each([&index](T /*a*/) { 477 index++; 478 }); 479 return index; 480 } 481 482 int count(std::function<bool(T)> predicate) const 483 { 484 return where(predicate).count(); 485 } 486 487 int count(const T& item) const 488 { 489 return count([item](T value) { 490 return item == value; 491 }); 492 } 493 494 // Bool aggregators 495 496 bool any(std::function<bool(T)> predicate) const 497 { 498 Linq<S, T> linq = *this; 499 500 try { 501 while (true) { 502 if (predicate(linq.next())) 503 return true; 504 } 505 } 506 catch (LinqEndException&) {} 507 508 return false; 509 } 510 511 bool any() const 512 { 513 return any([](T value) { 514 return static_cast<bool>(value); 515 }); 516 } 517 518 bool all(std::function<bool(T)> predicate) const 519 { 520 return !any([predicate](T value) { 521 return !predicate(value); 522 }); 523 } 524 525 bool all() const 526 { 527 return all([](T value) { 528 return static_cast<bool>(value); 529 }); 530 } 531 532 bool contains(const T& item) const 533 { 534 return any([&item](T value) { 535 return value == item; 536 }); 537 } 538 539 // Election aggregators 540 541 T elect(std::function<T(T, T)> accumulate) const 542 { 543 T result; 544 545 for_each_i([accumulate, &result](T value, int i) { 546 if (i == 0) { 547 result = value; 548 } 549 else { 550 result = accumulate(result, value); 551 } 552 }); 553 return result; 554 } 555 556 template<typename F> 557 T max(F transform) const 558 { 559 return elect([transform](const T& a, const T& b) { 560 return (transform(a) < transform(b)) ? b : a; 561 }); 562 } 563 564 T max() const 565 { 566 return max([](T value) { 567 return value; 568 }); 569 } 570 571 template<typename F> 572 T min(F transform) const 573 { 574 return elect([transform](const T& a, const T& b) { 575 return (transform(a) < transform(b)) ? a : b; 576 }); 577 } 578 579 T min() const 580 { 581 return min([](T value) { 582 return value; 583 }); 584 } 585 586 // Single object returners 587 588 T elementAt(int index) const 589 { 590 return skip(index).next(); 591 } 592 593 T first(std::function<bool(T)> predicate) const 594 { 595 return where(predicate).next(); 596 } 597 598 T first() const 599 { 600 return Linq<S, T>(*this).next(); 601 } 602 603 T firstOrDefault(std::function<bool(T)> predicate, T const& defaultValue = T()) const 604 { 605 try { 606 return where(predicate).next(); 607 } 608 catch (LinqEndException&) {} 609 610 return defaultValue; 611 } 612 613 T firstOrDefault(T const& defaultValue = T()) const 614 { 615 try { 616 return Linq<S, T>(*this).next(); 617 } 618 catch (LinqEndException&) {} 619 620 return defaultValue; 621 } 622 623 T last(std::function<bool(T)> predicate) const 624 { 625 T res; 626 int index = -1; 627 628 where(predicate).for_each_i([&res, &index](T value, int i) { 629 res = value; 630 index = i; 631 }); 632 633 if (index == -1) { 634 throw LinqEndException(); 635 } 636 637 return res; 638 } 639 640 T last() const 641 { 642 return last([](T /*value*/) { 643 return true; 644 }); 645 } 646 647 T lastOrDefault(std::function<bool(T)> predicate, T const& defaultValue = T()) const 648 { 649 T res = defaultValue; 650 651 where(predicate).for_each([&res](T value) { 652 res = value; 653 }); 654 return res; 655 } 656 657 T lastOrDefault(T const& defaultValue = T()) const 658 { 659 return lastOrDefault([](T /*value*/) { 660 return true; 661 }, defaultValue); 662 } 663 664 // Export to containers 665 666 std::vector<T> toStdVector() const 667 { 668 std::vector<T> items; 669 670 for_each([&items](T value) { 671 items.push_back(value); 672 }); 673 return items; 674 } 675 676 std::list<T> toStdList() const 677 { 678 std::list<T> items; 679 680 for_each([&items](T value) { 681 items.push_back(value); 682 }); 683 return items; 684 } 685 686 std::deque<T> toStdDeque() const 687 { 688 std::deque<T> items; 689 690 for_each([&items](T value) { 691 items.push_back(value); 692 }); 693 return items; 694 } 695 696 std::set<T> toStdSet() const 697 { 698 std::set<T> items; 699 700 for_each([&items](T value) { 701 items.insert(value); 702 }); 703 return items; 704 } 705 706 std::unordered_set<T> toStdUnorderedSet() const 707 { 708 std::unordered_set<T> items; 709 710 for_each([&items](T value) { 711 items.insert(value); 712 }); 713 return items; 714 } 715 716 // Bits and bytes 717 718 Linq<std::tuple<Linq<S, T>, BytesDirection, T, int>, int> bytes(BytesDirection direction = BytesFirstToLast) const 719 { 720 return Linq<std::tuple<Linq<S, T>, BytesDirection, T, int>, int>( 721 std::make_tuple(*this, direction, T(), sizeof(T)), 722 [](std::tuple<Linq<S, T>, BytesDirection, T, int>& tuple) { 723 Linq<S, T>& linq = std::get<0>(tuple); 724 BytesDirection& bytesDirection = std::get<1>(tuple); 725 T& value = std::get<2>(tuple); 726 int& index = std::get<3>(tuple); 727 728 if (index == sizeof(T)) { 729 value = linq.next(); 730 index = 0; 731 } 732 733 unsigned char* ptr = reinterpret_cast<unsigned char*>(&value); 734 735 int byteIndex = index; 736 if (bytesDirection == BytesLastToFirst) { 737 byteIndex = sizeof(T) - 1 - byteIndex; 738 } 739 740 index++; 741 return ptr[byteIndex]; 742 } 743 ); 744 } 745 746 template<typename TRet> 747 Linq<std::tuple<Linq<S, T>, BytesDirection, int>, TRet> unbytes(BytesDirection direction = BytesFirstToLast) const 748 { 749 return Linq<std::tuple<Linq<S, T>, BytesDirection, int>, TRet>( 750 std::make_tuple(*this, direction, 0), 751 [](std::tuple<Linq<S, T>, BytesDirection, int>& tuple) { 752 Linq<S, T>& linq = std::get<0>(tuple); 753 BytesDirection& bytesDirection = std::get<1>(tuple); 754 755 /*int& index =*/ std::get<2>(tuple); 756 757 TRet value; 758 unsigned char* ptr = reinterpret_cast<unsigned char*>(&value); 759 760 for (int i = 0; i < sizeof(TRet); i++) { 761 int byteIndex = i; 762 if (bytesDirection == BytesLastToFirst) { 763 byteIndex = sizeof(TRet) - 1 - byteIndex; 764 } 765 766 ptr[byteIndex] = linq.next(); 767 } 768 769 return value; 770 } 771 ); 772 } 773 774 Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int>, int> bits(BitsDirection bitsDir = BitsHighToLow, 775 BytesDirection bytesDir = BytesFirstToLast) const 776 { 777 return Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int>, int>( 778 std::make_tuple(*this, bytesDir, bitsDir, T(), sizeof(T) * CHAR_BIT), 779 [](std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int>& tuple) { 780 Linq<S, T>& linq = std::get<0>(tuple); 781 BytesDirection& bytesDirection = std::get<1>(tuple); 782 BitsDirection& bitsDirection = std::get<2>(tuple); 783 T& value = std::get<3>(tuple); 784 int& index = std::get<4>(tuple); 785 786 if (index == sizeof(T) * CHAR_BIT) { 787 value = linq.next(); 788 index = 0; 789 } 790 791 unsigned char* ptr = reinterpret_cast<unsigned char*>(&value); 792 793 int byteIndex = index / CHAR_BIT; 794 if (bytesDirection == BytesLastToFirst) { 795 byteIndex = sizeof(T) - 1 - byteIndex; 796 } 797 798 int bitIndex = index % CHAR_BIT; 799 if (bitsDirection == BitsHighToLow) { 800 bitIndex = CHAR_BIT - 1 - bitIndex; 801 } 802 803 index++; 804 return (ptr[byteIndex] >> bitIndex) & 1; 805 } 806 ); 807 } 808 809 template<typename TRet = unsigned char> 810 Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int>, TRet> unbits(BitsDirection bitsDir = BitsHighToLow, 811 BytesDirection bytesDir = BytesFirstToLast) const 812 { 813 return Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int>, TRet>( 814 std::make_tuple(*this, bytesDir, bitsDir, 0), 815 [](std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int>& tuple) { 816 Linq<S, T>& linq = std::get<0>(tuple); 817 BytesDirection& bytesDirection = std::get<1>(tuple); 818 BitsDirection& bitsDirection = std::get<2>(tuple); 819 820 /*int& index =*/ std::get<3>(tuple); 821 822 TRet value = TRet(); 823 unsigned char* ptr = reinterpret_cast<unsigned char*>(&value); 824 825 for (int i = 0; i < sizeof(TRet) * CHAR_BIT; i++) { 826 int byteIndex = i / CHAR_BIT; 827 if (bytesDirection == BytesLastToFirst) { 828 byteIndex = sizeof(TRet) - 1 - byteIndex; 829 } 830 831 int bitIndex = i % CHAR_BIT; 832 if (bitsDirection == BitsHighToLow) { 833 bitIndex = CHAR_BIT - 1 - bitIndex; 834 } 835 836 ptr[byteIndex] &= ~(1 << bitIndex); 837 ptr[byteIndex] |= bool(linq.next()) << bitIndex; 838 } 839 840 return value; 841 } 842 ); 843 } 844 845 }; 846 847 template<typename S, typename T> 848 std::ostream& operator<<(std::ostream& stream, Linq<S, T> linq) 849 { 850 try { 851 while (true) { 852 stream << linq.next() << ' '; 853 } 854 } 855 catch (LinqEndException&) {} 856 857 return stream; 858 } 859 860 //////////////////////////////////////////////////////////////// 861 // Linq Creators 862 //////////////////////////////////////////////////////////////// 863 864 template<typename T> 865 Linq<std::pair<T, T>, typename std::iterator_traits<T>::value_type> from(const T& begin, const T& end) 866 { 867 return Linq<std::pair<T, T>, typename std::iterator_traits<T>::value_type>( 868 std::make_pair(begin, end), 869 [](std::pair<T, T>& pair) { 870 if (pair.first == pair.second) { 871 throw LinqEndException(); 872 } 873 874 return *(pair.first++); 875 } 876 ); 877 } 878 879 template<typename T> 880 Linq<std::pair<T, T>, typename std::iterator_traits<T>::value_type> from(const T& it, int n) 881 { 882 return from(it, it + n); 883 } 884 885 template<typename T, int N> 886 Linq<std::pair<const T*, const T*>, T> from(T (& array)[N]) 887 { 888 return from((const T*)(&array), (const T*)(&array) + N); 889 } 890 891 template<template<class> class TV, typename TT> 892 auto from(const TV<TT>& container) 893 -> decltype(from(container.cbegin(), container.cend())) 894 { 895 return from(container.cbegin(), container.cend()); 896 } 897 898 // std::list, std::vector, std::dequeue 899 template<template<class, class> class TV, typename TT, typename TU> 900 auto from(const TV<TT, TU>& container) 901 -> decltype(from(container.cbegin(), container.cend())) 902 { 903 return from(container.cbegin(), container.cend()); 904 } 905 906 // std::set 907 template<template<class, class, class> class TV, typename TT, typename TS, typename TU> 908 auto from(const TV<TT, TS, TU>& container) 909 -> decltype(from(container.cbegin(), container.cend())) 910 { 911 return from(container.cbegin(), container.cend()); 912 } 913 914 // std::map 915 template<template<class, class, class, class> class TV, typename TK, typename TT, typename TS, typename TU> 916 auto from(const TV<TK, TT, TS, TU>& container) 917 -> decltype(from(container.cbegin(), container.cend())) 918 { 919 return from(container.cbegin(), container.cend()); 920 } 921 922 // std::array 923 template<template<class, size_t> class TV, typename TT, size_t TL> 924 auto from(const TV<TT, TL>& container) 925 -> decltype(from(container.cbegin(), container.cend())) 926 { 927 return from(container.cbegin(), container.cend()); 928 } 929 930 template<typename T> 931 Linq<std::pair<T, int>, T> repeat(const T& value, int count) { 932 return Linq<std::pair<T, int>, T>( 933 std::make_pair(value, count), 934 [](std::pair<T, int>& pair) { 935 if (pair.second > 0) { 936 pair.second--; 937 return pair.first; 938 } 939 940 throw LinqEndException(); 941 } 942 ); 943 } 944 945 template<typename T> 946 Linq<std::tuple<T, T, T>, T> range(const T& start, const T& end, const T& step) { 947 return Linq<std::tuple<T, T, T>, T>( 948 std::make_tuple(start, end, step), 949 [](std::tuple<T, T, T>& tuple) { 950 T& start = std::get<0>(tuple); 951 T& end = std::get<1>(tuple); 952 T& step = std::get<2>(tuple); 953 954 T value = start; 955 if (value < end) { 956 start += step; 957 return value; 958 } 959 960 throw LinqEndException(); 961 } 962 ); 963 } 964 965 } 966