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#include "vector.h"
7
8
9namespace original {
27 template<typename TYPE>
29
48 template<typename TYPE, typename Callback>
50
69 template<typename TYPE, typename Callback>
71
90 template<typename TYPE, typename Callback>
92
114 template<typename T, typename U>
116
131 template<typename TYPE>
133
150 template<typename TYPE, typename Callback>
152
169 template<typename TYPE, typename Callback>
171
188 template<typename TYPE, typename Callback>
190
207 template<typename TYPE, typename Callback>
209
231 template<typename T, std::convertible_to<T> U>
233
252 template<typename T, std::convertible_to<T> U>
254
273 template<typename TYPE>
275
293 template<typename TYPE>
295
313 template<typename TYPE, typename Callback>
315
333 template<typename TYPE, typename Callback>
335
357 template<typename Callback>
358 class genPipe {
359 Callback c_;
360
361 genPipe() = default;
362
363 explicit genPipe(Callback&& c);
364
365 template<typename Generator>
366 auto operator()(Generator&& gen);
367 public:
368 template<typename TYPE, typename F>
370
371 template<typename T, typename U>
372 friend auto join(coroutine::generator<T> gen2);
373
374 template<typename T, typename U>
375 friend auto flatten();
376
377 template<typename F>
378 friend auto transforms(F&& f);
379
380 template<typename F>
381 friend auto filters(F&& f);
382
383 template<typename F>
384 friend auto extract(F&& f);
385
386 template<typename>
387 friend auto enumerate();
388
389 template<typename>
390 friend auto take(u_integer n);
391
392 template<typename>
393 friend auto skip(u_integer n);
394
395 template<typename F>
396 friend auto zipWith(coroutine::generator<F> gen2);
397
398 template<typename>
399 friend auto count();
400
401 template<typename F>
402 friend auto count(F&& f);
403
404 template<typename F>
405 friend auto all(F&& f);
406
407 template<typename F>
408 friend auto none(F&& f);
409
410 template<typename F>
411 friend auto any(F&& f);
412
413 template<typename F>
414 friend auto position(F&& f);
415
416 template<typename F>
417 friend auto find(F&& f);
418 };
419
436 template<typename TYPE, typename F>
438
453 template<typename F>
454 auto transforms(F&& f);
455
464 template<typename F>
465 auto filters(F&& f);
466
475 template<typename F>
476 auto extract(F&& f);
477
484 template<typename = void>
485 auto enumerate();
486
494 template<typename = void>
495 auto take(u_integer n);
496
504 template<typename = void>
505 auto skip(u_integer n);
506
516 template<typename T, typename U>
518
527 template<typename T, typename U>
528 auto flatten();
529
538 template<typename U>
540
547 template<typename = void>
548 auto count();
549
557 template<typename F>
558 auto count(F&& f);
559
567 template<typename F>
568 auto all(F&& f);
569
577 template<typename F>
578 auto none(F&& f);
579
587 template<typename F>
588 auto any(F&& f);
589
597 template<typename F>
598 auto position(F&& f);
599
607 template<typename F>
608 auto find(F&& f);
609
626 template<typename TYPE, typename SET = hashSet<TYPE>>
629 {
630 SET set;
631 for (auto elem : gen)
632 {
633 set.add(elem);
634 }
635 return set;
636 }
637
653 template <typename TYPE, template <typename> typename SERIAL = vector>
656 {
658 for (auto elem : gen)
659 {
660 list.pushEnd(elem);
661 }
662 return list;
663 }
664}
665
666template <typename TYPE>
668original::enumerate(coroutine::generator<TYPE> gen)
669{
670 u_integer i = 0;
671 for (auto elem : gen)
672 {
673 co_yield {i, elem};
674 i += 1;
675 }
676}
677
678template <typename TYPE, typename Callback>
680{
681 for (auto elem : gen)
682 {
683 co_yield c(std::forward<TYPE>(elem));
684 }
685}
686
687template <typename TYPE, typename Callback>
689original::filters(coroutine::generator<TYPE> gen, Callback&& c)
690{
691 for (auto elem : gen)
692 {
693 if (c(std::forward<TYPE>(elem)))
694 {
695 co_yield elem;
696 }
697 }
698}
699
700template <typename TYPE, typename Callback>
702original::extract(coroutine::generator<TYPE> gen, Callback&& c)
703{
704 for (auto elem : gen)
705 {
706 if (c(std::forward<TYPE>(elem)))
707 {
708 continue;
709 }
710 co_yield elem;
711 }
712}
713
714template <typename T, typename U>
716original::zip(coroutine::generator<T> gen1, coroutine::generator<U> gen2)
717{
718 auto elem1 = gen1.next();
719 auto elem2 = gen2.next();
720 while (elem1 && elem2)
721 {
722 co_yield {std::move(*elem1), std::move(*elem2)};
723 elem1 = std::move(gen1.next());
724 elem2 = std::move(gen2.next());
725 }
726}
727
728template <typename TYPE>
729original::u_integer original::count(coroutine::generator<TYPE> gen)
730{
731 u_integer res = 0;
732 while (auto val = gen.next())
733 {
734 res += 1;
735 }
736 return res;
737}
738
739template <typename TYPE, typename Callback>
740original::u_integer original::count(coroutine::generator<TYPE> gen, Callback&& c)
741{
742 u_integer res = 0;
743 while (auto val = gen.next())
744 {
745 if (c(std::forward<TYPE>(*val)))
746 res += 1;
747 }
748 return res;
749}
750
751template <typename TYPE, typename Callback>
753{
754 while (auto val = gen.next())
755 {
756 if (!c(std::forward<TYPE>(*val)))
757 return false;
758 }
759 return true;
760}
761
762template <typename TYPE, typename Callback>
764{
765 while (auto val = gen.next())
766 {
767 if (c(std::forward<TYPE>(*val)))
768 return false;
769 }
770 return true;
771}
772
773template <typename TYPE, typename Callback>
775{
776 while (auto val = gen.next())
777 {
778 if (c(std::forward<TYPE>(*val)))
779 return true;
780 }
781 return false;
782}
783
784template<typename T, std::convertible_to<T> U>
786original::join(coroutine::generator<T> gen1, coroutine::generator<U> gen2)
787{
788 for (auto elem : gen1)
789 {
790 co_yield elem;
791 }
792 for (auto elem : gen2)
793 {
794 co_yield static_cast<T>(elem);
795 }
796}
797
798template <typename T, std::convertible_to<T> U>
800original::flatten(coroutine::generator<couple<T, U>> gen)
801{
802 for (auto [elem1, elem2] : gen)
803 {
804 co_yield elem1;
805 co_yield static_cast<T>(elem2);
806 }
807}
808
809template <typename TYPE>
811original::take(coroutine::generator<TYPE> gen, const u_integer n)
812{
813 u_integer i = 0;
814 for (auto elem : gen)
815 {
816 if (i == n)
817 {
818 co_return;
819 }
820 i += 1;
821 co_yield elem;
822 }
823}
824
825template <typename TYPE>
827original::skip(coroutine::generator<TYPE> gen, const u_integer n)
828{
829 u_integer i = 0;
830 for (auto elem : gen)
831 {
832 if (i < n)
833 {
834 i += 1;
835 continue;
836 }
837 co_yield elem;
838 }
839}
840
841template <typename TYPE, typename Callback>
842original::u_integer original::position(coroutine::generator<TYPE> gen, Callback&& c)
843{
844 u_integer i = 0;
845 for (auto elem : gen)
846 {
847 if (c(std::forward<TYPE>(elem))){
848 return i;
849 }
850 i += 1;
851 }
852 return i;
853}
854
855template <typename TYPE, typename Callback>
857{
858 for (auto elem : gen)
859 {
860 if (c(std::forward<TYPE>(elem)))
861 {
862 return elem;
863 }
864 }
865 return TYPE{};
866}
867
868template <typename Callback>
869original::genPipe<Callback>::genPipe(Callback&& c) : c_(std::forward<Callback>(c)) {}
870
871template <typename Callback>
872template <typename Generator>
873auto original::genPipe<Callback>::operator()(Generator&& gen)
874{
875 return this->c_(std::forward<Generator>(gen));
876}
877
878template <typename TYPE, typename F>
880{
881 return p(std::move(gen));
882}
883
884template <typename F>
886{
887 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
888 return transforms(std::move(gen), std::move(c));
889 }};
890}
891
892template <typename F>
894{
895 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
896 return filters(std::move(gen), std::move(c));
897 }};
898}
899
900template <typename F>
902{
903 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
904 return extract(std::move(gen), std::move(c));
905 }};
906}
907
908template<typename>
910{
911 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
912 return enumerate(std::move(gen));
913 }};
914}
915
916template<typename>
918{
919 return genPipe{[n]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
920 return take(std::move(gen), n);
921 }};
922}
923
924template<typename>
926{
927 return genPipe{[n]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
928 return skip(std::move(gen), n);
929 }};
930}
931
932template <typename T, typename U>
934{
935 return genPipe{[gen2 = std::move(gen2)]<typename TYPE>(coroutine::generator<TYPE> gen1) mutable {
936 return join<T, TYPE>(std::move(gen1), std::move(gen2));
937 }};
938}
939
940template<typename T, typename U>
942{
943 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
944 return flatten<T, U>(std::move(gen));
945 }};
946}
947
948template<typename U>
950{
951 return genPipe{[gen2 = std::move(gen2)]<typename T>(coroutine::generator<T> gen1) mutable {
952 return zip(std::move(gen1), std::move(gen2));
953 }};
954}
955
956template<typename>
958{
959 return genPipe{[]<typename TYPE>(coroutine::generator<TYPE> gen) {
960 return count(std::move(gen));
961 }};
962}
963
964template<typename F>
966{
967 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
968 return count(std::move(gen), std::move(c));
969 }};
970}
971
972template<typename F>
974{
975 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
976 return all(std::move(gen), std::move(c));
977 }};
978}
979
980template<typename F>
982{
983 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
984 return none(std::move(gen), std::move(c));
985 }};
986}
987
988template<typename F>
990{
991 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
992 return any(std::move(gen), std::move(c));
993 }};
994}
995
996template<typename F>
998{
999 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
1000 return position(std::move(gen), std::move(c));
1001 }};
1002}
1003
1004template<typename F>
1006{
1007 return genPipe{[c = std::forward<F>(f)]<typename TYPE>(coroutine::generator<TYPE> gen) mutable {
1008 return find(std::move(gen), std::move(c));
1009 }};
1010}
1011
1012#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:358
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.
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Abstract base class for unique element containers.
Definition set.h:44
virtual bool add(const K_TYPE &e)=0
Adds a new element to the set.
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.
Main namespace for the project Original.
Definition algorithms.h:21
SET collect(coroutine::generator< TYPE > gen)
Collects generator elements into a set.
Definition generators.h:628
coroutine::generator< TYPE > skip(coroutine::generator< TYPE > gen, u_integer n)
Skips the first n elements of a generator.
SERIAL< TYPE > list(coroutine::generator< TYPE > gen)
Collects generator elements into a list container.
Definition generators.h:655
bool all(coroutine::generator< TYPE > gen, Callback &&c)
Checks if all elements satisfy a predicate.
Definition generators.h:752
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:949
TYPE find(coroutine::generator< TYPE > gen, Callback &&c)
Finds the first element satisfying a predicate.
Definition generators.h:856
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:909
bitSet< ALLOC_ > operator|(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Bitwise OR operator for two bitSets.
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:679
bool none(coroutine::generator< TYPE > gen, Callback &&c)
Checks if no elements satisfy a predicate.
Definition generators.h:763
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:957
bool any(coroutine::generator< TYPE > gen, Callback &&c)
Checks if any element satisfies a predicate.
Definition generators.h:774
auto flatten()
Creates a flatten pipe operation.
Definition generators.h:941
Standard namespace extensions for original::alternative.
Definition allocator.h:351
Implementation of set containers with different underlying data structures.
Dynamic array container with automatic resizing.