From 9c812552a97a3fb934eb9bef54eb2f5e4a708deb Mon Sep 17 00:00:00 2001 From: Chanwoo Ahn Date: Wed, 10 Apr 2024 12:23:24 +0900 Subject: [PATCH] feat: Implement pattern check with test --- include/efp/enum.hpp | 4 +-- include/efp/maybe.hpp | 57 +++++++++++++++++++++++++++++------------- include/efp/meta.hpp | 16 ++++++------ test/efp/enum_test.hpp | 1 + 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/include/efp/enum.hpp b/include/efp/enum.hpp index db7893a..e81e4f3 100644 --- a/include/efp/enum.hpp +++ b/include/efp/enum.hpp @@ -239,8 +239,6 @@ namespace detail { public: constexpr static uint8_t alt_num = sizeof...(As) + 1; - // constexpr static uint8_t switch_size = power_2_ceiling(alt_num); - // Default constructor initializes the first alternative with default constructor EnumBase() : _index {0} { new (reinterpret_cast(&_storage)) A {}; @@ -410,7 +408,7 @@ namespace detail { private: template - struct AltIndex: Find>::template Binded, A, As...> {}; + using AltIndex = Find>::template Binded, A, As...>; // Assume that the index is altready bounded template diff --git a/include/efp/maybe.hpp b/include/efp/maybe.hpp index 7c8e9e4..d6d04a5 100644 --- a/include/efp/maybe.hpp +++ b/include/efp/maybe.hpp @@ -6,12 +6,22 @@ #include "efp/trait.hpp" namespace efp { + struct Nothing {}; constexpr Nothing nothing; // Specialization of Enum for Maybe +template +using Maybe = Enum; + +template +struct IsMaybe: False {}; + +template +struct IsMaybe>: True {}; + template class Enum: public detail::EnumBase { public: @@ -44,22 +54,44 @@ class Enum: public detail::EnumBase { } template - auto fmap(const F& f) -> Enum> { + static Enum pure(const A& a) { + return a; + } + + template + auto fmap(const F& f) -> Enum> const { if (has_value()) return f(value()); else return nothing; } -}; -template -using Maybe = Enum; + template + auto ap(const Enum& mf) -> Enum> const { + if (has_value() && mf.has_value()) + return mf.value()(value()); + else + return nothing; + } -template -struct IsMaybe: False {}; + template + auto bind(const F& f) + -> EnableIf>::value, InvokeResult> const { + if (has_value()) + return f(value()); + else + return nothing; + } -template -struct IsMaybe>: True {}; + template + auto operator>>=(const F& f) + -> EnableIf>::value, InvokeResult> const { + if (has_value()) + return f(value()); + else + return nothing; + } +}; // Element specializetion for Maybe template @@ -102,15 +134,6 @@ auto bind(const Maybe& ma, const F& f) return nothing; } -template -auto operator>>=(const Maybe& ma, const F& f) - -> EnableIf>::value, InvokeResult> { - if (ma) - return f(ma.value()); - else - return nothing; -} - } // namespace efp #endif \ No newline at end of file diff --git a/include/efp/meta.hpp b/include/efp/meta.hpp index e2f7f4f..6e531f7 100644 --- a/include/efp/meta.hpp +++ b/include/efp/meta.hpp @@ -820,24 +820,24 @@ constexpr A _product(const A (&as)[n]) { } // All -// ! Deprecated because of performance issue. Use foldl instead +// ! Not suitable for library implementation because of compile-time performance issue template -struct All: Bool<_all({A::value, As::value...})> {}; +using All = Bool<_all({A::value, As::value...})>; // Any -// ! Deprecated because of performance issue. Use foldl instead +// ! Not suitable for library implementation because of compile-time performance issue template -struct Any: Bool<_any({A::value, As::value...})> {}; +using Any = Bool<_any({A::value, As::value...})>; // Minimum -// ! Deprecated because of performance issue. Use foldl instead +// ! Not suitable for library implementation because of compile-time performance issue template -struct Minimum: CtConst {}; +using Mininum = CtConst; // Maximum -// ! Deprecated because of performance issue. Use foldl instead +// ! Not suitable for library implementation because of compile-time performance issue template -struct Maximum: CtConst {}; +using Maximum = CtConst; // Common template diff --git a/test/efp/enum_test.hpp b/test/efp/enum_test.hpp index bf018c3..484e799 100644 --- a/test/efp/enum_test.hpp +++ b/test/efp/enum_test.hpp @@ -369,6 +369,7 @@ TEST_CASE("enum_match") { // ! Sould be failed to get compiled and show static assert message on top // a.match([&](int x) { b += 1; }, [&](double _) { b += 1; }); // a.match([&](int x) { b += 1; }, [&](False _) {}, [&]() {}); + // a.match([&]() {}, [&](int x) { b += 1; }); CHECK(b == 0.); }