diff --git a/doc/src/adaptors.rst b/doc/src/adaptors.rst index 20c70eec..8865bac5 100644 --- a/doc/src/adaptors.rst +++ b/doc/src/adaptors.rst @@ -8,7 +8,7 @@ Function Adaptors ../../include/fit/compose ../../include/fit/conditional ../../include/fit/combine - ../../include/fit/compress + ../../include/fit/fold ../../include/fit/decorate ../../include/fit/fix ../../include/fit/flip @@ -24,7 +24,7 @@ Function Adaptors ../../include/fit/protect ../../include/fit/result ../../include/fit/reveal - ../../include/fit/reverse_compress + ../../include/fit/reverse_fold ../../include/fit/rotate ../../include/fit/static ../../include/fit/unpack \ No newline at end of file diff --git a/doc/src/point_free.md b/doc/src/point_free.md index 3f37a75a..9ece3cba 100644 --- a/doc/src/point_free.md +++ b/doc/src/point_free.md @@ -74,14 +74,14 @@ Another example, say we would like to write a varidiac version of `max`. We coul return std::max(x, max(y, xs...)); } -With point-free style programming, we can recognize this is a [fold](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29), and write it using the [`compress`](/include/fit/compress) adaptor, which will do a fold over the variadic parameters: +With point-free style programming, we can recognize this is a [fold](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29), and write it using the [`fold`](/include/fit/fold) adaptor, which will do a fold over the variadic parameters: - FIT_STATIC_FUNCTION(max) = compress(FIT_LIFT(std::max)); + FIT_STATIC_FUNCTION(max) = fold(FIT_LIFT(std::max)); [`FIT_LIFT`](/include/fit/lift) is used to grab the entire overload set of `std::max` function, which is needed since `std::max` is templated and we want the variadic `std::max` function to handle any types as well. So now it can be called like this: auto n = max(1, 2, 4, 3); // Returns 4 auto m = max(0.1, 0.2, 0.5, 0.4); // Returns 0.5 -By using [`compress`](/include/fit/compress), `max(1, 2, 4, 3)` will call `std::max` like `std::max(std::max(std::max(1, 2), 4), 3)` and `max(0.1, 0.2, 0.5, 0.4)` will be called like `std::max(std::max(std::max(0.1, 0.2), 0.5), 0.4)`. +By using [`fold`](/include/fit/fold), `max(1, 2, 4, 3)` will call `std::max` like `std::max(std::max(std::max(1, 2), 4), 3)` and `max(0.1, 0.2, 0.5, 0.4)` will be called like `std::max(std::max(std::max(0.1, 0.2), 0.5), 0.4)`. diff --git a/example/example.h b/example/example.h index 83bed4aa..1f993242 100644 --- a/example/example.h +++ b/example/example.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/example/pointfree.cpp b/example/pointfree.cpp index b37f6800..62de152c 100644 --- a/example/pointfree.cpp +++ b/example/pointfree.cpp @@ -12,7 +12,7 @@ using namespace fit; FIT_STATIC_FUNCTION(simple_print) = FIT_LIFT(std::ref(std::cout) << _); FIT_STATIC_FUNCTION(print) = by(simple_print); FIT_STATIC_FUNCTION(print_lines) = by(flow(simple_print, _ << std::integral_constant{})); -FIT_STATIC_FUNCTION(max) = compress(FIT_LIFT(std::max)); +FIT_STATIC_FUNCTION(max) = fold(FIT_LIFT(std::max)); int main() { diff --git a/example/sequence.cpp b/example/sequence.cpp index 57207d78..70e30a7b 100644 --- a/example/sequence.cpp +++ b/example/sequence.cpp @@ -23,7 +23,7 @@ FIT_STATIC_LAMBDA_FUNCTION(tuple_for_each) = [](auto&& sequence, auto f) // Fold over tuple using a f as the binary operator FIT_STATIC_LAMBDA_FUNCTION(tuple_fold) = [](auto&& sequence, auto f) { - return unpack(compress(f))(std::forward(sequence)); + return unpack(fold(f))(std::forward(sequence)); }; // Concat multiple tuples FIT_STATIC_FUNCTION(tuple_cat) = unpack(construct()); diff --git a/include/fit.hpp b/include/fit.hpp index ee3fa6a0..16aef5ed 100644 --- a/include/fit.hpp +++ b/include/fit.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/fit/apply.hpp b/include/fit/apply.hpp index 2de70deb..cc1d4535 100644 --- a/include/fit/apply.hpp +++ b/include/fit/apply.hpp @@ -26,7 +26,7 @@ /// --------- /// /// assert(apply(f)(xs...) == f(xs...)); -/// assert(compress(apply, f)(x, y, z) == f(x)(y)(z)); +/// assert(fold(apply, f)(x, y, z) == f(x)(y)(z)); /// /// Requirements /// ------------ diff --git a/include/fit/compress.hpp b/include/fit/fold.hpp similarity index 81% rename from include/fit/compress.hpp rename to include/fit/fold.hpp index 4bbda297..06cc0935 100644 --- a/include/fit/compress.hpp +++ b/include/fit/fold.hpp @@ -1,20 +1,20 @@ /*============================================================================= Copyright (c) 2015 Paul Fultz II - compress.h + fold.h Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ -#ifndef FIT_GUARD_COMPRESS_H -#define FIT_GUARD_COMPRESS_H +#ifndef FIT_GUARD_FOLD_H +#define FIT_GUARD_FOLD_H -/// compress +/// fold /// ======== /// /// Description /// ----------- /// -/// The `compress` function adaptor uses a binary function to apply a +/// The `fold` function adaptor uses a binary function to apply a /// [fold](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29) /// operation to the arguments passed to the function. Additionally, an /// optional initial state can be provided, otherwise the first argument is @@ -27,18 +27,18 @@ /// -------- /// /// template -/// constexpr compress_adaptor compress(F f, State s); +/// constexpr fold_adaptor fold(F f, State s); /// /// template -/// constexpr compress_adaptor compress(F f); +/// constexpr fold_adaptor fold(F f); /// /// Semantics /// --------- /// -/// assert(compress(f, z)() == z); -/// assert(compress(f, z)(x, xs...) == compress(f, f(z, x))(xs...)); -/// assert(compress(f)(x) == x); -/// assert(compress(f)(x, y, xs...) == compress(f)(f(x, y), xs...)); +/// assert(fold(f, z)() == z); +/// assert(fold(f, z)(x, xs...) == fold(f, f(z, x))(xs...)); +/// assert(fold(f)(x) == x); +/// assert(fold(f)(x, y, xs...) == fold(f)(f(x, y), xs...)); /// /// Requirements /// ------------ @@ -67,7 +67,7 @@ /// } /// }; /// int main() { -/// assert(fit::compress(max_f())(2, 3, 4, 5) == 5); +/// assert(fit::fold(max_f())(2, 3, 4, 5) == 5); /// } /// /// References @@ -106,11 +106,11 @@ struct v_fold } template -struct compress_adaptor +struct fold_adaptor : detail::compressed_pair, State> { typedef detail::compressed_pair, State> base_type; - FIT_INHERIT_CONSTRUCTOR(compress_adaptor, base_type) + FIT_INHERIT_CONSTRUCTOR(fold_adaptor, base_type) template constexpr const detail::callable_base& base_function(Ts&&... xs) const noexcept @@ -124,7 +124,7 @@ struct compress_adaptor return this->second(xs...); } - FIT_RETURNS_CLASS(compress_adaptor); + FIT_RETURNS_CLASS(fold_adaptor); template constexpr FIT_SFINAE_RESULT(detail::v_fold, id_&>, id_, id_...) @@ -140,10 +140,10 @@ struct compress_adaptor template -struct compress_adaptor +struct fold_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(compress_adaptor, detail::callable_base) + FIT_INHERIT_CONSTRUCTOR(fold_adaptor, detail::callable_base) template constexpr const detail::callable_base& base_function(Ts&&... xs) const noexcept @@ -151,7 +151,7 @@ struct compress_adaptor return fit::always_ref(*this)(xs...); } - FIT_RETURNS_CLASS(compress_adaptor); + FIT_RETURNS_CLASS(fold_adaptor); template constexpr FIT_SFINAE_RESULT(detail::v_fold, id_&>, id_...) @@ -164,7 +164,7 @@ struct compress_adaptor ) }; -FIT_DECLARE_STATIC_VAR(compress, detail::make); +FIT_DECLARE_STATIC_VAR(fold, detail::make); } // namespace fit diff --git a/include/fit/reverse_compress.hpp b/include/fit/reverse_fold.hpp similarity index 78% rename from include/fit/reverse_compress.hpp rename to include/fit/reverse_fold.hpp index a56455e0..3c995a3f 100644 --- a/include/fit/reverse_compress.hpp +++ b/include/fit/reverse_fold.hpp @@ -1,20 +1,20 @@ /*============================================================================= Copyright (c) 2015 Paul Fultz II - reverse_compress.h + reverse_fold.h Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ -#ifndef FIT_GUARD_REVERSE_COMPRESS_H -#define FIT_GUARD_REVERSE_COMPRESS_H +#ifndef FIT_GUARD_REVERSE_FOLD_H +#define FIT_GUARD_REVERSE_FOLD_H -/// reverse_compress +/// reverse_fold /// ======== /// /// Description /// ----------- /// -/// The `reverse_compress` function adaptor uses a binary function to apply a +/// The `reverse_fold` function adaptor uses a binary function to apply a /// reverse [fold] /// (https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)(ie right /// fold in functional programming terms) operation to the arguments passed to @@ -28,18 +28,18 @@ /// -------- /// /// template -/// constexpr reverse_compress_adaptor reverse_compress(F f, State s); +/// constexpr reverse_fold_adaptor reverse_fold(F f, State s); /// /// template -/// constexpr reverse_compress_adaptor reverse_compress(F f); +/// constexpr reverse_fold_adaptor reverse_fold(F f); /// /// Semantics /// --------- /// -/// assert(reverse_compress(f, z)() == z); -/// assert(reverse_compress(f, z)(x, xs...) == f(reverse_compress(f, z)(xs...), x)); -/// assert(reverse_compress(f)(x) == x); -/// assert(reverse_compress(f)(x, xs...) == f(reverse_compress(f)(xs...), x)); +/// assert(reverse_fold(f, z)() == z); +/// assert(reverse_fold(f, z)(x, xs...) == f(reverse_fold(f, z)(xs...), x)); +/// assert(reverse_fold(f)(x) == x); +/// assert(reverse_fold(f)(x, xs...) == f(reverse_fold(f)(xs...), x)); /// /// Requirements /// ------------ @@ -69,7 +69,7 @@ /// }; /// /// int main() { -/// assert(fit::reverse_compress(max_f())(2, 3, 4, 5) == 5); +/// assert(fit::reverse_fold(max_f())(2, 3, 4, 5) == 5); /// } /// /// References @@ -108,11 +108,11 @@ struct v_reverse_fold } template -struct reverse_compress_adaptor +struct reverse_fold_adaptor : detail::compressed_pair, State> { typedef detail::compressed_pair, State> base_type; - FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, base_type) + FIT_INHERIT_CONSTRUCTOR(reverse_fold_adaptor, base_type) template constexpr const detail::callable_base& base_function(Ts&&... xs) const noexcept @@ -126,7 +126,7 @@ struct reverse_compress_adaptor return this->second(xs...); } - FIT_RETURNS_CLASS(reverse_compress_adaptor); + FIT_RETURNS_CLASS(reverse_fold_adaptor); template constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_&>, id_, id_...) @@ -142,10 +142,10 @@ struct reverse_compress_adaptor template -struct reverse_compress_adaptor +struct reverse_fold_adaptor : detail::callable_base { - FIT_INHERIT_CONSTRUCTOR(reverse_compress_adaptor, detail::callable_base) + FIT_INHERIT_CONSTRUCTOR(reverse_fold_adaptor, detail::callable_base) template constexpr const detail::callable_base& base_function(Ts&&... xs) const noexcept @@ -153,7 +153,7 @@ struct reverse_compress_adaptor return fit::always_ref(*this)(xs...); } - FIT_RETURNS_CLASS(reverse_compress_adaptor); + FIT_RETURNS_CLASS(reverse_fold_adaptor); template constexpr FIT_SFINAE_RESULT(detail::v_reverse_fold, id_&>, id_...) @@ -166,7 +166,7 @@ struct reverse_compress_adaptor ) }; -FIT_DECLARE_STATIC_VAR(reverse_compress, detail::make); +FIT_DECLARE_STATIC_VAR(reverse_fold, detail::make); } // namespace fit diff --git a/test/compress.cpp b/test/compress.cpp deleted file mode 100644 index f207bc76..00000000 --- a/test/compress.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include "test.hpp" - -struct max_f -{ - template - constexpr T operator()(T x, U y) const noexcept - { - return x > y ? x : y; - } -}; - -struct sum_f -{ - template - constexpr T operator()(T x, U y) const FIT_RETURNS_DEDUCE_NOEXCEPT(x+y) - { - return x + y; - } -}; - -#if FIT_HAS_NOEXCEPT_DEDUCTION -FIT_TEST_CASE() -{ - static_assert(noexcept(fit::compress(max_f(), 0)(2, 3, 4, 5)), "noexcept compress"); - static_assert(noexcept(fit::compress(sum_f(), 0)(2, 3, 4, 5)), "noexcept compress"); - static_assert(!noexcept(fit::compress(sum_f(), std::string())("hello", "-", "world")), "noexcept compress"); -} -#endif - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::compress(max_f(), 0)(2, 3, 4, 5) == 5); - FIT_TEST_CHECK(fit::compress(max_f(), 0)(5, 4, 3, 2) == 5); - FIT_TEST_CHECK(fit::compress(max_f(), 0)(2, 3, 5, 4) == 5); - - FIT_STATIC_TEST_CHECK(fit::compress(max_f(), 0)(2, 3, 4, 5) == 5); - FIT_STATIC_TEST_CHECK(fit::compress(max_f(), 0)(5, 4, 3, 2) == 5); - FIT_STATIC_TEST_CHECK(fit::compress(max_f(), 0)(2, 3, 5, 4) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::compress(max_f(), 0)() == 0); - FIT_TEST_CHECK(fit::compress(max_f(), 0)(5) == 5); - - FIT_STATIC_TEST_CHECK(fit::compress(max_f(), 0)() == 0); - FIT_STATIC_TEST_CHECK(fit::compress(max_f(), 0)(5) == 5); -} - -template -constexpr auto find_positive_max(Ts... xs) FIT_RETURNS -( - fit::compress(max_f(), 0)(xs...) -); - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(find_positive_max() == 0); - FIT_TEST_CHECK(find_positive_max(5) == 5); - - FIT_STATIC_TEST_CHECK(find_positive_max() == 0); - FIT_STATIC_TEST_CHECK(find_positive_max(5) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::compress(max_f())(5) == 5); - - FIT_STATIC_TEST_CHECK(fit::compress(max_f())(5) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::compress(max_f())(2, 3, 4, 5) == 5); - FIT_TEST_CHECK(fit::compress(max_f())(5, 4, 3, 2) == 5); - FIT_TEST_CHECK(fit::compress(max_f())(2, 3, 5, 4) == 5); - - FIT_STATIC_TEST_CHECK(fit::compress(max_f())(2, 3, 4, 5) == 5); - FIT_STATIC_TEST_CHECK(fit::compress(max_f())(5, 4, 3, 2) == 5); - FIT_STATIC_TEST_CHECK(fit::compress(max_f())(2, 3, 5, 4) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::compress(sum_f(), std::string())("hello", "-", "world") == "hello-world"); -} diff --git a/test/fold.cpp b/test/fold.cpp new file mode 100644 index 00000000..fc37dce6 --- /dev/null +++ b/test/fold.cpp @@ -0,0 +1,87 @@ +#include +#include "test.hpp" + +struct max_f +{ + template + constexpr T operator()(T x, U y) const noexcept + { + return x > y ? x : y; + } +}; + +struct sum_f +{ + template + constexpr T operator()(T x, U y) const FIT_RETURNS_DEDUCE_NOEXCEPT(x+y) + { + return x + y; + } +}; + +#if FIT_HAS_NOEXCEPT_DEDUCTION +FIT_TEST_CASE() +{ + static_assert(noexcept(fit::fold(max_f(), 0)(2, 3, 4, 5)), "noexcept fold"); + static_assert(noexcept(fit::fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept fold"); + static_assert(!noexcept(fit::fold(sum_f(), std::string())("hello", "-", "world")), "noexcept fold"); +} +#endif + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::fold(max_f(), 0)(2, 3, 4, 5) == 5); + FIT_TEST_CHECK(fit::fold(max_f(), 0)(5, 4, 3, 2) == 5); + FIT_TEST_CHECK(fit::fold(max_f(), 0)(2, 3, 5, 4) == 5); + + FIT_STATIC_TEST_CHECK(fit::fold(max_f(), 0)(2, 3, 4, 5) == 5); + FIT_STATIC_TEST_CHECK(fit::fold(max_f(), 0)(5, 4, 3, 2) == 5); + FIT_STATIC_TEST_CHECK(fit::fold(max_f(), 0)(2, 3, 5, 4) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::fold(max_f(), 0)() == 0); + FIT_TEST_CHECK(fit::fold(max_f(), 0)(5) == 5); + + FIT_STATIC_TEST_CHECK(fit::fold(max_f(), 0)() == 0); + FIT_STATIC_TEST_CHECK(fit::fold(max_f(), 0)(5) == 5); +} + +template +constexpr auto find_positive_max(Ts... xs) FIT_RETURNS +( + fit::fold(max_f(), 0)(xs...) +); + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(find_positive_max() == 0); + FIT_TEST_CHECK(find_positive_max(5) == 5); + + FIT_STATIC_TEST_CHECK(find_positive_max() == 0); + FIT_STATIC_TEST_CHECK(find_positive_max(5) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::fold(max_f())(5) == 5); + + FIT_STATIC_TEST_CHECK(fit::fold(max_f())(5) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::fold(max_f())(2, 3, 4, 5) == 5); + FIT_TEST_CHECK(fit::fold(max_f())(5, 4, 3, 2) == 5); + FIT_TEST_CHECK(fit::fold(max_f())(2, 3, 5, 4) == 5); + + FIT_STATIC_TEST_CHECK(fit::fold(max_f())(2, 3, 4, 5) == 5); + FIT_STATIC_TEST_CHECK(fit::fold(max_f())(5, 4, 3, 2) == 5); + FIT_STATIC_TEST_CHECK(fit::fold(max_f())(2, 3, 5, 4) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::fold(sum_f(), std::string())("hello", "-", "world") == "hello-world"); +} diff --git a/test/reverse_compress.cpp b/test/reverse_compress.cpp deleted file mode 100644 index e2bb933b..00000000 --- a/test/reverse_compress.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include "test.hpp" - -struct max_f -{ - template - constexpr T operator()(T x, U y) const noexcept - { - return x > y ? x : y; - } -}; - -struct sum_f -{ - template - constexpr T operator()(T x, U y) const FIT_RETURNS_DEDUCE_NOEXCEPT(x+y) - { - return x + y; - } -}; - -#if FIT_HAS_NOEXCEPT_DEDUCTION -FIT_TEST_CASE() -{ - static_assert(noexcept(fit::reverse_compress(max_f(), 0)(2, 3, 4, 5)), "noexcept reverse_compress"); - static_assert(noexcept(fit::reverse_compress(sum_f(), 0)(2, 3, 4, 5)), "noexcept reverse_compress"); - static_assert(!noexcept(fit::reverse_compress(sum_f(), std::string())("hello", "-", "world")), "noexcept reverse_compress"); -} -#endif - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::reverse_compress(max_f(), 0)(2, 3, 4, 5) == 5); - FIT_TEST_CHECK(fit::reverse_compress(max_f(), 0)(5, 4, 3, 2) == 5); - FIT_TEST_CHECK(fit::reverse_compress(max_f(), 0)(2, 3, 5, 4) == 5); - - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f(), 0)(2, 3, 4, 5) == 5); - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f(), 0)(5, 4, 3, 2) == 5); - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f(), 0)(2, 3, 5, 4) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::reverse_compress(max_f(), 0)() == 0); - FIT_TEST_CHECK(fit::reverse_compress(max_f(), 0)(5) == 5); - - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f(), 0)() == 0); - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f(), 0)(5) == 5); -} - -template -constexpr auto find_positive_max(Ts... xs) FIT_RETURNS -( - fit::reverse_compress(max_f(), 0)(xs...) -); - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(find_positive_max() == 0); - FIT_TEST_CHECK(find_positive_max(5) == 5); - - FIT_STATIC_TEST_CHECK(find_positive_max() == 0); - FIT_STATIC_TEST_CHECK(find_positive_max(5) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::reverse_compress(max_f())(5) == 5); - - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f())(5) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::reverse_compress(max_f())(2, 3, 4, 5) == 5); - FIT_TEST_CHECK(fit::reverse_compress(max_f())(5, 4, 3, 2) == 5); - FIT_TEST_CHECK(fit::reverse_compress(max_f())(2, 3, 5, 4) == 5); - - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f())(2, 3, 4, 5) == 5); - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f())(5, 4, 3, 2) == 5); - FIT_STATIC_TEST_CHECK(fit::reverse_compress(max_f())(2, 3, 5, 4) == 5); -} - -FIT_TEST_CASE() -{ - FIT_TEST_CHECK(fit::reverse_compress(sum_f(), std::string())("hello", "-", "world") == "world-hello"); -} diff --git a/test/reverse_fold.cpp b/test/reverse_fold.cpp new file mode 100644 index 00000000..a19d4b2e --- /dev/null +++ b/test/reverse_fold.cpp @@ -0,0 +1,87 @@ +#include +#include "test.hpp" + +struct max_f +{ + template + constexpr T operator()(T x, U y) const noexcept + { + return x > y ? x : y; + } +}; + +struct sum_f +{ + template + constexpr T operator()(T x, U y) const FIT_RETURNS_DEDUCE_NOEXCEPT(x+y) + { + return x + y; + } +}; + +#if FIT_HAS_NOEXCEPT_DEDUCTION +FIT_TEST_CASE() +{ + static_assert(noexcept(fit::reverse_fold(max_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold"); + static_assert(noexcept(fit::reverse_fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold"); + static_assert(!noexcept(fit::reverse_fold(sum_f(), std::string())("hello", "-", "world")), "noexcept reverse_fold"); +} +#endif + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5); + FIT_TEST_CHECK(fit::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5); + FIT_TEST_CHECK(fit::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5); + + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5); + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5); + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::reverse_fold(max_f(), 0)() == 0); + FIT_TEST_CHECK(fit::reverse_fold(max_f(), 0)(5) == 5); + + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f(), 0)() == 0); + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f(), 0)(5) == 5); +} + +template +constexpr auto find_positive_max(Ts... xs) FIT_RETURNS +( + fit::reverse_fold(max_f(), 0)(xs...) +); + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(find_positive_max() == 0); + FIT_TEST_CHECK(find_positive_max(5) == 5); + + FIT_STATIC_TEST_CHECK(find_positive_max() == 0); + FIT_STATIC_TEST_CHECK(find_positive_max(5) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::reverse_fold(max_f())(5) == 5); + + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f())(5) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::reverse_fold(max_f())(2, 3, 4, 5) == 5); + FIT_TEST_CHECK(fit::reverse_fold(max_f())(5, 4, 3, 2) == 5); + FIT_TEST_CHECK(fit::reverse_fold(max_f())(2, 3, 5, 4) == 5); + + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f())(2, 3, 4, 5) == 5); + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f())(5, 4, 3, 2) == 5); + FIT_STATIC_TEST_CHECK(fit::reverse_fold(max_f())(2, 3, 5, 4) == 5); +} + +FIT_TEST_CASE() +{ + FIT_TEST_CHECK(fit::reverse_fold(sum_f(), std::string())("hello", "-", "world") == "world-hello"); +}