ORIGINAL
Loading...
Searching...
No Matches
generators.h
1#ifndef ORIGINAL_GENERATORS_H
2#define ORIGINAL_GENERATORS_H
3#include "coroutines.h"
4#include "couple.h"
5#include "sets.h"
6
7
8namespace original {
26 template<typename TYPE>
28
45 template<typename TYPE, typename SET = hashSet<TYPE>>
48
64 template<typename TYPE, template <typename> typename SERIAL = vector>
67
86 template<typename TYPE, typename Callback>
88
107 template<typename TYPE, typename Callback>
109
128 template<typename TYPE, typename Callback>
130
152 template<typename T, typename U>
154
169 template<typename TYPE>
171
188 template<typename TYPE, typename Callback>
190
207 template<typename TYPE, typename Callback>
209
226 template<typename TYPE, typename Callback>
228
245 template<typename TYPE, typename Callback>
247
269 template<typename T, std::convertible_to<T> U>
271
290 template<typename T, std::convertible_to<T> U>
292
311 template<typename TYPE>
313
331 template<typename TYPE>
333
351 template<typename TYPE, typename Callback>
353
371 template<typename TYPE, typename Callback>
373
395 template<typename Callback>
396 class genPipe {
397 Callback c_;
398
399 genPipe() = default;
400
401 explicit genPipe(Callback&& c);
402
403 template<typename Generator>
404 auto operator()(Generator&& gen);
405 public:
406 template<typename TYPE, typename F>
408
409 template<typename T, typename U>
410 friend auto join(coroutine::generator<T> gen2);
411
412 template<typename T, typename U>
413 friend auto flatten();
414
415 template<typename F>
416 friend auto transforms(F&& f);
417
418 template<typename F>
419 friend auto filters(F&& f);
420
421 template<typename F>
422 friend auto extract(F&& f);
423
424 template<typename>
425 friend auto enumerate();
426
427 template<typename>
428 friend auto take(u_integer n);
429
430 template<typename>
431 friend auto skip(u_integer n);
432
433 template<typename F>
434 friend auto zipWith(coroutine::generator<F> gen2);
435
436 template<typename>
437 friend auto count();
438
439 template<typename F>
440 friend auto count(F&& f);
441
442 template<typename F>
443 friend auto all(F&& f);
444
445 template<typename F>
446 friend auto none(F&& f);
447
448 template<typename F>
449 friend auto any(F&& f);
450
451 template<typename F>
452 friend auto position(F&& f);
453
454 template<typename F>
455 friend auto find(F&& f);
456 };
457
474 template<typename TYPE, typename F>
476
491 template<typename F>
492 auto transforms(F&& f);
493
502 template<typename F>
503 auto filters(F&& f);
504
513 template<typename F>
514 auto extract(F&& f);
515
522 template<typename = void>
523 auto enumerate();
524
532 template<typename = void>
533 auto take(u_integer n);
534
542 template<typename = void>
543 auto skip(u_integer n);
544
554 template<typename T, typename U>
556
565 template<typename T, typename U>
566 auto flatten();
567
576 template<typename U>
578
585 template<typename = void>
586 auto count();
587
595 template<typename F>
596 auto count(F&& f);
597
605 template<typename F>
606 auto all(F&& f);
607
615 template<typename F>
616 auto none(F&& f);
617
625 template<typename F>
626 auto any(F&& f);
627
635 template<typename F>
636 auto position(F&& f);
637
645 template<typename F>
646 auto find(F&& f);
647}
648
649template <typename TYPE>
651original::enumerate(coroutine::generator<TYPE> gen)
652{
653 u_integer i = 0;
654 for (auto elem : gen)
655 {
656 co_yield {i, elem};
657 i += 1;
658 }
659}
660
661template<typename TYPE, typename SET>
663SET original::collect(coroutine::generator<TYPE> gen)
664{
665 SET set;
666 for (auto elem : gen)
667 {
668 set.add(elem);
669 }
670 return set;
671}
672
673template <typename TYPE, template <typename> class SERIAL>
675SERIAL<TYPE> original::list(coroutine::generator<TYPE> gen)
676{
677 SERIAL<TYPE> list;
678 for (auto elem : gen)
679 {
680 list.pushEnd(elem);
681 }
682 return list;
683}
684
685template <typename TYPE, typename Callback>
687{
688 for (auto elem : gen)
689 {
690 co_yield c(std::forward<TYPE>(elem));
691 }
692}
693
694template <typename TYPE, typename Callback>
696original::filters(coroutine::generator<TYPE> gen, Callback&& c)
697{
698 for (auto elem : gen)
699 {
700 if (c(std::forward<TYPE>(elem)))
701 {
702 co_yield elem;
703 }
704 }
705}
706
707template <typename TYPE, typename Callback>
709original::extract(coroutine::generator<TYPE> gen, Callback&& c)
710{
711 for (auto elem : gen)
712 {
713 if (c(std::forward<TYPE>(elem)))
714 {
715 continue;
716 }
717 co_yield elem;
718 }
719}
720
721template <typename T, typename U>
723original::zip(coroutine::generator<T> gen1, coroutine::generator<U> gen2)
724{
725 auto elem1 = gen1.next();
726 auto elem2 = gen2.next();
727 while (elem1 && elem2)
728 {
729 co_yield {std::move(*elem1), std::move(*elem2)};
730 elem1 = std::move(gen1.next());
731 elem2 = std::move(gen2.next());
732 }
733}
734
735template <typename TYPE>
736original::u_integer original::count(coroutine::generator<TYPE> gen)
737{
738 u_integer res = 0;
739 while (auto val = gen.next())
740 {
741 res += 1;
742 }
743 return res;
744}
745
746template <typename TYPE, typename Callback>
747original::u_integer original::count(coroutine::generator<TYPE> gen, Callback&& c)
748{
749 u_integer res = 0;
750 while (auto val = gen.next())
751 {
752 if (c(std::forward<TYPE>(*val)))
753 res += 1;
754 }
755 return res;
756}
757
758template <typename TYPE, typename Callback>
760{
761 while (auto val = gen.next())
762 {
763 if (!c(std::forward<TYPE>(*val)))
764 return false;
765 }
766 return true;
767}
768
769template <typename TYPE, typename Callback>
771{
772 while (auto val = gen.next())
773 {
774 if (c(std::forward<TYPE>(*val)))
775 return false;
776 }
777 return true;
778}
779
780template <typename TYPE, typename Callback>
782{
783 while (auto val = gen.next())
784 {
785 if (c(std::forward<TYPE>(*val)))
786 return true;
787 }
788 return false;
789}
790
791template<typename T, std::convertible_to<T> U>
793original::join(coroutine::generator<T> gen1, coroutine::generator<U> gen2)
794{
795 for (auto elem : gen1)
796 {
797 co_yield elem;
798 }
799 for (auto elem : gen2)
800 {
801 co_yield static_cast<T>(elem);
802 }
803}
804
805template <typename T, std::convertible_to<T> U>
807original::flatten(coroutine::generator<couple<T, U>> gen)
808{
809 for (auto [elem1, elem2] : gen)
810 {
811 co_yield elem1;
812 co_yield static_cast<T>(elem2);
813 }
814}
815
816template <typename TYPE>
818original::take(coroutine::generator<TYPE> gen, const u_integer n)
819{
820 u_integer i = 0;
821 for (auto elem : gen)
822 {
823 if (i == n)
824 {
825 co_return;
826 }
827 i += 1;
828 co_yield elem;
829 }
830}
831
832template <typename TYPE>
834original::skip(coroutine::generator<TYPE> gen, const u_integer n)
835{
836 u_integer i = 0;
837 for (auto elem : gen)
838 {
839 if (i < n)
840 {
841 i += 1;
842 continue;
843 }
844 co_yield elem;
845 }
846}
847
848template <typename TYPE, typename Callback>
849original::u_integer original::position(coroutine::generator<TYPE> gen, Callback&& c)
850{
851 u_integer i = 0;
852 for (auto elem : gen)
853 {
854 if (c(std::forward<TYPE>(elem))){
855 return i;
856 }
857 i += 1;
858 }
859 return i;
860}
861
862template <typename TYPE, typename Callback>
864{
865 for (auto elem : gen)
866 {
867 if (c(std::forward<TYPE>(elem)))
868 {
869 return elem;
870 }
871 }
872 return TYPE{};
873}
874
875template <typename Callback>
876original::genPipe<Callback>::genPipe(Callback&& c) : c_(std::forward<Callback>(c)) {}
877
878template <typename Callback>
879template <typename Generator>
880auto original::genPipe<Callback>::operator()(Generator&& gen)
881{
882 return this->c_(std::forward<Generator>(gen));
883}
884
885template <typename TYPE, typename F>
887{
888 return p(std::move(gen));
889}
890
891template <typename F>
893{
894 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
895 return transforms(std::move(gen), std::move(c));
896 }};
897}
898
899template <typename F>
901{
902 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
903 return filters(std::move(gen), std::move(c));
904 }};
905}
906
907template <typename F>
909{
910 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
911 return extract(std::move(gen), std::move(c));
912 }};
913}
914
915template<typename>
917{
918 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
919 return enumerate(std::move(gen));
920 }};
921}
922
923template<typename>
925{
926 return genPipe{[n]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
927 return take(std::move(gen), n);
928 }};
929}
930
931template<typename>
933{
934 return genPipe{[n]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
935 return skip(std::move(gen), n);
936 }};
937}
938
939template <typename T, typename U>
941{
942 return genPipe{[gen2 = std::move(gen2)]<typename TYPE>(coroutine::generator<TYPE> gen1) mutable {
943 return join<T, TYPE>(std::move(gen1), std::move(gen2));
944 }};
945}
946
947template<typename T, typename U>
949{
950 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
951 return flatten<T, U>(std::move(gen));
952 }};
953}
954
955template<typename U>
957{
958 return genPipe{[gen2 = std::move(gen2)]<typename T>(coroutine::generator<T> gen1) mutable {
959 return zip(std::move(gen1), std::move(gen2));
960 }};
961}
962
963template<typename>
965{
966 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) {
967 return count(std::move(gen));
968 }};
969}
970
971template<typename F>
973{
974 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
975 return count(std::move(gen), std::move(c));
976 }};
977}
978
979template<typename F>
981{
982 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
983 return all(std::move(gen), std::move(c));
984 }};
985}
986
987template<typename F>
989{
990 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
991 return none(std::move(gen), std::move(c));
992 }};
993}
994
995template<typename F>
997{
998 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
999 return any(std::move(gen), std::move(c));
1000 }};
1001}
1002
1003template<typename F>
1005{
1006 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
1007 return position(std::move(gen), std::move(c));
1008 }};
1009}
1010
1011template<typename F>
1013{
1014 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
1015 return find(std::move(gen), std::move(c));
1016 }};
1017}
1018
1019#endif //ORIGINAL_GENERATORS_H
Lazy sequence generator using C++20 coroutines.
Definition coroutines.h:57
alternative< TYPE > next()
Advances generator and gets next value.
Definition coroutines.h:408
Pipe adapter for generator operations to enable fluent chaining.
Definition generators.h:396
friend auto enumerate()
Creates an enumerate pipe operation.
friend auto skip(u_integer n)
Creates a skip pipe operation.
friend auto all(F &&f)
Creates an all-match pipe operation.
friend auto take(u_integer n)
Creates a take pipe operation.
friend auto any(F &&f)
Creates an any-match pipe operation.
friend auto none(F &&f)
Creates a none-match pipe operation.
friend auto flatten()
Creates a flatten pipe operation.
friend auto filters(F &&f)
Creates a filter pipe operation.
friend auto find(F &&f)
Creates an element-finding pipe operation.
friend auto position(F &&f)
Creates a position-finding pipe operation.
friend auto count()
Creates a count pipe operation.
friend auto count(F &&f)
Creates a conditional count pipe operation.
friend auto operator|(coroutine::generator< TYPE > gen, genPipe< F > p)
Pipe operator for generator operations.
friend auto extract(F &&f)
Creates an extract pipe operation.
friend auto transforms(F &&f)
Creates a transform pipe operation.
A placeholder type representing the absence of a value.
Definition types.h:33
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Dynamic array container with amortized constant time operations.
Definition vector.h:43
Checks derivation or type identity using std::derived_from.
Definition types.h:472
C++20 coroutine support with generator pattern implementation.
Generic pair container implementation.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:263
Main namespace for the project Original.
Definition algorithms.h:21
coroutine::generator< TYPE > skip(coroutine::generator< TYPE > gen, u_integer n)
Skips the first n elements of a generator.
bool all(coroutine::generator< TYPE > gen, Callback &&c)
Checks if all elements satisfy a predicate.
Definition generators.h:759
coroutine::generator< TYPE > take(coroutine::generator< TYPE > gen, u_integer n)
Takes the first n elements from a generator.
auto zipWith(coroutine::generator< U > gen2)
Creates a zipWith pipe operation.
Definition generators.h:956
TYPE find(coroutine::generator< TYPE > gen, Callback &&c)
Finds the first element satisfying a predicate.
Definition generators.h:863
coroutine::generator< T > join(coroutine::generator< T > gen1, coroutine::generator< U > gen2)
Joins two generators of compatible types.
coroutine::generator< TYPE > filters(coroutine::generator< TYPE > gen, Callback &&c)
Filters generator elements based on a predicate.
coroutine::generator< TYPE > extract(coroutine::generator< TYPE > gen, Callback &&c)
Extracts elements that do not satisfy a predicate.
u_integer position(coroutine::generator< TYPE > gen, Callback &&c)
Finds the position of the first element satisfying a predicate.
auto enumerate()
Creates an enumerate pipe operation.
Definition generators.h:916
bitSet< ALLOC_ > operator|(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Bitwise OR operator for two bitSets.
SET collect(coroutine::generator< TYPE > gen)
Collects generator elements into a set.
auto transforms(coroutine::generator< TYPE > gen, Callback &&c) -> coroutine::generator< std::invoke_result_t< Callback, TYPE > >
Transforms generator elements using a callable.
Definition generators.h:686
coroutine::generator< couple< T, U > > zip(coroutine::generator< T > gen1, coroutine::generator< U > gen2)
Zips two generators into pairs.
auto count()
Creates a count pipe operation.
Definition generators.h:964
bool any(coroutine::generator< TYPE > gen, Callback &&c)
Checks if any element satisfies a predicate.
Definition generators.h:781
auto flatten()
Creates a flatten pipe operation.
Definition generators.h:948
SERIAL< TYPE > list(coroutine::generator< TYPE > gen)
Collects generator elements into a list container.
Standard namespace extensions for original::alternative.
Definition allocator.h:351
Implementation of set containers with different underlying data structures.