From b200c23ac30a7f953548cb164c0893f3fe7f36cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20=C5=81ab=C4=99dziewski?= Date: Mon, 29 Dec 2025 12:35:11 +0100 Subject: [PATCH 1/4] Update test_fv.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * funkcja 'test_infinite_zip'= łączy dwa nieskończone źródła (liczby po kolei i liczby losowe). --- tests/test_fv.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/test_fv.cpp b/tests/test_fv.cpp index b36241e..f7c0f5f 100644 --- a/tests/test_fv.cpp +++ b/tests/test_fv.cpp @@ -598,6 +598,31 @@ void test_free_stream() { } +void test_infinite_zip() { + // Generuje 0 - nieskończoność + auto infinite_ints = iota_stream(0); + + // Generuje liczby losowe (nieskończoność) + auto infinite_randoms = crandom_stream(); + + // Łączymy dwa nieskończone strumienie + // Bierzemy tylko 10 pierwszych par => bylaby pętla nieskończona + auto zipped = infinite_ints.zip(infinite_randoms).take(10); + + VALUE(zipped.size()) EXPECTED(10); + + // Sprawdzamy czy pierwszy element pary to kolejne liczby całkowite + VALUE(zipped.element_at(0).value().first) EXPECTED(0); + VALUE(zipped.element_at(5).value().first) EXPECTED(5); + VALUE(zipped.element_at(9).value().first) EXPECTED(9); + + // Czy da się iterować? + std::cout << "Infinite Zip Output: "; + zipped.foreach(S(std::cout << "[" << _.first << ":" << _.second << "] ")); + std::cout << "\n"; +} + + int main() { const int failed = + SUITE(test_type_presentation) @@ -627,8 +652,9 @@ int main() { + SUITE(test_array_view) + SUITE(test_string) + SUITE(test_underscore_macros) - + SUITE(test_free_stream); + + SUITE(test_free_stream) + + SUITE(test_infinite_zip); std::cout << (failed == 0 ? "ALL OK" : "FAILURE") << std::endl; return failed; -} \ No newline at end of file +} From 68c257183174cacd95c51878b3553a40ec536b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20=C5=81ab=C4=99dziewski?= Date: Thu, 22 Jan 2026 12:03:54 +0100 Subject: [PATCH 2/4] Add test for DirectView with unknown container size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dodaniu testu, czy DirectView (który jest kontenerem skończonym) poprawnie współpracuje z funkcją zaprojektowaną dla kontenerów o nieznanym rozmiarze --- tests/test_fv.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/test_fv.cpp b/tests/test_fv.cpp index f7c0f5f..c900c4d 100644 --- a/tests/test_fv.cpp +++ b/tests/test_fv.cpp @@ -597,7 +597,6 @@ void test_free_stream() { } - void test_infinite_zip() { // Generuje 0 - nieskończoność auto infinite_ints = iota_stream(0); @@ -622,6 +621,27 @@ void test_infinite_zip() { std::cout << "\n"; } +void test_direct_view_as_unknown() { + // Symulacja funkcji "wybranej", która może przyjmować kontenery o nieznanym rozmiarze + // używa take() aby wymusić skończoność przetwarzania + auto process_infinite_source = [](const auto& container) { + return container.map(F(_ * 2)).take(3).sum(); + }; + + std::vector data = {1, 2, 3, 4, 5, 6}; + + // DirectView jako źródło danych + auto dv = DirectView(data); + + // Sprawdzenie czy DirectView jest poprawnie obsługiwany jako kontener o nieznanym rozmiarze + // Oczekiwany wynik: (1*2) + (2*2) + (3*2) = 12 + VALUE(process_infinite_source(dv)) EXPECTED(12); + + // Wyciągnięcie operacji z lambdą przed makro VALUE + size_t count_result = dv.count(F(_ > 0)); + VALUE(count_result) EXPECTED(6); +} + int main() { const int failed = @@ -653,7 +673,8 @@ int main() { + SUITE(test_string) + SUITE(test_underscore_macros) + SUITE(test_free_stream) - + SUITE(test_infinite_zip); + + SUITE(test_infinite_zip) + + SUITE(test_direct_view_as_unknown); std::cout << (failed == 0 ? "ALL OK" : "FAILURE") << std::endl; return failed; From 43ba09427aaaf650ee81e5f2de43c338c5dfb5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20=C5=81ab=C4=99dziewski?= Date: Thu, 22 Jan 2026 12:06:44 +0100 Subject: [PATCH 3/4] Update test_fv.cpp --- tests/test_fv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_fv.cpp b/tests/test_fv.cpp index c900c4d..83ff432 100644 --- a/tests/test_fv.cpp +++ b/tests/test_fv.cpp @@ -622,7 +622,7 @@ void test_infinite_zip() { } void test_direct_view_as_unknown() { - // Symulacja funkcji "wybranej", która może przyjmować kontenery o nieznanym rozmiarze + // Symulacja funkcji, która może przyjmować kontenery o nieznanym rozmiarze // używa take() aby wymusić skończoność przetwarzania auto process_infinite_source = [](const auto& container) { return container.map(F(_ * 2)).take(3).sum(); From 1ae7688e067146a677f005976c5474a2296447b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20=C5=81ab=C4=99dziewski?= Date: Thu, 22 Jan 2026 12:09:07 +0100 Subject: [PATCH 4/4] Delete tests/test_fv.cpp --- tests/test_fv.cpp | 681 ---------------------------------------------- 1 file changed, 681 deletions(-) delete mode 100644 tests/test_fv.cpp diff --git a/tests/test_fv.cpp b/tests/test_fv.cpp deleted file mode 100644 index 83ff432..0000000 --- a/tests/test_fv.cpp +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright 2022, Tomasz Bold -// https://github.com/tboldagh/FunRootAna -// Distributed under the MIT License -// (See accompanying file LICENSE file) - -#include "Testing.h" -#include "LazyFunctionalVector.h" - -#include - -using namespace lfv; -void test_type_presentation() { - std::vector t1({ 1,19,4 }); - auto vt1 = lazy_view(t1); - decltype(vt1)::value_type x; - VALUE(typeid(x) == typeid(int)) EXPECTED(true); - VALUE(typeid(x) == typeid(float)) EXPECTED(false); - auto ft1 = vt1.filter(F(_ > 0)); - decltype(ft1)::value_type y; - VALUE(typeid(y) == typeid(int)) EXPECTED(true); - auto mt1 = vt1.map(F(_ + 2)); - decltype(mt1)::value_type z1; - VALUE(typeid(z1) == typeid(int)) EXPECTED(true); - - auto mt2 = vt1.map(F(_ * 0.1)); - decltype(mt2)::value_type z2; - VALUE(typeid(z2) == typeid(double)) EXPECTED(true); - - static_assert(details::has_fast_element_access_tag::value == false); - static_assert(details::has_fast_element_access_tag>>::value == true); -} - -void test_element_access() { - std::vector t1({ 1,19,4 }); - auto vt1 = lazy_view(t1); - VALUE( vt1.element_at(0).value()) EXPECTED(1); - VALUE( vt1.element_at(2).value()) EXPECTED(4); - VALUE( vt1.element_at(3).has_value()) EXPECTED(false); -} - -void test_count_and_find() { - std::vector t1({ 1,19,4 }); - auto vt1 = lazy_view(t1); - VALUE(vt1.size()) EXPECTED(3); - const size_t count_below_5 = vt1.count(F(_ < 5)); - VALUE(count_below_5) EXPECTED(2); - const size_t count_below_50 = vt1.count(F(_ < 50)); - VALUE(count_below_50) EXPECTED(3); - const size_t count_never = vt1.count(F(false)); - VALUE(count_never) EXPECTED(0); - - VALUE(vt1.empty()) EXPECTED(false); - - VALUE(vt1.contains(2)) EXPECTED(false); - VALUE(vt1.contains(4)) EXPECTED(true); - const bool contains_mod_3 = vt1.contains(F(_ % 3 == 0)); - VALUE(contains_mod_3) EXPECTED(false); - const bool contains_mod_2 = vt1.contains(F(_ % 2 == 0)); - VALUE(contains_mod_2) EXPECTED(true); - const auto first_above_10 = vt1.first_of(F(_ > 10)); - VALUE(first_above_10.value()) EXPECTED(19); - const auto contains_above_100 = vt1.first_of(F(_ > 100)); - VALUE(contains_above_100.has_value()) EXPECTED(false); - - const bool gt_10 = vt1.all(F(_ > 10)); - VALUE(gt_10) EXPECTED(false); - const bool gt_0 = vt1.all(F(_ > 0)); - VALUE(gt_0) EXPECTED(true); - - - -} - -void test_filter() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto ft1 = vt1.filter(F(_ > 2)); - VALUE(ft1.size()) EXPECTED(4); - auto ft2 = ft1.filter(F(_ >= 5)); - VALUE(ft2.size()) EXPECTED(3); - std::vector r; - ft2.push_back_to(r); - VALUE(int(r.at(0))) EXPECTED(19); - size_t count_of_5 = ft2.count(F(_ == 5)); - VALUE(count_of_5) EXPECTED(2); - - VALUE(ft1.empty()) EXPECTED(false); - auto ft3 = ft2.filter(F(false)); // impossible filter - VALUE(ft3.size()) EXPECTED(0); - VALUE(ft3.empty()) EXPECTED(true); -} - -void test_map() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - { - auto mt1 = vt1.map(F(_ + 2)); - std::vector r; - mt1.push_back_to(r); - VALUE(int(r[0])) EXPECTED(3); - VALUE(int(r[1])) EXPECTED(21); - } - { - auto mt1 = vt1.map(F(_ * 0.2)); - std::vector r; - mt1.push_back_to(r); - VALUE(double(r[0])) EXPECTED(0.2); - VALUE(double(r[2])) EXPECTED(0.8); - } - - // VALUE( mt1.element_at(0)) EXPECTED ( 33 ); -} - -void test_filter_map() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - { - auto mt1 = vt1.map(F(_ + 2)).filter(F(_ > 4)); - VALUE(mt1.size()) EXPECTED(4); - - std::vector r; - mt1.push_back_to(r); - VALUE(int(r[0])) EXPECTED(21); - VALUE(int(r[1])) EXPECTED(6); - } - // filter after type change - { - auto mt1 = vt1.map(F(_ * 0.2)).filter(F(_ >= 1.0)); - VALUE(mt1.size()) EXPECTED(3); - std::vector r; - mt1.push_back_to(r); - VALUE(double(r[0])) EXPECTED(3.8); - VALUE(double(r[1])) EXPECTED(1.0); - } - // filter and then map - { - auto mt1 = vt1.filter(F(_ >= 2)).map(F(_ * 0.2)); - VALUE(mt1.size()) EXPECTED(5); - std::vector r; - mt1.push_back_to(r); - VALUE(double(r[0])) EXPECTED(3.8); - VALUE(double(r[1])) EXPECTED(0.8); - VALUE(double(r[2])) EXPECTED(0.4); - } -} - -void test_staging() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto plainVec = vt1.map(F(_ + 2)).filter(F(_ < 4)).filter(F(_ == 1)).map(F(_ * _ * 0.1)).stage(); - auto mt1 = lazy_view(plainVec); - // one element (initially -1) should survive - VALUE(mt1.size()) EXPECTED(1); - VALUE(mt1.element_at(0).value()) EXPECTED(0.1); - int a = 1, b = 8, c = 7; - std::vector< const int *> v = {&a, &b, &c}; - auto s = lazy_view(v); - auto ssum = s.map( F(*_)).sum(); - VALUE( ssum ) EXPECTED (16); - auto ssum2 = s.toref().sum(); - VALUE( ssum2 ) EXPECTED ( 16 ); - - auto sv = s.element_at(1).value(); - VALUE( *sv ) EXPECTED ( 8 ); - sv = s.sort( F(*_)).element_at(1).value(); - VALUE( *sv ) EXPECTED ( 7 ); - sv = s.sort( F(*_)).reverse().element_at(0).value(); - VALUE( *sv ) EXPECTED ( 8 ); - - - -} - - -void test_take() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto tt1 = vt1.take(3); - VALUE(tt1.size()) EXPECTED(3); - VALUE(tt1.element_at(0).value()) EXPECTED(1); - VALUE(tt1.element_at(2).value()) EXPECTED(4); - // take element with stride - auto tt1s = vt1.take(lfv::all_elements, 2); - VALUE(tt1s.size()) EXPECTED(4); - VALUE(tt1s.element_at(1).value()) EXPECTED(4); - VALUE(tt1s.element_at(3).value()) EXPECTED(5); - - - auto tt2 = vt1.take_while(F(_ > 0)); - VALUE(tt2.size()) EXPECTED(5); - VALUE(tt2.element_at(4).value()) EXPECTED(5); - - auto tt3 = vt1.skip(3); - VALUE(tt3.size()) EXPECTED(4); - VALUE(tt3.element_at(0).value()) EXPECTED(2); - - auto tt4 = vt1.skip_while(F(_ > 0)); - VALUE(tt4.size()) EXPECTED(2); - VALUE(tt4.element_at(0).value()) EXPECTED(-1); - - // combine - auto tt5 = vt1.take(5).skip(3); - VALUE(tt5.size()) EXPECTED(2); - VALUE(tt5.element_at(0).value()) EXPECTED(2); - VALUE(tt5.element_at(1).value()) EXPECTED(5); - - auto tt6 = vt1.take_while(F(_ != 5)).skip_while(F(_ != 4)); - VALUE(tt6.size()) EXPECTED(2); - VALUE(tt6.element_at(0).value()) EXPECTED(4); - VALUE(tt6.element_at(1).value()) EXPECTED(2); -} - - -void test_sum_and_accumulate() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto s = vt1.sum(); - VALUE( s ) EXPECTED(35); - auto s3 = vt1.take(3).sum(F(_)); - VALUE(s3) EXPECTED(24); - const int multiply_el = vt1.take(4).skip(2).accumulate([](int t, int el) {return t * el;}, 1); - VALUE(multiply_el) EXPECTED(8); -} - -void test_chain() { - std::vector t1({ 1,19,4, 2 }); - std::vector t2({ 5, -1, 3 }); - auto vt1 = lazy_view(t1); - auto vt2 = lazy_view(t2); - auto jt = vt1.chain(vt2); - VALUE(jt.size()) EXPECTED(7); - std::vector byhand({1,19,4, 2, 5, -1, 3}); - auto vb = lazy_view(byhand); - VALUE( vb.is_same(jt)) EXPECTED(true); - - auto ajt = vt1.skip(1).chain(vt2.filter(F(_ < 0))); - VALUE(ajt.size()) EXPECTED(4); - VALUE(ajt.element_at(0).value()) EXPECTED(19); - VALUE(ajt.element_at(3).value()) EXPECTED(-1); - - auto r = jt.reverse(); - VALUE(r.element_at(0).value()) EXPECTED(3); - - -} - - -void test_sort() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto st1 = vt1.sort(); // default use values themselves - VALUE(st1.size()) EXPECTED(t1.size()); - VALUE(st1.element_at(0).value()) EXPECTED(-1); - VALUE(st1.element_at(1).value()) EXPECTED(1); - VALUE(st1.element_at(6).value()) EXPECTED(19); - - auto rst1 = vt1.sort(F(-std::abs(_))); // reverse sort - VALUE(rst1.size()) EXPECTED(t1.size()); - VALUE(rst1.element_at(0).value()) EXPECTED(19); - - -} - -void test_enumerate() { - // test first the indexed struct helper - - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto en1 = vt1.enumerate(); - std::cout << "..... "; - en1.foreach(S(std::cout << _.first << ":" << _.second << " ")); - std::cout << "\n"; - - VALUE(en1.element_at(0).value().first) EXPECTED(0); - VALUE(en1.element_at(0).value().second) EXPECTED(1); - VALUE(en1.element_at(1).value().first) EXPECTED(1); - VALUE(en1.element_at(1).value().second) EXPECTED(19); - - auto index_greater_than_value = en1.first_of(F(static_cast(_.first) > _.second)); - VALUE(index_greater_than_value.value().first) EXPECTED(3); - VALUE(index_greater_than_value.value().second) EXPECTED(2); - - // this is failing as expected - // auto sen1 = en1.take(20).sort(F(_.second)).stage(); - // auto plainVec = en1.take(20).stage(); - // auto sen1 = lazy_view(plainVec).sort(F(_.second)); // it should be staged again - // // TODO figure out why staging was needed after sort - // VALUE(sen1.element_at(0).value().second) EXPECTED(-1); - // VALUE(sen1.element_at(0).value().first) EXPECTED(5); -} - -void test_reversal() { - std::vector t1({ 1,19,4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - auto r1 = vt1.reverse(); - VALUE( r1.size() ) EXPECTED( 7); - VALUE(r1.element_at(0).value()) EXPECTED(5); - VALUE(r1.element_at(1).value()) EXPECTED(-1); - - auto back = r1.reverse(); - VALUE( back.size() ) EXPECTED( vt1.size() ); - VALUE( back.is_same(vt1) ) EXPECTED(true); - - auto last_3 = r1.reverse().take(3).reverse(); - VALUE(last_3.size()) EXPECTED(3); - VALUE(last_3.element_at(0).value()) EXPECTED(4); - VALUE(last_3.element_at(1).value()) EXPECTED(19); - VALUE(last_3.element_at(2).value()) EXPECTED(1); - - - - auto s1 = r1.sort(); - VALUE(s1.element_at(0).value()) EXPECTED(-1); - - // double reversescala - auto r2 = r1.reverse(); - VALUE(r2.element_at(1).value()) EXPECTED(19); - - // TODO try sorting - auto s2 = r2.sort(); - VALUE(s2.element_at(0).value()) EXPECTED(-1); -} - -void test_min_max() { - std::vector t1({ 1, 19, 4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - - - auto max1 = vt1.max(F(_)); - VALUE(max1.contains(19)) EXPECTED(true); - - auto min1 = vt1.min(); - VALUE(min1.contains(-1)) EXPECTED(true); - - VALUE(vt1.take(5).skip(2).size()) EXPECTED(3); - VALUE(vt1.take(5).skip(2).size()) EXPECTED(3); - VALUE(vt1.take(5).skip(2).empty()) EXPECTED(false); - - auto min2 = vt1.take(5).skip(2).min(); - VALUE(min2.size()) EXPECTED (1); - vt1.take(5).skip(2).foreach(S(std::cout << _ << " ")); - VALUE(min2.element_at(0).value()) EXPECTED(2); - -} - -void test_zip() { - std::vector t1({ 1, 19, 4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - - std::vector t2({ 0, -1, -2, -3, -4 }); - auto vt2 = lazy_view(t2).reverse(); - auto z = vt1.zip(vt2); - std::cout << "..... "; - z.foreach(S(std::cout << _.first << ":" << _.second << ", ")); - std::cout << "\n"; - - VALUE(z.size()) EXPECTED(std::min(t1.size(), t2.size())); - VALUE(z.element_at(0).value().first) EXPECTED(1); - VALUE(z.element_at(0).value().second) EXPECTED(-4); - - const bool same = vt1.is_same(vt1); - const bool diff = vt1.is_same(vt2); - VALUE(same) EXPECTED(true); - VALUE(diff) EXPECTED(false); -} -void test_redirect() { -#ifdef TEST_LAZY - std::vector t1({ 1, 19 }); - std::vector t2({-1, 5 }); - auto v = DirectView(t1); - VALUE(v.sum()) EXPECTED(20); - v.update_container(t2); - VALUE(v.sum()) EXPECTED(4); -#endif -} -void test_series() { -#ifdef TEST_LAZY - auto s1 = geometric_stream(2.5, 2); - auto s1_5 = s1.take(5); - VALUE(s1_5.size()) EXPECTED(5); - auto s1_10 = s1.take(10); - VALUE(s1_10.size()) EXPECTED(10); - - VALUE(s1_5.element_at(0).value()) EXPECTED(2.5); - VALUE(s1_5.element_at(1).value()) EXPECTED(5.0); - auto staged = s1_10.stage(); - VALUE(s1_5.is_same(lazy_view(staged))) EXPECTED(true); // we compare only first 5 elements - - auto s2 = arithmetic_stream(2, 3); - VALUE(s2.element_at(0).value()) EXPECTED(2); - VALUE(s2.element_at(1).value()) EXPECTED(5); - VALUE(s2.element_at(2).value()) EXPECTED(8); -#endif - auto ra = range_stream(6, 12); - ra.foreach(PRINT); - auto inv = range_stream(6., 0., -1.5); - inv.foreach(PRINT); - - ra.zip(inv).foreach(PRINT); - - VALUE(ra.size()) EXPECTED(6); - VALUE(ra.element_at(0).value()) EXPECTED(6); - VALUE(ra.element_at(5).value()) EXPECTED(11); - VALUE(ra.element_at(6).has_value()) EXPECTED(false); - - auto rd = range_stream(0.1, 0.2, 0.01); - VALUE(rd.size()) EXPECTED(10); - // randoms - auto r = crandom_stream(); - std::cout << "..... "; - r.map(F(double(_) / RAND_MAX)).take_while(F(_ < 0.9)).foreach(S(std::cout << _ << " ")); - // std::cout << "\n"; - - // calculate pi for fun - const size_t npoints = 10000; - auto points = crandom_stream().map(F(double(_) / RAND_MAX)).group(2).take(npoints); - size_t points_in = points.map(F(_.map(F(_ * _)).sum())).filter(F(_ < 1.0)).size(); - std::cout << "..... pi " << 4.0 * static_cast(points_in) / npoints; -} - - -void test_cartesian() { - auto x = range_stream(2, 6); - auto y = range_stream(-3, 0); - - auto z = x.cartesian(y); - VALUE(z.size()) EXPECTED(12); - z.foreach(S(std::cout << _.first << ":" << _.second << ", ")); - auto permanent = z.map(F(std::make_pair(_.first, _.second))); - // TODO fix an issue with element access and stage ( issue is in use of pair<&,&> which is evaporative) - VALUE(permanent.element_at(0).value().first) EXPECTED(2); - VALUE(permanent.element_at(0).value().second) EXPECTED(-3); - -} - -void test_group() { - auto x = range_stream(0, 4); - const size_t s2 = x.group(2).size(); - VALUE(s2) EXPECTED(2); - const size_t s2_by_1 = x.group(2, 1).size(); - VALUE(s2_by_1) EXPECTED(3); - x.group(2, 1).foreach(S(std::cout << _.element_at(0).value() << ":" << _.element_at(1).value() << " ")); - x.group(2).map( F(_.sum())); -} - -void test_stat() { - std::vector t1({ 1, 19, 4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - - auto s = vt1.stat(); - VALUE(s.sum) EXPECTED( vt1.sum() ); - VALUE(s.count) EXPECTED( vt1.size() ); - VALUE(s.mean()) EXPECTED( static_cast( vt1.sum())/vt1.size() ); - double var = vt1.map( CLOSURE(_-s.mean())).map( F(_*_) ).sum()/vt1.size(); // calculate it by hand - VALUE(s.var()) EXPECTED( var); -} - -void test_to_ref_ptr() { - std::vector t1({ 1, 19, 4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - const int sum1 = vt1.sum(); - const int sum2 = vt1.toptr().sum( F(*_)); - VALUE( sum1 ) EXPECTED( sum2 ); - - const int sum3 = vt1.toptr().toref().sum( F(_)); - VALUE( sum1 ) EXPECTED( sum3 ); - -} - -// a tricky container -template -struct MyVec{ - using value_type = T*; - std::vector data; - ~MyVec(){ for ( auto el: data) delete el; } - auto begin() const { return data.begin(); } - auto end() const { return data.end(); } - size_t size() const { return data.size(); } - const T* at(size_t i) const { return data[i]; } - -}; - - - - -void test_one_element_container() { - auto one = one_own(7.15); - - auto filtered_ok = one.filter(F(_>3)); - VALUE(filtered_ok.size()) EXPECTED(1); - VALUE(filtered_ok.get().value()) EXPECTED( 7.15); - auto filtered_toempty = one.filter(F(_<3)); - VALUE(filtered_toempty.size()) EXPECTED(0); -} - -void test_match() { - // test how finding best element between two containers would work (also when no match is found) - // auto ints = lazy_own({1,4,5,6}); - // auto floats = lazy_own({1.5,3.9,5.12}); - // auto distance = [&floats](int i) { - // // returns value it i is closer to ant of the floats than 0.2 - // return floats.filter( CLOSURE( std::abs(_-i) < 0.2) ).min( CLOSURE( std::abs(_-i)) ).get(); - // }; - // VALUE(distance(1).has_value()) EXPECTED(false); - // TODO - this needs fixing - strange memory issues here -// // r.size(); -// auto close_pairs = ints.map( CLOSURE( std::make_pair(_,distance(_))) ); -// VALUE( close_pairs.size() ) EXPECTED( 4 ); -// VALUE( close_pairs.element_at(0).value().first ) EXPECTED(1); -// VALUE( close_pairs.element_at(1).value().first ) EXPECTED(4); -// VALUE( close_pairs.element_at(0).value().second.size() ) EXPECTED(0); -// VALUE( close_pairs.element_at(1).value().second.size() ) EXPECTED(0); - - // auto only_with_matches = close_pairs.filter( F(not _.second.empty()) ); // can filter missing - // VALUE( only_with_matches.element_at(0).value().first ) EXPECTED( 4 ); - // VALUE( only_with_matches.element_at(1).value().first ) EXPECTED( 5 ); - -// auto defaulted_matches = close_pairs.map( F( std::make_pair( _.first, _.second.get().value_or(-1)) ) ).stage(); - -} - -void test_ptr_view() { - std::vector v; - - v.push_back( new int(1)); - v.push_back( new int(7)); - v.push_back( new int(-3)); - auto lv = lazy_view(v); - VALUE( *(lv.get().value()) ) EXPECTED( 1 ); - const int s = lv.map(F(*_)).sum(); - VALUE(s) EXPECTED(5); - const int s1 = lv.filter(F(*_ > 0)).map(F(*_)).sum(); - VALUE(s1) EXPECTED(8); - const int s2 = lv.toref().filter(F(_>0)).sum(); - VALUE(s2) EXPECTED(s1); - - std::vector vc; - vc.push_back(new int(5)); - vc.push_back(new int(9)); - vc.push_back(new int(15)); - auto lvc = lazy_view(vc); - const int cs = lvc.filter( F(*_ > 6) ).toref().sum(); - VALUE( cs ) EXPECTED( 24 ); - const auto fc = lvc.filter(F(*_ >10)).get(); - VALUE( *fc.value() ) EXPECTED( 15 ); - auto min = lv.min( F(*_) ).get().value(); - VALUE(min) EXPECTED(v.data()[2]); - auto absmin = lv.min( F(std::abs(*_)) ).get().value(); - VALUE(absmin) EXPECTED(v.data()[0]); - -} - -void test_array_view() { -#ifdef TEST_LAZY - int data[5] = {1,7,8,2,-1}; - auto array_view = lazy_view(data, sizeof(data)/sizeof(int)); - VALUE( array_view.sum() ) EXPECTED ( 17 ); - VALUE( array_view.take(3).sum() ) EXPECTED ( 16 ); - - auto byptr_view = lazy_view( data, data+4); - VALUE( byptr_view.sum() ) EXPECTED (18); - VALUE( byptr_view.skip(3).max().get().value() ) EXPECTED (2); - VALUE( byptr_view.element_at(5).has_value()) EXPECTED(false); -#endif -} - -void test_string() { - std::string h("Hello there people"); - auto lh = lazy_view(h); - auto f3 = lh.skip(6).take(3); - VALUE( f3.size() ) EXPECTED(3); - VALUE( f3.element_at(0).value() ) EXPECTED( 't' ); - VALUE( lh.take(60).size() ) EXPECTED( h.size() ); - auto filt = lh.filter(F(_ == 'o')); - VALUE(filt.size()) EXPECTED (2); -} - -void test_underscore_macros() { - std::vector t1({ 1, 19, 4, 2, 5, -1, 5 }); - auto vt1 = lazy_view(t1); - int val = vt1._filter(_>1).size(); - VALUE(val) EXPECTED(5); - int el = vt1._filter(_>1).take(1)._map(_+1).get().value(); - VALUE(el) EXPECTED(20); - -} -#include "TRandom3.h" -void test_free_stream() { - TRandom* gen = new TRandom3; - auto fs = free_stream([gen](double){ return gen->Poisson(2); }); - fs.take(10).foreach(PRINT); - auto s = fs.take(10000).stat(); - // check if generation actually worked as expected - for poisson bot mean and variance should be similar and equal to poisson parameter - std::cout << s.mean() << " " << s.sigma() << std::endl; - VALUE(std::abs(s.mean() - 2) < 0.1) EXPECTED(true); - VALUE(std::abs(s.var() - 2) < 0.1) EXPECTED(true); - -} - -void test_infinite_zip() { - // Generuje 0 - nieskończoność - auto infinite_ints = iota_stream(0); - - // Generuje liczby losowe (nieskończoność) - auto infinite_randoms = crandom_stream(); - - // Łączymy dwa nieskończone strumienie - // Bierzemy tylko 10 pierwszych par => bylaby pętla nieskończona - auto zipped = infinite_ints.zip(infinite_randoms).take(10); - - VALUE(zipped.size()) EXPECTED(10); - - // Sprawdzamy czy pierwszy element pary to kolejne liczby całkowite - VALUE(zipped.element_at(0).value().first) EXPECTED(0); - VALUE(zipped.element_at(5).value().first) EXPECTED(5); - VALUE(zipped.element_at(9).value().first) EXPECTED(9); - - // Czy da się iterować? - std::cout << "Infinite Zip Output: "; - zipped.foreach(S(std::cout << "[" << _.first << ":" << _.second << "] ")); - std::cout << "\n"; -} - -void test_direct_view_as_unknown() { - // Symulacja funkcji, która może przyjmować kontenery o nieznanym rozmiarze - // używa take() aby wymusić skończoność przetwarzania - auto process_infinite_source = [](const auto& container) { - return container.map(F(_ * 2)).take(3).sum(); - }; - - std::vector data = {1, 2, 3, 4, 5, 6}; - - // DirectView jako źródło danych - auto dv = DirectView(data); - - // Sprawdzenie czy DirectView jest poprawnie obsługiwany jako kontener o nieznanym rozmiarze - // Oczekiwany wynik: (1*2) + (2*2) + (3*2) = 12 - VALUE(process_infinite_source(dv)) EXPECTED(12); - - // Wyciągnięcie operacji z lambdą przed makro VALUE - size_t count_result = dv.count(F(_ > 0)); - VALUE(count_result) EXPECTED(6); -} - - -int main() { - const int failed = - + SUITE(test_type_presentation) - + SUITE(test_element_access) - + SUITE(test_count_and_find) - + SUITE(test_filter) - + SUITE(test_map) - + SUITE(test_filter_map) - + SUITE(test_staging) - + SUITE(test_take) - + SUITE(test_sum_and_accumulate) - + SUITE(test_chain) - + SUITE(test_sort) - + SUITE(test_enumerate) - + SUITE(test_reversal) - + SUITE(test_min_max) - + SUITE(test_zip) - + SUITE(test_redirect) - + SUITE(test_series) - + SUITE(test_cartesian) - + SUITE(test_group) - + SUITE(test_stat) - + SUITE(test_to_ref_ptr) - + SUITE(test_one_element_container) - + SUITE(test_match) - + SUITE(test_ptr_view) - + SUITE(test_array_view) - + SUITE(test_string) - + SUITE(test_underscore_macros) - + SUITE(test_free_stream) - + SUITE(test_infinite_zip) - + SUITE(test_direct_view_as_unknown); - - std::cout << (failed == 0 ? "ALL OK" : "FAILURE") << std::endl; - return failed; -}