1 // Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. 2 // https://github.com/Dobiasd/FunctionalPlus 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #include <doctest/doctest.h> 8 #include <fplus/fplus.hpp> 9 #include <vector> 10 11 namespace { 12 __anon107dddc40202(int x)13 auto is_even_int = [](int x){ return x % 2 == 0; }; 14 typedef std::vector<int> IntVector; 15 typedef std::vector<bool> BoolVector; 16 IntVector xs = {1,2,2,3,2}; 17 } 18 19 TEST_CASE("container_properties_test - any") 20 { 21 using namespace fplus; 22 REQUIRE_EQ(any(BoolVector()), false); 23 REQUIRE_EQ(any(BoolVector({true})), true); 24 REQUIRE_EQ(any(BoolVector({false})), false); 25 REQUIRE_EQ(any(BoolVector({false, false})), false); 26 REQUIRE_EQ(any(BoolVector({true, false})), true); 27 28 REQUIRE_EQ(any_by(is_even_int, IntVector()), false); 29 REQUIRE_EQ(any_by(is_even_int, IntVector({2})), true); 30 REQUIRE_EQ(any_by(is_even_int, IntVector({1})), false); 31 REQUIRE_EQ(any_by(is_even_int, IntVector({1, 1})), false); 32 REQUIRE_EQ(any_by(is_even_int, IntVector({2, 1})), true); 33 } 34 35 36 TEST_CASE("container_properties_test - none") 37 { 38 using namespace fplus; 39 REQUIRE_EQ(none(BoolVector()), true); 40 REQUIRE_EQ(none(BoolVector({true})), false); 41 REQUIRE_EQ(none(BoolVector({false})), true); 42 REQUIRE_EQ(none(BoolVector({false, false})), true); 43 REQUIRE_EQ(none(BoolVector({true, false})), false); 44 45 REQUIRE_EQ(none_by(is_even_int, IntVector()), true); 46 REQUIRE_EQ(none_by(is_even_int, IntVector({2})), false); 47 REQUIRE_EQ(none_by(is_even_int, IntVector({1})), true); 48 REQUIRE_EQ(none_by(is_even_int, IntVector({1, 1})), true); 49 REQUIRE_EQ(none_by(is_even_int, IntVector({2, 1})), false); 50 } 51 52 TEST_CASE("container_properties_test - minmax") 53 { 54 using namespace fplus; __anon107dddc40302(int i) 55 auto negateInt = [](int i) -> int { return -i; }; 56 57 REQUIRE_EQ(minimum(xs), 1); 58 REQUIRE_EQ(maximum(xs), 3); 59 60 REQUIRE_EQ(minimum_by(std::greater<int>(), xs), 3); 61 REQUIRE_EQ(maximum_by(std::greater<int>(), xs), 1); 62 63 REQUIRE_EQ(minimum_on(negateInt, xs), 3); 64 REQUIRE_EQ(maximum_on(negateInt, xs), 1); 65 66 REQUIRE_EQ(minimum_idx(xs), 0); 67 REQUIRE_EQ(maximum_idx(xs), 3); 68 69 REQUIRE_EQ(minimum_idx_by(std::greater<int>(), xs), 3); 70 REQUIRE_EQ(maximum_idx_by(std::greater<int>(), xs), 0); 71 72 REQUIRE_EQ(minimum_idx_on(negateInt, xs), 3); 73 REQUIRE_EQ(maximum_idx_on(negateInt, xs), 0); 74 } 75 76 TEST_CASE("container_properties_test - minmax_maybe") 77 { 78 using namespace fplus; __anon107dddc40402(int i) 79 auto negateInt = [](int i) -> int { return -i; }; 80 81 REQUIRE_EQ(minimum_maybe(xs), maybe<int>(1)); 82 REQUIRE_EQ(maximum_maybe(xs), maybe<int>(3)); 83 84 REQUIRE_EQ(minimum_by_maybe(std::greater<int>(), xs), maybe<int>(3)); 85 REQUIRE_EQ(maximum_by_maybe(std::greater<int>(), xs), maybe<int>(1)); 86 87 REQUIRE_EQ(minimum_on_maybe(negateInt, xs), maybe<int>(3)); 88 REQUIRE_EQ(maximum_on_maybe(negateInt, xs), maybe<int>(1)); 89 90 REQUIRE_EQ(minimum_idx_maybe(xs), maybe<std::size_t>(0)); 91 REQUIRE_EQ(maximum_idx_maybe(xs), maybe<std::size_t>(3)); 92 93 REQUIRE_EQ(minimum_idx_by_maybe(std::greater<int>(), xs), maybe<std::size_t>(3)); 94 REQUIRE_EQ(maximum_idx_by_maybe(std::greater<int>(), xs), maybe<std::size_t>(0)); 95 96 97 } 98 99 TEST_CASE("container_properties_test - mean") 100 { 101 using namespace fplus; 102 std::vector<unsigned char> uchars = {200, 202}; 103 typedef std::vector<double> DoubleVector; 104 REQUIRE_EQ(sum(xs), 10); 105 REQUIRE_EQ(product(xs), 24); 106 REQUIRE_EQ(mean<int>(xs), 2); 107 REQUIRE_EQ(mean_using_doubles<unsigned char>(uchars), 201); 108 REQUIRE_EQ(median(IntVector({ 3 })), 3); 109 REQUIRE_EQ(median(IntVector({ 3, 5 })), 4); 110 REQUIRE(is_in_interval(3.49f, 3.51f, median<IntVector, float>(IntVector({ 3, 4 })))); 111 REQUIRE(is_in_interval(3.49, 3.51, mean<double>(DoubleVector({ 3, 4 })))); 112 REQUIRE_EQ(median(IntVector({ 3, 9, 5 })), 5); 113 REQUIRE_EQ(median(xs), 2); 114 REQUIRE_EQ(sum(convert_container_and_elems<std::vector<int>>(std::string("hello"))), 532); 115 REQUIRE(is_in_interval(5.99, 6.01, mean_stddev<double>(DoubleVector({ 4, 8 })).first)); 116 REQUIRE(is_in_interval(1.99, 2.01, mean_stddev<double>(DoubleVector({ 4, 8 })).second)); 117 REQUIRE(is_in_interval(3.749f, 3.751f, mean_stddev<float>(IntVector({ 1, 3, 7, 4 })).first)); 118 REQUIRE(is_in_interval(2.16f, 2.17f, mean_stddev<float>(IntVector({ 1, 3, 7, 4 })).second)); 119 } 120 121 TEST_CASE("container_properties_test - all_unique_less") 122 { 123 using namespace fplus; 124 REQUIRE_FALSE(all_unique_less(IntVector({1,2,3,2}))); 125 REQUIRE(all_unique_less(IntVector({4,2,1,3}))); 126 } 127 128 TEST_CASE("container_properties_test - infix") 129 { 130 using namespace fplus; 131 REQUIRE_EQ(is_infix_of(IntVector({}), IntVector({})), true); 132 REQUIRE_EQ(is_infix_of(IntVector({}), IntVector({1,2})), true); 133 REQUIRE_EQ(is_infix_of(IntVector({2,3}), xs), true); 134 REQUIRE_EQ(is_infix_of(IntVector({2,3}), xs), true); 135 REQUIRE_EQ(is_infix_of(IntVector({2,1}), xs), false); 136 REQUIRE_EQ(is_prefix_of(IntVector({ 1,2 }), xs), true); 137 REQUIRE_EQ(is_prefix_of(IntVector({ 2,2 }), xs), false); 138 REQUIRE_EQ(is_suffix_of(IntVector({ 3,2 }), xs), true); 139 REQUIRE_EQ(is_suffix_of(IntVector({ 2,2 }), xs), false); 140 } 141 142 TEST_CASE("container_properties_test - subsequence") 143 { 144 using namespace fplus; 145 REQUIRE_EQ(is_subsequence_of(IntVector(), IntVector()), true); 146 REQUIRE_EQ(is_subsequence_of(IntVector(), xs), true); 147 REQUIRE_EQ(is_subsequence_of(IntVector({ 1,3 }), xs), true); 148 REQUIRE_EQ(is_subsequence_of(IntVector({ 3,1 }), xs), false); 149 } 150 151 TEST_CASE("container_properties_test - count") 152 { 153 using namespace fplus; 154 REQUIRE_EQ(count(2, xs), 3); 155 } 156 157 TEST_CASE("container_properties_test - is_unique_in") 158 { 159 using namespace fplus; 160 REQUIRE_FALSE(is_unique_in(2, xs)); 161 REQUIRE(is_unique_in(3, xs)); 162 } 163 164 TEST_CASE("container_properties_test - is_permutation_of") 165 { 166 using namespace fplus; 167 REQUIRE(is_permutation_of(IntVector({2,3,1}), IntVector({1,2,3}))); 168 REQUIRE_FALSE(is_permutation_of(IntVector({2,3,2}), IntVector({1,2,3}))); 169 REQUIRE_FALSE(is_permutation_of(IntVector({2,3}), IntVector({1,2,3}))); 170 REQUIRE_FALSE(is_permutation_of(IntVector({2,3,1}), IntVector({1,23}))); 171 } 172 173 TEST_CASE("container_properties_test - fill_pigeonholes") 174 { 175 const std::vector<unsigned int> ys = { 0, 1, 3, 1 }; 176 REQUIRE_EQ(fplus::fill_pigeonholes_to(5, ys), std::vector<std::size_t>({1,2,0,1,0})); 177 REQUIRE_EQ(fplus::fill_pigeonholes_to(3, ys), std::vector<std::size_t>({1,2,0})); 178 REQUIRE_EQ(fplus::fill_pigeonholes(ys), std::vector<std::size_t>({1,2,0,1})); 179 180 REQUIRE_EQ(fplus::fill_pigeonholes_bool_to(3, ys), std::vector<unsigned char>({1,1,0})); 181 REQUIRE_EQ(fplus::fill_pigeonholes_bool_to(5, ys), std::vector<unsigned char>({1,1,0,1,0})); 182 REQUIRE_EQ(fplus::fill_pigeonholes_bool(ys), std::vector<unsigned char>({1,1,0,1})); 183 } 184 185 TEST_CASE("container_properties_test - present_in_all") 186 { 187 using namespace fplus; 188 const std::vector<std::vector<int>> xss = { {4,1,2}, {5,2,1}, {2,4,1} }; 189 REQUIRE_EQ(present_in_all(xss), IntVector({1,2})); 190 }