1 /* Copyright 2017-2018 Fizyr B.V. - https://fizyr.com 2 * 3 * Redistribution and use in source and binary forms, with or without modification, 4 * are permitted provided that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain the above copyright notice, 7 * this list of conditions and the following disclaimer. 8 * 9 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * 13 * 3. Neither the name of the copyright holder nor the names of its contributors 14 * may be used to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "../static_assert_same.hpp" 30 #include "tuple/fold.hpp" 31 32 #include <catch2/catch.hpp> 33 34 namespace estd { 35 36 TEST_CASE("tuple left fold", "[tuple]") { __anon44bd59e20102(auto a, auto b) 37 auto sum = [] (auto a, auto b) { return a + b; }; __anon44bd59e20202(auto a, auto b) 38 auto mul = [] (auto a, auto b) { return a * b; }; __anon44bd59e20302(auto a, auto) 39 auto drop_right = [] (auto a, auto) { return a; }; __anon44bd59e20402(auto, auto b) 40 auto drop_left = [] (auto, auto b) { return b; }; 41 42 SECTION("foldl over empty tuple returns initial accumulator") { 43 REQUIRE(foldl(std::tuple<>(), 5, sum) == 5); 44 } 45 46 SECTION("foldl without accumulator over single element tuple returns first element") { 47 REQUIRE(foldl(std::tuple(5), mul) == 5); 48 } 49 50 SECTION("foldl without accumulator over non-empty tuple") { 51 REQUIRE(foldl(std::tuple(1, 2, 3, 4), sum) == 1 + 2 + 3 + 4); 52 REQUIRE(foldl(std::tuple(1, 2, 3, 4), mul) == 1 * 2 * 3 * 4); 53 } 54 55 SECTION("foldl with accumulator over non-empty tuple") { 56 REQUIRE(foldl(std::tuple(1, 2, 3, 4), 10, sum) == 10 + 1 + 2 + 3 + 4); 57 REQUIRE(foldl(std::tuple(1, 2, 3, 4), 10, mul) == 10 * 1 * 2 * 3 * 4); 58 } 59 60 SECTION("foldl over heterogenous tuple") { 61 REQUIRE(foldl(std::tuple(1, 2.0, 3.f, 4), 10, sum) == 10.0 + 1 + 2 + 3 + 4); 62 REQUIRE(foldl(std::tuple(1, 2.0, 3.f, 4), 10, mul) == 10.0 * 1 * 2 * 3 * 4); 63 static_assert_same<decltype(foldl(std::tuple(1, 2.0, 3.f, 4), 10, sum)), double>(); 64 static_assert_same<decltype(foldl(std::tuple(1, 2.0, 3.f, 4), 10, mul)), double>(); 65 } 66 67 SECTION("foldl is a left fold") { 68 REQUIRE(foldl(std::tuple(1.0, 2, 3, 4.0), 10, drop_right) == 10); 69 REQUIRE(foldl(std::tuple(1 , 2, 3, 4.0), drop_right) == 1); 70 static_assert_same<decltype(foldl(std::tuple(1.0, 2, 3, 4.0), 10, drop_right)), int>(); 71 static_assert_same<decltype(foldl(std::tuple(1 , 2, 3, 4.0), drop_right)), int>(); 72 73 REQUIRE(foldl(std::tuple(1, 2, 3, 4.0), 10, drop_left) == 4.0); 74 REQUIRE(foldl(std::tuple(1, 2, 3, 4.0), drop_left) == 4.0); 75 static_assert_same<decltype(foldl(std::tuple(1, 2, 3, 4.0), 10, drop_left)), double>(); 76 static_assert_same<decltype(foldl(std::tuple(1, 2, 3, 4.0), drop_left)), double>(); 77 } 78 } 79 80 TEST_CASE("tuple right fold", "[tuple]") { __anon44bd59e20502(auto a, auto b) 81 auto sum = [] (auto a, auto b) { return a + b; }; __anon44bd59e20602(auto a, auto b) 82 auto mul = [] (auto a, auto b) { return a * b; }; __anon44bd59e20702(auto a, auto) 83 auto drop_right = [] (auto a, auto) { return a; }; __anon44bd59e20802(auto, auto b) 84 auto drop_left = [] (auto, auto b) { return b; }; 85 86 SECTION("foldr over empty tuple returns initial accumulator") { 87 REQUIRE(foldr(std::tuple<>(), 5, sum) == 5); 88 } 89 90 SECTION("foldr without accumulator over single element tuple returns first element") { 91 REQUIRE(foldr(std::tuple(5), mul) == 5); 92 } 93 94 SECTION("foldr without accumulator over non-empty tuple") { 95 REQUIRE(foldr(std::tuple(1, 2, 3, 4), sum) == 1 + 2 + 3 + 4); 96 REQUIRE(foldr(std::tuple(1, 2, 3, 4), mul) == 1 * 2 * 3 * 4); 97 } 98 99 SECTION("foldr with accumulator over non-empty tuple") { 100 REQUIRE(foldr(std::tuple(1, 2, 3, 4), 10, sum) == 10 + 1 + 2 + 3 + 4); 101 REQUIRE(foldr(std::tuple(1, 2, 3, 4), 10, mul) == 10 * 1 * 2 * 3 * 4); 102 } 103 104 SECTION("foldr over heterogenous tuple") { 105 REQUIRE(foldr(std::tuple(1, 2.0, 3.f, 4), 10, sum) == 10.0 + 1 + 2 + 3 + 4); 106 REQUIRE(foldr(std::tuple(1, 2.0, 3.f, 4), 10, mul) == 10.0 * 1 * 2 * 3 * 4); 107 static_assert_same<decltype(foldr(std::tuple(1, 2.0, 3.f, 4), 10, sum)), double>(); 108 static_assert_same<decltype(foldr(std::tuple(1, 2.0, 3.f, 4), 10, mul)), double>(); 109 } 110 111 SECTION("foldr is a right fold") { 112 REQUIRE(foldr(std::tuple(1, 2, 3, 4.0), 10.0, drop_right) == 1); 113 REQUIRE(foldr(std::tuple(1, 2, 3, 4.0), drop_right) == 1); 114 static_assert_same<decltype(foldr(std::tuple(1, 2, 3, 4.0), 10.0, drop_right)), int>(); 115 static_assert_same<decltype(foldr(std::tuple(1, 2, 3, 4.0), drop_right)), int>(); 116 117 REQUIRE(foldr(std::tuple(1, 2, 3, 4 ), 10.0, drop_left) == 10.0); 118 REQUIRE(foldr(std::tuple(1, 2, 3, 4.0), drop_left) == 4.0); 119 static_assert_same<decltype(foldr(std::tuple(1, 2, 3, 4 ), 10.0, drop_left)), double>(); 120 static_assert_same<decltype(foldr(std::tuple(1, 2, 3, 4.0), drop_left)), double>(); 121 } 122 } 123 124 } 125