From b6b01636f5af28134ef610659ce4333a014554f3 Mon Sep 17 00:00:00 2001 From: Mars Date: Wed, 7 May 2025 02:13:52 -0400 Subject: [PATCH] that looks pretty good i think --- include/argparse.hpp | 3 +- include/matchit.hpp | 875 ++++++++++++++++++--------------------- src/core/system_data.cpp | 17 +- src/os/windows.cpp | 3 +- src/ui/ui.cpp | 60 +-- src/util/logging.hpp | 3 - 6 files changed, 458 insertions(+), 503 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index c2d2e1b..add2589 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -1701,8 +1701,7 @@ namespace argparse { } if (m_is_optional) { - // TODO: check if an implicit value was programmed for this argument - if (!m_is_used && !m_default_value.has_value() && m_is_required) + if (!m_is_used && !m_default_value.has_value() && !m_implicit_value.has_value() && m_is_required) return Err(DracError(DracErrorCode::InvalidArgument, std::format("Required argument '{}' was not provided", m_names[0]))); if (m_is_used && m_is_required && m_values.empty()) diff --git a/include/matchit.hpp b/include/matchit.hpp index 9badaf6..ed34766 100644 --- a/include/matchit.hpp +++ b/include/matchit.hpp @@ -3,18 +3,23 @@ * Distributed Under The Apache-2.0 License */ -#ifndef MATCHIT_H -#define MATCHIT_H +#pragma once -#ifndef MATCHIT_CORE_H - #define MATCHIT_CORE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include - #include - #include - #include +#include "src/util/defs.hpp" +// NOLINTBEGIN(readability-identifier-*, cppcoreguidelines-special-member-functions) namespace matchit { - // NOLINTBEGIN(*-identifier-naming) namespace impl { template class ValueType { @@ -29,7 +34,7 @@ namespace matchit { }; template - constexpr auto matchPatterns(Value&& value, const Patterns&... patterns); + constexpr fn matchPatterns(Value&& value, const Patterns&... patterns); template class MatchHelper { @@ -42,36 +47,27 @@ namespace matchit { template constexpr explicit MatchHelper(V&& value) : mValue { std::forward(value) } {} + template - constexpr auto operator()(const PatternPair&... patterns) { + constexpr fn operator()(const PatternPair&... patterns) { return matchPatterns(std::forward(mValue), patterns...); } + + MatchHelper(const MatchHelper&) = delete; + MatchHelper(MatchHelper&&) = delete; }; template - constexpr auto match(Value&& value) { + constexpr fn match(Value&& value) { return MatchHelper { std::forward(value) }; } template - constexpr auto match(First&& first, Values&&... values) { + constexpr fn match(First&& first, Values&&... values) { auto result = std::forward_as_tuple(std::forward(first), std::forward(values)...); return MatchHelper { std::forward(result) }; } - } // namespace impl - // export symbols - using impl::match; - -} // namespace matchit -#endif // MATCHIT_CORE_H -#ifndef MATCHIT_EXPRESSION_H - #define MATCHIT_EXPRESSION_H - - #include - -namespace matchit { - namespace impl { template class Nullary : public T { public: @@ -79,29 +75,28 @@ namespace matchit { }; template - constexpr auto nullary(const T& t) { + constexpr fn nullary(const T& t) { return Nullary { t }; } template class Id; template - constexpr auto expr(Id& id) { + constexpr fn expr(Id& id) { return nullary([&] { return *id; }); } template - constexpr auto expr(const T& v) { + constexpr fn expr(const T& v) { return nullary([&] { return v; }); } template - constexpr auto toNullary(T&& v) { - if constexpr (std::is_invocable_v>) { - return v; - } else { - return expr(v); - } + constexpr fn toNullary(T&& v) { + if constexpr (std::is_invocable_v>) + return std::forward(v); + else + return expr(std::forward(v)); } // for constant @@ -109,7 +104,7 @@ namespace matchit { class EvalTraits { public: template - constexpr static decltype(auto) evalImpl(const T& v, const Args&...) { + constexpr static fn evalImpl(const T& v, const Args&... /*unused*/) -> decltype(auto) { return v; } }; @@ -117,7 +112,7 @@ namespace matchit { template class EvalTraits> { public: - constexpr static decltype(auto) evalImpl(const Nullary& e) { + constexpr static fn evalImpl(const Nullary& e) -> decltype(auto) { return e(); } }; @@ -126,8 +121,8 @@ namespace matchit { template class EvalTraits> { public: - constexpr static decltype(auto) evalImpl(const Id& id) { - return *const_cast&>(id); + constexpr static fn evalImpl(const Id& id) -> decltype(auto) { + return *id; } }; @@ -142,7 +137,7 @@ namespace matchit { class EvalTraits> { public: template - constexpr static decltype(auto) evalImpl(const Unary& e, const Arg& arg) { + constexpr static fn evalImpl(const Unary& e, const Arg& arg) -> decltype(auto) { return e(arg); } }; @@ -152,13 +147,13 @@ namespace matchit { class EvalTraits { public: template - constexpr static decltype(auto) evalImpl(const Wildcard&, const Arg& arg) { + constexpr static fn evalImpl(const Wildcard& /*unused*/, const Arg& arg) -> decltype(auto) { return arg; } }; template - constexpr decltype(auto) evaluate_(const T& t, const Args&... args) { + constexpr fn evaluate_(const T& t, const Args&... args) -> decltype(auto) { return EvalTraits::evalImpl(t, args...); } @@ -172,25 +167,29 @@ namespace matchit { class IsNullaryOrId> : public std::true_type {}; template - constexpr auto isNullaryOrIdV = IsNullaryOrId>::value; + constexpr bool isNullaryOrIdV = IsNullaryOrId>::value; - #define UN_OP_FOR_NULLARY(op) \ - template , bool> = true> \ - constexpr auto operator op(T const& t) { \ - return nullary([&] { return op evaluate_(t); }); \ - } +#define UN_OP_FOR_NULLARY(op) \ + template \ + constexpr fn operator op(T const& t) \ + requires isNullaryOrIdV \ + { \ + return nullary([&] { return op evaluate_(t); }); \ + } - #define BIN_OP_FOR_NULLARY(op) \ - template || isNullaryOrIdV, bool> = true> \ - constexpr auto operator op(T const& t, U const& u) { \ - return nullary([&] { return evaluate_(t) op evaluate_(u); }); \ - } +#define BIN_OP_FOR_NULLARY(op) \ + template \ + constexpr fn operator op(T const& t, U const& u) \ + requires isNullaryOrIdV || isNullaryOrIdV \ + { \ + return nullary([&] { return evaluate_(t) op evaluate_(u); }); \ + } // ADL will find these operators. UN_OP_FOR_NULLARY(!) UN_OP_FOR_NULLARY(-) - #undef UN_OP_FOR_NULLARY +#undef UN_OP_FOR_NULLARY BIN_OP_FOR_NULLARY(+) BIN_OP_FOR_NULLARY(-) @@ -207,7 +206,7 @@ namespace matchit { BIN_OP_FOR_NULLARY(&&) BIN_OP_FOR_NULLARY(^) - #undef BIN_OP_FOR_NULLARY +#undef BIN_OP_FOR_NULLARY // Unary template @@ -220,30 +219,34 @@ namespace matchit { class IsUnaryOrWildcard> : public std::true_type {}; template - constexpr auto isUnaryOrWildcardV = IsUnaryOrWildcard>::value; + constexpr bool isUnaryOrWildcardV = IsUnaryOrWildcard>::value; // unary is an alias of meet. template - constexpr auto unary(T&& t) { + constexpr fn unary(T&& t) { return meet(std::forward(t)); } - #define UN_OP_FOR_UNARY(op) \ - template , bool> = true> \ - constexpr auto operator op(T const& t) { \ - return unary([&](auto&& arg) constexpr { return op evaluate_(t, arg); }); \ - } +#define UN_OP_FOR_UNARY(op) \ + template \ + constexpr fn operator op(T const& t) \ + requires isUnaryOrWildcardV \ + { \ + return unary([&](auto&& arg) constexpr { return op evaluate_(t, arg); }); \ + } - #define BIN_OP_FOR_UNARY(op) \ - template || isUnaryOrWildcardV, bool> = true> \ - constexpr auto operator op(T const& t, U const& u) { \ - return unary([&](auto&& arg) constexpr { return evaluate_(t, arg) op evaluate_(u, arg); }); \ - } +#define BIN_OP_FOR_UNARY(op) \ + template \ + constexpr fn operator op(T const& t, U const& u) \ + requires isUnaryOrWildcardV || isUnaryOrWildcardV \ + { \ + return unary([&](auto&& arg) constexpr { return evaluate_(t, arg) op evaluate_(u, arg); }); \ + } UN_OP_FOR_UNARY(!) UN_OP_FOR_UNARY(-) - #undef UN_OP_FOR_UNARY +#undef UN_OP_FOR_UNARY BIN_OP_FOR_UNARY(+) BIN_OP_FOR_UNARY(-) @@ -260,28 +263,8 @@ namespace matchit { BIN_OP_FOR_UNARY(&&) BIN_OP_FOR_UNARY(^) - #undef BIN_OP_FOR_UNARY +#undef BIN_OP_FOR_UNARY - } // namespace impl - using impl::expr; -} // namespace matchit - -#endif // MATCHIT_EXPRESSION_H -#ifndef MATCHIT_PATTERNS_H - #define MATCHIT_PATTERNS_H - - #include - #include - #include - #include - #include - - #if !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS) - #define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 0 - #endif // !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS) - -namespace matchit { - namespace impl { template class Subrange { I mBegin; @@ -294,25 +277,31 @@ namespace matchit { constexpr Subrange(const Subrange& other) : mBegin { other.begin() }, mEnd { other.end() } {} - Subrange& operator=(const Subrange& other) { + fn operator=(const Subrange& other)->Subrange& { + if (this == &other) + return *this; + mBegin = other.begin(); mEnd = other.end(); + return *this; } - size_t size() const { + [[nodiscard]] fn size() const -> size_t { return static_cast(std::distance(mBegin, mEnd)); } - auto begin() const { + + [[nodiscard]] fn begin() const { return mBegin; } - auto end() const { + + [[nodiscard]] fn end() const { return mEnd; } }; template - constexpr auto makeSubrange(I begin, S end) { + constexpr fn makeSubrange(I begin, S end) { return Subrange { begin, end }; } @@ -344,20 +333,20 @@ namespace matchit { Subrange::beginT, typename IterUnderlyingType::endT>; template - bool operator==(const Subrange& lhs, const Subrange& rhs) { + fn operator==(const Subrange& lhs, const Subrange& rhs)->bool { using std::operator==; return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } template - auto operator==(const std::pair& t, const std::pair& u) { + constexpr fn operator==(const std::pair& t, const std::pair& u) { return t.first == u.first && t.second == u.second; } template class WithinTypes { public: - constexpr static auto value = (std::is_same_v || ...); + constexpr static bool value = (std::is_same_v || ...); }; template @@ -365,7 +354,7 @@ namespace matchit { template class PrependUnique> { - constexpr static auto unique = !WithinTypes::value; + constexpr static bool unique = !WithinTypes::value; public: using type = std::conditional_t, std::tuple>; @@ -399,50 +388,49 @@ namespace matchit { namespace detail { template - constexpr decltype(auto) subtupleImpl(Tuple&& t, std::index_sequence) { + constexpr fn subtupleImpl(Tuple&& t, std::index_sequence /*unused*/) -> decltype(auto) { return std::forward_as_tuple(get(std::forward(t))...); } } // namespace detail // [start, end) template - constexpr decltype(auto) subtuple(Tuple&& t) { - constexpr auto tupleSize = std::tuple_size_v>; + constexpr fn subtuple(Tuple&& t) -> decltype(auto) { + constexpr size_t tupleSize = std::tuple_size_v>; static_assert(start <= end); static_assert(end <= tupleSize); return detail::subtupleImpl(std::forward(t), std::make_index_sequence {}); } template - constexpr decltype(auto) drop(Tuple&& t) { - constexpr auto tupleSize = std::tuple_size_v>; + constexpr fn drop(Tuple&& t) -> decltype(auto) { + constexpr size_t tupleSize = std::tuple_size_v>; static_assert(start <= tupleSize); return subtuple(std::forward(t)); } template - constexpr decltype(auto) take(Tuple&& t) { - constexpr auto tupleSize = std::tuple_size_v>; + constexpr fn take(Tuple&& t) -> decltype(auto) { + constexpr size_t tupleSize = std::tuple_size_v>; static_assert(len <= tupleSize); return subtuple<0, len>(std::forward(t)); } template - constexpr decltype(auto) apply_(F&& f, Tuple&& t) { + constexpr fn apply_(F&& f, Tuple&& t) -> decltype(auto) { return std::apply(std::forward(f), drop<0>(std::forward(t))); } // as constexpr template - constexpr std::invoke_result_t - invoke_(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v) { + constexpr fn invoke_(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v) -> std::invoke_result_t { return std::apply(std::forward(f), std::forward_as_tuple(std::forward(args)...)); } template struct decayArray { private: - typedef std::remove_reference_t U; + using U = std::remove_reference_t; public: using type = std::conditional_t, std::remove_extent_t*, T>; @@ -451,8 +439,8 @@ namespace matchit { template using decayArrayT = typename decayArray::type; - static_assert(std::is_same_v, int32_t*>); - static_assert(std::is_same_v, const int32_t*>); + static_assert(std::is_same_v, int32_t*>); + static_assert(std::is_same_v, const int32_t*>); static_assert(std::is_same_v, const int32_t&>); template @@ -460,6 +448,7 @@ namespace matchit { using type = std::conditional_t, T, std::add_pointer_t>>>; }; + template using AddConstToPointerT = typename AddConstToPointer::type; @@ -478,8 +467,10 @@ namespace matchit { using RetType = std::common_type_t; }; - enum class IdProcess : int32_t { kCANCEL, - kCONFIRM }; + enum class IdProcess : uint8_t { + kCANCEL, + kCONFIRM, + }; template constexpr void processId(const Pattern& pattern, int32_t depth, IdProcess idProcess) { @@ -507,11 +498,11 @@ namespace matchit { public: template - constexpr void emplace_back(T&& t) { + constexpr fn emplace_back(T&& t) -> void { mMemHolder[mSize] = std::forward(t); ++mSize; } - constexpr auto back() -> ElementT& { + constexpr fn back() -> ElementT& { return mMemHolder[mSize - 1]; } }; @@ -529,7 +520,7 @@ namespace matchit { }; template - constexpr auto matchPattern(Value&& value, const Pattern& pattern, int32_t depth, ConctextT& context) { + constexpr fn matchPattern(Value&& value, const Pattern& pattern, int32_t depth, ConctextT& context) { const auto result = PatternTraits::matchPatternImpl(std::forward(value), pattern, depth, context); const auto process = result ? IdProcess::kCONFIRM : IdProcess::kCANCEL; processId(pattern, depth, process); @@ -544,16 +535,18 @@ namespace matchit { constexpr PatternPair(const Pattern& pattern, const Func& func) : mPattern { pattern }, mHandler { func } {} + template - constexpr bool matchValue(Value&& value, ContextT& context) const { + constexpr fn matchValue(Value&& value, ContextT& context) const -> bool { return matchPattern(std::forward(value), mPattern, /*depth*/ 0, context); } - constexpr auto execute() const { + + constexpr fn execute() const { return mHandler(); } private: - const Pattern mPattern; + Pattern mPattern; std::conditional_t, const Func&, const Func> mHandler; }; @@ -567,8 +560,8 @@ namespace matchit { }; template - constexpr auto when(Pred&& pred) { - auto p = toNullary(pred); + constexpr fn when(Pred&& pred) { + auto p = toNullary(std::forward(pred)); return When { p }; } @@ -577,25 +570,27 @@ namespace matchit { public: constexpr explicit PatternHelper(const Pattern& pattern) : mPattern { pattern } {} + template - constexpr auto operator=(Func&& func) { - auto f = toNullary(func); + constexpr fn operator=(Func&& func) { // NOLINT(misc-unconventional-assign-operator, cppcoreguidelines-c-copy-assignment-signature) + auto f = toNullary(std::forward(func)); return PatternPair { mPattern, f }; } + template - constexpr auto operator|(const When& w) { + constexpr fn operator|(const When& w) { return PatternHelper>(PostCheck(mPattern, w.mPred)); } private: - const Pattern mPattern; + Pattern mPattern; }; template class Ds; template - constexpr auto ds(const Patterns&... patterns) -> Ds; + constexpr fn ds(const Patterns&... patterns) -> Ds; template class OooBinder; @@ -604,17 +599,17 @@ namespace matchit { public: template // ReSharper disable once CppDFAUnreachableFunctionCall - constexpr auto operator|(const Pattern& p) const { + constexpr fn operator|(const Pattern& p) const->PatternHelper { return PatternHelper { p }; } template - constexpr auto operator|(const T* p) const { + constexpr fn operator|(const T* p) const->PatternHelper { return PatternHelper { p }; } template - constexpr auto operator|(const OooBinder& p) const { + constexpr fn operator|(const OooBinder& p) const->PatternHelper { return operator|(ds(p)); } }; @@ -627,14 +622,13 @@ namespace matchit { template using AppResultTuple = std::tuple<>; - constexpr static auto nbIdV = 0; + constexpr static int nbIdV = 0; template - constexpr static auto - matchPatternImpl(Value&& value, const Pattern& pattern, int32_t /* depth */, ContextT& /*context*/) { + constexpr static fn matchPatternImpl(Value&& value, const Pattern& pattern, int32_t /* depth */, ContextT& /*context*/) -> bool { return pattern == std::forward(value); } - constexpr static void processIdImpl(const Pattern&, int32_t /*depth*/, IdProcess) {} + constexpr static void processIdImpl(const Pattern& /*unused*/, int32_t /*depth*/, IdProcess /*unused*/) {} }; class Wildcard {}; @@ -649,13 +643,13 @@ namespace matchit { template using AppResultTuple = std::tuple<>; - constexpr static auto nbIdV = 0; + constexpr static int nbIdV = 0; template - constexpr static bool matchPatternImpl(Value&&, const Pattern&, int32_t, ContextT&) { + constexpr static fn matchPatternImpl(Value&& /*unused*/, const Pattern& /*unused*/, int32_t /*unused*/, ContextT& /*unused*/) -> bool { return true; } - constexpr static void processIdImpl(const Pattern&, int32_t /*depth*/, IdProcess) {} + constexpr static fn processIdImpl(const Pattern& /*unused*/, int32_t /*depth*/, IdProcess /*unused*/) -> void {} }; template @@ -663,7 +657,7 @@ namespace matchit { public: constexpr explicit Or(const Patterns&... patterns) : mPatterns { patterns... } {} - constexpr const auto& patterns() const { + constexpr fn patterns() const -> const std::tuple...>& { return mPatterns; } @@ -672,7 +666,7 @@ namespace matchit { }; template - constexpr auto or_(const Patterns&... patterns) { + constexpr fn or_(const Patterns&... patterns) -> Or { return Or { patterns... }; } @@ -683,12 +677,11 @@ namespace matchit { using AppResultTuple = decltype(std::tuple_cat(typename PatternTraits::template AppResultTuple {}...)); - constexpr static auto nbIdV = (PatternTraits::nbIdV + ... + 0); + constexpr static int nbIdV = (PatternTraits::nbIdV + ... + 0); template - constexpr static auto - matchPatternImpl(Value&& value, const Or& orPat, int32_t depth, ContextT& context) { - constexpr auto patSize = sizeof...(Patterns); + constexpr static fn matchPatternImpl(Value&& value, const Or& orPat, int32_t depth, ContextT& context) -> bool { + constexpr uint64_t patSize = sizeof...(Patterns); return std::apply( [&value, depth, &context](const auto&... patterns) { return (matchPattern(value, patterns, depth + 1, context) || ...); @@ -712,7 +705,7 @@ namespace matchit { }; template - constexpr auto meet(const Pred& pred) { + constexpr fn meet(const Pred& pred) -> Meet { return Meet { pred }; } @@ -722,38 +715,39 @@ namespace matchit { template using AppResultTuple = std::tuple<>; - constexpr static auto nbIdV = 0; + constexpr static int nbIdV = 0; template - constexpr static auto matchPatternImpl(Value&& value, const Meet& meetPat, int32_t /* depth */, ContextT&) { + constexpr static fn matchPatternImpl(Value&& value, const Meet& meetPat, int32_t /* depth */, ContextT& /*unused*/) -> bool { return meetPat(std::forward(value)); } - constexpr static void processIdImpl(const Meet&, int32_t /*depth*/, IdProcess) {} + + constexpr static fn processIdImpl(const Meet& /*unused*/, int32_t /*depth*/, IdProcess /*unused*/) -> void {} }; template class App { public: - constexpr App(Unary&& unary, const Pattern& pattern) - : mUnary { std::forward(unary) }, mPattern { pattern } {} - constexpr const auto& unary() const { + constexpr App(Unary&& unary, const Pattern& pattern) : mUnary { std::move(unary) }, mPattern { pattern } {} + + [[nodiscard]] constexpr fn unary() const -> const Unary& { return mUnary; } - constexpr const auto& pattern() const { + [[nodiscard]] constexpr fn pattern() const -> const InternalPatternT& { return mPattern; } private: - const Unary mUnary; - const InternalPatternT mPattern; + std::decay_t mUnary; + InternalPatternT mPattern; }; template - constexpr auto app(Unary&& unary, const Pattern& pattern) { - return App { std::forward(unary), pattern }; + constexpr fn app(Unary&& unary, const Pattern& pattern) -> App { + return { std::forward(unary), pattern }; } - constexpr auto y = 1; + constexpr int y = 1; static_assert(std::holds_alternative(std::variant { &y })); template @@ -765,11 +759,7 @@ namespace matchit { // support constexpr. template using AppResultCurTuple = std::conditional_t< - std::is_lvalue_reference_v> - #if NO_SCALAR_REFERENCES_USED_IN_PATTERNS - || std::is_scalar_v> - #endif // NO_SCALAR_REFERENCES_USED_IN_PATTERNS - , + std::is_lvalue_reference_v> || std::is_scalar_v>, std::tuple<>, std::tuple>>>; @@ -779,22 +769,22 @@ namespace matchit { std::declval::template AppResultTuple>>() )); - constexpr static auto nbIdV = PatternTraits::nbIdV; + constexpr static int nbIdV = PatternTraits::nbIdV; template - constexpr static auto - matchPatternImpl(Value&& value, const App& appPat, const int32_t depth, ContextT& context) { + constexpr static fn matchPatternImpl(Value&& value, const App& appPat, const int32_t depth, ContextT& context) -> bool { if constexpr (std::is_same_v, std::tuple<>>) { return matchPattern( - std::forward>(invoke_(appPat.unary(), value)), appPat.pattern(), depth + 1, context + std::forward>(invoke_(appPat.unary(), std::forward(value))), appPat.pattern(), depth + 1, context ); } else { - context.emplace_back(invoke_(appPat.unary(), value)); + context.emplace_back(invoke_(appPat.unary(), std::forward(value))); decltype(auto) result = get>>(context.back()); - return matchPattern(std::forward>(result), appPat.pattern(), depth + 1, context); + return matchPattern(std::forward(result), appPat.pattern(), depth + 1, context); } } - constexpr static void processIdImpl(const App& appPat, int32_t depth, IdProcess idProcess) { + + constexpr static fn processIdImpl(const App& appPat, int32_t depth, IdProcess idProcess) -> void { return processId(appPat.pattern(), depth, idProcess); } }; @@ -804,7 +794,8 @@ namespace matchit { public: constexpr explicit And(const Patterns&... patterns) : mPatterns { patterns... } {} - constexpr const auto& patterns() const { + + constexpr fn patterns() const -> const std::tuple...>& { return mPatterns; } @@ -813,8 +804,8 @@ namespace matchit { }; template - constexpr auto and_(const Patterns&... patterns) { - return And { patterns... }; + constexpr fn and_(const Patterns&... patterns) -> And { + return { patterns... }; } template @@ -823,7 +814,7 @@ namespace matchit { template class NbIdInTuple> { public: - constexpr static auto nbIdV = (PatternTraits>::nbIdV + ... + 0); + constexpr static int nbIdV = (PatternTraits>::nbIdV + ... + 0); }; template @@ -833,13 +824,12 @@ namespace matchit { using AppResultTuple = decltype(std::tuple_cat(std::declval::template AppResultTuple>()...)); - constexpr static auto nbIdV = (PatternTraits::nbIdV + ... + 0); + constexpr static int nbIdV = (PatternTraits::nbIdV + ... + 0); template - constexpr static auto - matchPatternImpl(Value&& value, const And& andPat, int32_t depth, ContextT& context) { - constexpr auto patSize = sizeof...(Patterns); - const auto exceptLast = std::apply( + constexpr static fn matchPatternImpl(Value&& value, const And& andPat, int32_t depth, ContextT& context) -> bool { + constexpr uint64_t patSize = sizeof...(Patterns); + const auto exceptLast = std::apply( [&value, depth, &context](const auto&... patterns) { return (matchPattern(value, patterns, depth + 1, context) && ...); }, @@ -867,7 +857,7 @@ namespace matchit { public: explicit Not(const Pattern& pattern) : mPattern { pattern } {} - const auto& pattern() const { + [[nodiscard]] constexpr fn pattern() const -> const InternalPatternT& { return mPattern; } @@ -876,8 +866,8 @@ namespace matchit { }; template - constexpr auto not_(const Pattern& pattern) { - return Not { pattern }; + constexpr fn not_(const Pattern& pattern) -> Not { + return { pattern }; } template @@ -886,13 +876,13 @@ namespace matchit { template using AppResultTuple = typename PatternTraits::template AppResultTuple; - constexpr static auto nbIdV = PatternTraits::nbIdV; + constexpr static int nbIdV = PatternTraits::nbIdV; template - constexpr static auto - matchPatternImpl(Value&& value, const Not& notPat, const int32_t depth, ContextT& context) { + constexpr static fn matchPatternImpl(Value&& value, const Not& notPat, const int32_t depth, ContextT& context) -> bool { return !matchPattern(std::forward(value), notPat.pattern(), depth + 1, context); } + constexpr static void processIdImpl(const Not& notPat, int32_t depth, IdProcess idProcess) { processId(notPat.pattern(), depth, idProcess); } @@ -917,12 +907,8 @@ namespace matchit { const std::remove_reference_t*>>>>; template - struct StorePointer< - Type, - Value, - std::void_t&>() = &std::declval())>> - : std::is_reference // need to double check this condition. to loosen it. - {}; + struct StorePointer&>() = &std::declval())>> + : std::is_reference {}; static_assert(!StorePointer::value); static_assert(StorePointer::value); @@ -937,8 +923,8 @@ namespace matchit { }; template - constexpr auto overload(Ts&&... ts) { - return Overload { ts... }; + constexpr fn overload(Ts&&... ts) -> Overload { + return { std::forward(ts)... }; } template @@ -949,37 +935,32 @@ namespace matchit { template class IdTraits { public: - constexpr static auto - #if defined(__has_feature) - #if __has_feature(address_sanitizer) - __attribute__((no_sanitize_address)) - #endif - #endif - equal(Type const& lhs, Type const& rhs) { + constexpr static fn equal(const Type& lhs, const Type& rhs) -> bool { return lhs == rhs; } }; template class IdBlockBase { - int32_t mDepth; + int32_t mDepth {}; - protected: - ValueVariant mVariant; + private: + ValueVariant mVariant {}; public: - constexpr IdBlockBase() - : mDepth {}, mVariant {} {} + constexpr IdBlockBase() = default; - constexpr auto& variant() { + [[nodiscard]] constexpr fn variant() -> ValueVariant& { return mVariant; } + constexpr void reset(const int32_t depth) { if (mDepth - depth >= 0) { mVariant = {}; mDepth = depth; } } + constexpr void confirm(const int32_t depth) { if (mDepth > depth || mDepth == 0) { assert(depth == mDepth - 1 || depth == mDepth || mDepth == 0); @@ -993,22 +974,21 @@ namespace matchit { template class IdBlock : public IdBlockBase { public: - constexpr auto hasValue() const { + [[nodiscard]] constexpr fn hasValue() const -> bool { return std::visit( overload( [](const Type&) { return true; }, [](const Type*) { return true; }, - // [](Type *) - // { return true; }, [](const std::monostate&) { return false; } ), IdBlockBase::mVariant ); } - constexpr decltype(auto) get() const { + + [[nodiscard]] constexpr fn get() const -> decltype(auto) { return std::visit( overload( - [](const Type& v) -> const Type& { return v; }, + [](const Type& v) -> Type { return v; }, [](const Type* p) -> const Type& { return *p; }, [](Type* p) -> const Type& { return *p; }, [](const std::monostate&) -> const Type& { throw std::logic_error("invalid state!"); } @@ -1024,14 +1004,14 @@ namespace matchit { template class IdBlock : public IdBlockBase { public: - constexpr auto hasValue() const { + [[nodiscard]] constexpr fn hasValue() const -> bool { return std::visit( overload([](Type*) { return true; }, [](const std::monostate&) { return false; }), IdBlockBase::mVariant ); } - constexpr decltype(auto) get() { + [[nodiscard]] constexpr fn get() -> decltype(auto) { return std::visit( overload( [](Type* v) -> Type& { @@ -1050,7 +1030,7 @@ namespace matchit { template class IdBlock : public IdBlockBase { public: - constexpr auto hasValue() const { + [[nodiscard]] constexpr fn hasValue() const -> bool { return std::visit( overload( [](const Type&) { return true; }, [](Type*) { return true; }, [](const std::monostate&) { return false; } @@ -1059,7 +1039,7 @@ namespace matchit { ); } - constexpr decltype(auto) get() { + [[nodiscard]] constexpr fn get() -> decltype(auto) { return std::visit( overload( [](Type& v) -> Type& { return v; }, @@ -1080,13 +1060,14 @@ namespace matchit { class IdUtil { public: template - constexpr static auto bindValue(ValueVariant& v, Value&& value, std::false_type /* StorePointer */) { + constexpr static fn bindValue(ValueVariant& v, Value&& value, std::false_type /* StorePointer */) { // for constexpr v = ValueVariant { std::forward(value) }; } + template - constexpr static auto bindValue(ValueVariant& v, Value&& value, std::true_type /* StorePointer */) { - v = ValueVariant { &value }; + constexpr static fn bindValue(ValueVariant& v, Value&& value, std::true_type /* StorePointer */) { + v = ValueVariant { &std::forward(value) }; } }; @@ -1097,60 +1078,61 @@ namespace matchit { using BlockVT = std::variant; BlockVT mBlock = BlockT {}; - constexpr decltype(auto) internalValue() const { + [[nodiscard]] constexpr fn internalValue() const -> decltype(auto) { return block().get(); } public: constexpr Id() = default; - constexpr Id(const Id& id) { - mBlock = BlockVT { &id.block() }; - } + constexpr Id(const Id& id) : mBlock(BlockVT { &id.block() }) {} // non-const to inform users not to mark Id as const. template - constexpr auto at(Pattern&& pattern) { - return and_(pattern, *this); + constexpr fn at(Pattern&& pattern) -> decltype(auto) { + return and_(std::forward(pattern), *this); } // non-const to inform users not to mark Id as const. - constexpr auto at(const Ooo&) { + constexpr fn at(const Ooo& /*unused*/) -> OooBinder { return OooBinder { *this }; } - constexpr BlockT& block() const { + [[nodiscard]] constexpr fn block() const -> BlockT& { return std::visit( overload([](BlockT& v) -> BlockT& { return v; }, [](BlockT* p) -> BlockT& { return *p; }), - // constexpr does not allow mutable, we use const_cast - // instead. Never declare Id as const. - const_cast(mBlock) + mBlock ); } template - constexpr auto matchValue(Value&& v) const { - if (hasValue()) { + constexpr fn matchValue(Value&& v) const -> bool { + if (hasValue()) return IdTraits>::equal(internalValue(), v); - } + IdUtil::bindValue(block().variant(), std::forward(v), StorePointer {}); return true; } - constexpr void reset(int32_t depth) const { + + constexpr fn reset(int32_t depth) const -> void { return block().reset(depth); } - constexpr void confirm(int32_t depth) const { + + constexpr fn confirm(int32_t depth) const -> void { return block().confirm(depth); } - constexpr bool hasValue() const { + + [[nodiscard]] constexpr fn hasValue() const -> bool { return block().hasValue(); } + // non-const to inform users not to mark Id as const. - constexpr decltype(auto) get() { + [[nodiscard]] constexpr fn get() -> decltype(auto) { return block().get(); } + // non-const to inform users not to mark Id as const. - constexpr decltype(auto) operator*() { + [[nodiscard]] constexpr fn operator*()->decltype(auto) { return get(); } }; @@ -1161,16 +1143,16 @@ namespace matchit { template using AppResultTuple = std::tuple<>; - constexpr static auto nbIdV = true; + constexpr static bool nbIdV = true; template - constexpr static auto matchPatternImpl(Value&& value, const Id& idPat, int32_t /* depth */, ContextT&) { + constexpr static fn matchPatternImpl(Value&& value, const Id& idPat, int32_t /* depth */, ContextT& /*unused*/) -> bool { return idPat.matchValue(std::forward(value)); } - constexpr static void processIdImpl(const Id& idPat, int32_t depth, const IdProcess idProcess) { - switch (idProcess) { - case IdProcess::kCANCEL: idPat.reset(depth); break; + constexpr static fn processIdImpl(const Id& idPat, int32_t depth, const IdProcess idProcess) -> void { + switch (idProcess) { + case IdProcess::kCANCEL: idPat.reset(depth); break; case IdProcess::kCONFIRM: idPat.confirm(depth); break; } } @@ -1181,7 +1163,8 @@ namespace matchit { public: constexpr explicit Ds(const Patterns&... patterns) : mPatterns { patterns... } {} - constexpr const auto& patterns() const { + + [[nodiscard]] constexpr fn patterns() const -> const auto& { return mPatterns; } @@ -1192,7 +1175,7 @@ namespace matchit { }; template - constexpr auto ds(const Patterns&... patterns) -> Ds { + constexpr fn ds(const Patterns&... patterns) -> Ds { return Ds { patterns... }; } @@ -1203,7 +1186,8 @@ namespace matchit { public: explicit OooBinder(const Id& id) : mId { id } {} - decltype(auto) binder() const { + + [[nodiscard]] constexpr fn binder() const -> decltype(auto) { return mId; } }; @@ -1211,7 +1195,7 @@ namespace matchit { class Ooo { public: template - constexpr auto operator()(Id id) const { + constexpr fn operator()(Id id) const->OooBinder { return OooBinder { id }; } }; @@ -1224,13 +1208,14 @@ namespace matchit { template using AppResultTuple = std::tuple<>; - constexpr static auto nbIdV = false; + constexpr static bool nbIdV = false; template - constexpr static auto matchPatternImpl(Value&&, Ooo, int32_t /*depth*/, ContextT&) { + constexpr static fn matchPatternImpl(Value&& /*unused*/, Ooo /*unused*/, int32_t /*depth*/, ContextT& /*unused*/) -> bool { return true; } - constexpr static void processIdImpl(Ooo, int32_t /*depth*/, IdProcess) {} + + constexpr static fn processIdImpl(Ooo /*unused*/, int32_t /*depth*/, IdProcess /*unused*/) -> void {} }; template @@ -1239,14 +1224,14 @@ namespace matchit { template using AppResultTuple = typename PatternTraits::template AppResultTuple; - constexpr static auto nbIdV = PatternTraits::nbIdV; + constexpr static bool nbIdV = PatternTraits::nbIdV; template - constexpr static auto - matchPatternImpl(Value&& value, const OooBinder& oooBinderPat, const int32_t depth, ContextT& context) { + constexpr static fn matchPatternImpl(Value&& value, const OooBinder& oooBinderPat, const int32_t depth, ContextT& context) { return matchPattern(std::forward(value), oooBinderPat.binder(), depth + 1, context); } - constexpr static void processIdImpl(const OooBinder& oooBinderPat, int32_t depth, IdProcess idProcess) { + + constexpr static fn processIdImpl(const OooBinder& oooBinderPat, int32_t depth, IdProcess idProcess) -> void { processId(oooBinderPat.binder(), depth, idProcess); } }; @@ -1264,23 +1249,23 @@ namespace matchit { class IsOooBinder> : public std::true_type {}; template - constexpr auto isOooBinderV = IsOooBinder>::value; + constexpr bool isOooBinderV = IsOooBinder>::value; template - constexpr auto isOooOrBinderV = IsOoo>::value || isOooBinderV; + constexpr bool isOooOrBinderV = IsOoo>::value || isOooBinderV; template - constexpr auto nbOooOrBinderV = ((isOooOrBinderV ? 1 : 0) + ... + 0); + constexpr size_t nbOooOrBinderV = ((isOooOrBinderV ? 1 : 0) + ... + 0); static_assert(nbOooOrBinderV == 2); template - constexpr size_t findOooIdxImpl(std::index_sequence) { + constexpr fn findOooIdxImpl(std::index_sequence /*unused*/) -> std::size_t { return ((isOooOrBinderV(std::declval()))> ? I : 0) + ...); } template - constexpr size_t findOooIdx() { + constexpr fn findOooIdx() -> std::size_t { return findOooIdxImpl(std::make_index_sequence>> {}); } @@ -1290,71 +1275,47 @@ namespace matchit { static_assert(findOooIdx>() == 1); using std::get; - template < - std::size_t valueStartIdx, - std::size_t patternStartIdx, - std::size_t... I, - typename ValueTuple, - typename PatternTuple, - typename ContextT> - constexpr decltype(auto) - matchPatternMultipleImpl(ValueTuple&& valueTuple, PatternTuple&& patternTuple, const int32_t depth, ContextT& context, std::index_sequence) { - const auto func = [&](T&& value, auto&& pattern) { - return matchPattern(std::forward(value), pattern, depth + 1, context); - }; + + template + constexpr fn matchPatternMultipleImpl(ValueTuple&& valueTuple, PatternTuple&& patternTuple, const int32_t depth, ContextT& context, std::index_sequence /*unused*/) -> decltype(auto) { + const fn func = [&](T&& value, auto&& pattern) { return matchPattern(std::forward(value), pattern, depth + 1, context); }; + static_cast(func); - return ( - func( - get(std::forward(valueTuple)), std::get(patternTuple) - ) && - ... - ); + + return (func(get(std::forward(valueTuple)), std::get(patternTuple)) && ...); } - template < - std::size_t valueStartIdx, - std::size_t patternStartIdx, - std::size_t size, - typename ValueTuple, - typename PatternTuple, - typename ContextT> - constexpr decltype(auto) - matchPatternMultiple(ValueTuple&& valueTuple, PatternTuple&& patternTuple, int32_t depth, ContextT& context) { + template + constexpr fn matchPatternMultiple(ValueTuple&& valueTuple, PatternTuple&& patternTuple, int32_t depth, ContextT& context) -> decltype(auto) { return matchPatternMultipleImpl( - std::forward(valueTuple), patternTuple, depth, context, std::make_index_sequence {} + std::forward(valueTuple), std::forward(patternTuple), depth, context, std::make_index_sequence {} ); } - template < - std::size_t patternStartIdx, - std::size_t... I, - typename RangeBegin, - typename PatternTuple, - typename ContextT> - constexpr decltype(auto) - matchPatternRangeImpl(RangeBegin&& rangeBegin, PatternTuple&& patternTuple, const int32_t depth, ContextT& context, std::index_sequence) { - const auto func = [&](T&& value, auto&& pattern) { - return matchPattern(std::forward(value), pattern, depth + 1, context); - }; + template + constexpr fn matchPatternRangeImpl(RangeBegin&& rangeBegin, PatternTuple&& patternTuple, const int32_t depth, ContextT& context, std::index_sequence /*unused*/) -> decltype(auto) { + const fn func = [&](T&& value, auto&& pattern) { return matchPattern(std::forward(value), pattern, depth + 1, context); }; + static_cast(func); - // Fix Me, avoid call next from begin every time. - return (func(*std::next(rangeBegin, static_cast(I)), std::get(patternTuple)) && ...); + + auto it = rangeBegin; + + bool result = true; + + ((result = result && func(*it, std::get(patternTuple)), ++it), ...); + + return result; } - template < - std::size_t patternStartIdx, - std::size_t size, - typename ValueRangeBegin, - typename PatternTuple, - typename ContextT> - constexpr decltype(auto) matchPatternRange( + template + constexpr fn matchPatternRange( ValueRangeBegin&& valueRangeBegin, PatternTuple&& patternTuple, int32_t depth, ContextT& context ) { return matchPatternRangeImpl( - valueRangeBegin, patternTuple, depth, context, std::make_index_sequence {} + std::forward(valueRangeBegin), std::forward(patternTuple), depth, context, std::make_index_sequence {} ); } @@ -1369,7 +1330,7 @@ namespace matchit { template class SubTypes { - constexpr static auto tupleSize = std::tuple_size_v>; + constexpr static size_t tupleSize = std::tuple_size_v>; static_assert(start <= end); static_assert(end <= tupleSize); @@ -1382,14 +1343,10 @@ namespace matchit { template using SubTypesT = typename SubTypes::type; - static_assert(std::is_same_v< - std::tuple, - SubTypesT<3, 4, std::tuple>>); + static_assert(std::is_same_v, SubTypesT<3, 4, std::tuple>>); static_assert(std::is_same_v, SubTypesT<0, 1, std::tuple>>); static_assert(std::is_same_v, SubTypesT<1, 1, std::tuple>>); - static_assert(std::is_same_v< - std::tuple, - SubTypesT<2, 4, std::tuple>>); + static_assert(std::is_same_v, SubTypesT<2, 4, std::tuple>>); template class IsArray : public std::false_type {}; @@ -1398,17 +1355,16 @@ namespace matchit { class IsArray> : public std::true_type {}; template - constexpr auto isArrayV = IsArray>::value; + constexpr bool isArrayV = IsArray>::value; template > struct IsTupleLike : std::false_type {}; template - // ReSharper disable once CppUseTypeTraitAlias struct IsTupleLike::value)>> : std::true_type {}; template - constexpr auto isTupleLikeV = IsTupleLike>::value; + constexpr bool isTupleLikeV = IsTupleLike>::value; static_assert(isTupleLikeV>); static_assert(!isTupleLikeV); @@ -1417,20 +1373,18 @@ namespace matchit { struct IsRange : std::false_type {}; template - struct IsRange< - Value, - std::void_t())), decltype(std::end(std::declval()))>> + struct IsRange())), decltype(std::end(std::declval()))>> : std::true_type {}; template - constexpr auto isRangeV = IsRange>::value; + constexpr bool isRangeV = IsRange>::value; static_assert(!isRangeV>); static_assert(isRangeV>); template class PatternTraits> { - constexpr static auto nbOooOrBinder = nbOooOrBinderV; + constexpr static size_t nbOooOrBinder = nbOooOrBinderV; static_assert(nbOooOrBinder == 0 || nbOooOrBinder == 1); public: @@ -1440,8 +1394,7 @@ namespace matchit { template class PairPV, std::tuple> { public: - using type = - decltype(std::tuple_cat(std::declval::template AppResultTuple>()...)); + using type = decltype(std::tuple_cat(std::declval::template AppResultTuple>()...)); }; template @@ -1450,28 +1403,26 @@ namespace matchit { template class AppResultForTupleHelper<0, std::tuple> { public: - using type = - decltype(std::tuple_cat(std::declval::template AppResultTuple>()...) - ); + using type = decltype(std::tuple_cat(std::declval::template AppResultTuple>()...)); }; template class AppResultForTupleHelper<1, std::tuple> { - constexpr static auto idxOoo = findOooIdx::Type>(); + constexpr static size_t idxOoo = findOooIdx::Type>(); using Ps0 = SubTypesT<0, idxOoo, std::tuple>; using Vs0 = SubTypesT<0, idxOoo, std::tuple>; - constexpr static auto isBinder = isOooBinderV>>; + constexpr static bool isBinder = isOooBinderV>>; // <0, ...int32_t> to workaround compile failure for std::tuple<>. using ElemT = std::tuple_element_t<0, std::tuple..., int32_t>>; constexpr static int64_t diff = static_cast(sizeof...(Values) - sizeof...(Patterns)); constexpr static size_t clippedDiff = static_cast(diff > 0 ? diff : 0); using OooResultTuple = std::conditional_t>>, std::tuple<>>; - using FirstHalfTuple = typename PairPV::type; - using Ps1 = SubTypesT>; - constexpr static auto vs1Start = static_cast(static_cast(idxOoo) + 1 + diff); - using Vs1 = SubTypesT>; - using SecondHalfTuple = typename PairPV::type; + using FirstHalfTuple = typename PairPV::type; + using Ps1 = SubTypesT>; + constexpr static size_t vs1Start = static_cast(static_cast(idxOoo) + 1 + diff); + using Vs1 = SubTypesT>; + using SecondHalfTuple = typename PairPV::type; public: using type = decltype(std::tuple_cat( @@ -1482,8 +1433,7 @@ namespace matchit { }; template - using AppResultForTuple = - typename AppResultForTupleHelper(std::declval()))>::type; + using AppResultForTuple = typename AppResultForTupleHelper(std::declval()))>::type; template using RangeTuple = std::conditional_t>, std::tuple<>>; @@ -1491,9 +1441,7 @@ namespace matchit { template using AppResultForRangeType = decltype(std::tuple_cat( std::declval>(), - std::declval< - typename PatternTraits::template AppResultTuple()))>>( - )... + std::declval::template AppResultTuple()))>>()... )); template > @@ -1514,12 +1462,13 @@ namespace matchit { template using AppResultTuple = typename AppResultHelper::type; - constexpr static auto nbIdV = (PatternTraits::nbIdV + ... + 0); + constexpr static size_t nbIdV = (PatternTraits::nbIdV + ... + 0); template - constexpr static auto - matchPatternImpl(ValueTuple&& valueTuple, const Ds& dsPat, int32_t depth, ContextT& context) - -> std::enable_if_t, bool> { + constexpr static fn matchPatternImpl(ValueTuple&& valueTuple, const Ds& dsPat, int32_t depth, ContextT& context) + -> bool + requires(isTupleLikeV) + { if constexpr (nbOooOrBinder == 0) { return std::apply( [&valueTuple, depth, &context](const auto&... patterns) { @@ -1534,16 +1483,16 @@ namespace matchit { dsPat.patterns() ); } else if constexpr (nbOooOrBinder == 1) { - constexpr auto idxOoo = findOooIdx::Type>(); - constexpr auto isBinder = isOooBinderV>>; - constexpr auto isArray = isArrayV; - auto result = - matchPatternMultiple<0, 0, idxOoo>(std::forward(valueTuple), dsPat.patterns(), depth, context); - constexpr auto valLen = std::tuple_size_v>; - constexpr auto patLen = sizeof...(Patterns); + constexpr size_t idxOoo = findOooIdx::Type>(); + constexpr bool isBinder = isOooBinderV>>; + constexpr bool isArray = isArrayV; + auto result = matchPatternMultiple<0, 0, idxOoo>(std::forward(valueTuple), dsPat.patterns(), depth, context); + constexpr size_t valLen = std::tuple_size_v>; + constexpr size_t patLen = sizeof...(Patterns); + if constexpr (isArray) { if constexpr (isBinder) { - const auto rangeSize = static_cast(valLen - (patLen - 1)); + const size_t rangeSize = static_cast(valLen - (patLen - 1)); context.emplace_back(makeSubrange(&valueTuple[idxOoo], &valueTuple[idxOoo] + rangeSize)); using type = decltype(makeSubrange(&valueTuple[idxOoo], &valueTuple[idxOoo] + rangeSize)); result = result && @@ -1552,55 +1501,56 @@ namespace matchit { } else { static_assert(!isBinder); } - return result && - matchPatternMultiple( - std::forward(valueTuple), dsPat.patterns(), depth, context - ); + + return result && matchPatternMultiple(std::forward(valueTuple), dsPat.patterns(), depth, context); } - return; + return false; } template - constexpr static auto - matchPatternImpl(ValueRange&& valueRange, const Ds& dsPat, int32_t depth, ContextT& context) - -> std::enable_if_t && isRangeV, bool> { + constexpr static fn matchPatternImpl(ValueRange&& valueRange, const Ds& dsPat, int32_t depth, ContextT& context) + -> bool + requires(!isTupleLikeV && isRangeV) + { static_assert(nbOooOrBinder == 0 || nbOooOrBinder == 1); - constexpr auto nbPat = sizeof...(Patterns); + constexpr size_t nbPat = sizeof...(Patterns); if constexpr (nbOooOrBinder == 0) { // size mismatch for dynamic array is not an error; - if (valueRange.size() != nbPat) { + if (std::forward(valueRange).size() != nbPat) return false; - } - return matchPatternRange<0, nbPat>(std::begin(valueRange), dsPat.patterns(), depth, context); + + return matchPatternRange<0, nbPat>(std::begin(std::forward(valueRange)), dsPat.patterns(), depth, context); } else if constexpr (nbOooOrBinder == 1) { - if (valueRange.size() < nbPat - 1) { + if (std::forward(valueRange).size() < nbPat - 1) return false; - } - constexpr auto idxOoo = findOooIdx::Type>(); - constexpr auto isBinder = isOooBinderV>>; - auto result = matchPatternRange<0, idxOoo>(std::begin(valueRange), dsPat.patterns(), depth, context); - const auto valLen = valueRange.size(); - constexpr auto patLen = sizeof...(Patterns); - const auto beginOoo = std::next(std::begin(valueRange), idxOoo); + + constexpr auto idxOoo = findOooIdx::Type>(); + constexpr auto isBinder = isOooBinderV>>; + auto result = matchPatternRange<0, idxOoo>(std::begin(std::forward(valueRange)), dsPat.patterns(), depth, context); + const size_t valLen = std::forward(valueRange).size(); + constexpr size_t patLen = sizeof...(Patterns); + const auto beginOoo = std::next(std::begin(std::forward(valueRange)), idxOoo); + if constexpr (isBinder) { - const auto rangeSize = static_cast(valLen - (patLen - 1)); - const auto end = std::next(beginOoo, rangeSize); + const size_t rangeSize = static_cast(valLen - (patLen - 1)); + const auto end = std::next(beginOoo, rangeSize); context.emplace_back(makeSubrange(beginOoo, end)); using type = decltype(makeSubrange(beginOoo, end)); result = result && matchPattern(std::get(context.back()), std::get(dsPat.patterns()), depth, context); } + const auto beginAfterOoo = std::next(beginOoo, static_cast(valLen - patLen + 1)); return result && matchPatternRange(beginAfterOoo, dsPat.patterns(), depth, context); } - return; + return false; } - constexpr static void processIdImpl(const Ds& dsPat, int32_t depth, IdProcess idProcess) { + constexpr static fn processIdImpl(const Ds& dsPat, int32_t depth, IdProcess idProcess) -> void { return std::apply( [depth, idProcess](auto&&... patterns) { return (processId(patterns, depth, idProcess), ...); }, dsPat.patterns() @@ -1608,36 +1558,26 @@ namespace matchit { } }; - static_assert(std::is_same_v< - PatternTraits>>>>::AppResultTuple< - const std::array>, - std::tuple>>); - - static_assert(std::is_same_v< - PatternTraits>, matchit::impl::Id>>::AppResultTuple< - const std::array>, - std::tuple>>); - - static_assert(std::is_same_v< - PatternTraits>, matchit::impl::Id>>::AppResultTuple< - std::array>, - std::tuple>>); + static_assert(std::is_same_v>>>>::AppResultTuple>, std::tuple>>); + static_assert(std::is_same_v>, matchit::impl::Id>>::AppResultTuple>, std::tuple>>); + static_assert(std::is_same_v>, matchit::impl::Id>>::AppResultTuple>, std::tuple>>); template class PostCheck { public: constexpr explicit PostCheck(const Pattern& pattern, const Pred& pred) : mPattern { pattern }, mPred { pred } {} - constexpr bool check() const { + [[nodiscard]] constexpr fn check() const -> bool { return mPred(); } - constexpr const auto& pattern() const { + + constexpr fn pattern() const -> const Pattern& { return mPattern; } private: - const Pattern mPattern; - const Pred mPred; + Pattern mPattern; + Pred mPred; }; template @@ -1647,26 +1587,24 @@ namespace matchit { using AppResultTuple = typename PatternTraits::template AppResultTuple; template - constexpr static auto matchPatternImpl( + constexpr static fn matchPatternImpl( Value&& value, const PostCheck& postCheck, const int32_t depth, ContextT& context - ) { + ) -> bool { return matchPattern(std::forward(value), postCheck.pattern(), depth + 1, context) && postCheck.check(); } - constexpr static void - processIdImpl(const PostCheck& postCheck, int32_t depth, IdProcess idProcess) { + + constexpr static fn processIdImpl(const PostCheck& postCheck, int32_t depth, IdProcess idProcess) -> void { processId(postCheck.pattern(), depth, idProcess); } }; static_assert(std::is_same_v::AppResultTuple, std::tuple<>>); static_assert(std::is_same_v::AppResultTuple, std::tuple<>>); - constexpr auto x = [](auto&& t) { return t; }; - static_assert(std::is_same_v< - PatternTraits>::AppResultTuple>, - std::tuple>>); + constexpr fn x = [](auto&& t) { return t; }; + static_assert(std::is_same_v>::AppResultTuple>, std::tuple>>); static_assert(PatternTraits>>::nbIdV == 0); static_assert(PatternTraits>>>::nbIdV == 1); @@ -1675,7 +1613,7 @@ namespace matchit { static_assert(PatternTraits>::nbIdV == 0); template - constexpr auto matchPatterns(Value&& value, const PatternPairs&... patterns) { + constexpr fn matchPatterns(Value&& value, const PatternPairs&... patterns) { using RetType = typename PatternPairsRetType::RetType; using TypeTuple = decltype(std::tuple_cat( std::declval::template AppResultTuple>()... @@ -1683,7 +1621,7 @@ namespace matchit { // expression, has return value. if constexpr (!std::is_same_v) { - constexpr auto func = [](const auto& pattern, auto&& val, RetType& result) constexpr -> bool { + constexpr fn func = [](const auto& pattern, auto&& val, RetType& result) constexpr -> bool { if (auto context = typename ContextTrait::ContextT {}; pattern.matchValue(std::forward(val), context)) { result = pattern.execute(); @@ -1692,17 +1630,18 @@ namespace matchit { } return false; }; - RetType result {}; - const bool matched = (func(patterns, value, result) || ...); - if (!matched) { + + RetType result {}; + + const bool matched = (func(patterns, std::forward(value), result) || ...); + + if (!matched) throw std::logic_error { "Error: no patterns got matched!" }; - } + static_cast(matched); return result; - } else - // statement, no return value, mismatching all patterns is not an error. - { - const auto func = [](const auto& pattern, auto&& val) -> bool { + } else { + const fn func = [](const auto& pattern, auto&& val) -> bool { if (auto context = typename ContextTrait::ContextT {}; pattern.matchValue(std::forward(val), context)) { pattern.execute(); @@ -1711,45 +1650,18 @@ namespace matchit { } return false; }; - const bool matched = (func(patterns, value) || ...); + const bool matched = (func(patterns, std::forward(value)) || ...); static_cast(matched); } } - } // namespace impl - - // export symbols - using impl::_; - using impl::and_; - using impl::app; - using impl::ds; - using impl::Id; - using impl::is; - using impl::meet; - using impl::not_; - using impl::ooo; - using impl::or_; - using impl::Subrange; - using impl::SubrangeT; - using impl::when; -} // namespace matchit - -#endif // MATCHIT_PATTERNS_H -#ifndef MATCHIT_UTILITY_H - #define MATCHIT_UTILITY_H - - #include - -namespace matchit { - namespace impl { - template - constexpr auto cast = [](auto&& input) { return static_cast(input); }; + constexpr fn cast = [](auto&& input) { return static_cast(input); }; - constexpr auto deref = [](auto&& x) -> decltype(*x)& { return *x; }; - constexpr auto some = [](const auto pat) { return and_(app(cast, true), app(deref, pat)); }; + constexpr fn deref = [](auto&& x) -> decltype(*x)& { return *x; }; + constexpr fn some = [](const auto pat) { return and_(app(cast, true), app(deref, pat)); }; - constexpr auto none = app(cast, false); + constexpr fn none = app(cast, false); template > struct ViaGetIf : std::false_type {}; @@ -1760,7 +1672,7 @@ namespace matchit { struct ViaGetIf(std::declval()))>> : std::true_type {}; template - constexpr auto viaGetIfV = ViaGetIf::value; + constexpr bool viaGetIfV = ViaGetIf::value; static_assert(viaGetIfV>); @@ -1769,47 +1681,59 @@ namespace matchit { static_assert(!std::is_reference_v); public: - template >>* = nullptr> - constexpr auto operator()(Variant&& v) const { - return get_if(std::addressof(v)); + template + constexpr fn operator()(Variant&& v) const + requires(viaGetIfV>) + { + return get_if(std::addressof(std::forward(v))); } // template to disable implicit cast to std::any - template , std::any>>* = nullptr> - constexpr auto operator()(A&& a) const { - return std::any_cast(std::addressof(a)); + template + constexpr fn operator()(A&& a) const + requires(std::is_same_v, std::any>) + { + return std::any_cast(std::addressof(std::forward(a))); } // cast to base class - template && std::is_base_of_v>* = nullptr> - constexpr auto operator()(const D& d) const -> decltype(static_cast(std::addressof(d))) { + template + constexpr fn operator()(const D& d) const->decltype(static_cast(std::addressof(d))) + requires(!viaGetIfV && std::is_base_of_v) + { return static_cast(std::addressof(d)); } // No way to handle rvalue to save copy in this class. Need to define some in another way to handle this. // cast to base class - template && std::is_base_of_v>* = nullptr> - constexpr auto operator()(D& d) const -> decltype(static_cast(std::addressof(d))) { + template + constexpr fn operator()(D& d) const->decltype(static_cast(std::addressof(d))) + requires(!viaGetIfV && std::is_base_of_v) + { return static_cast(std::addressof(d)); } // cast to derived class - template && std::is_base_of_v>* = nullptr> - constexpr auto operator()(const B& b) const -> decltype(dynamic_cast(std::addressof(b))) { + template + constexpr fn operator()(const B& b) const->decltype(dynamic_cast(std::addressof(b))) + requires(!viaGetIfV && std::is_base_of_v) + { return dynamic_cast(std::addressof(b)); } // cast to derived class - template && std::is_base_of_v>* = nullptr> - constexpr auto operator()(B& b) const -> decltype(dynamic_cast(std::addressof(b))) { + template + constexpr fn operator()(B& b) const->decltype(dynamic_cast(std::addressof(b))) + requires(!viaGetIfV && std::is_base_of_v) + { return dynamic_cast(std::addressof(b)); } - constexpr auto operator()(const T& b) const { + constexpr fn operator()(const T& b) const { return std::addressof(b); } - constexpr auto operator()(T& b) const { + constexpr fn operator()(T& b) const { return std::addressof(b); } }; @@ -1821,33 +1745,52 @@ namespace matchit { constexpr AsPointer asPointer; template - constexpr auto as = [](const auto pat) { return app(asPointer, some(pat)); }; + constexpr fn as = [](const auto pat) { return app(asPointer, some(pat)); }; template - constexpr auto matched(Value&& v, Pattern&& p) { + constexpr fn matched(Value&& v, Pattern&& p) { return match(std::forward(v))( is | std::forward(p) = [] { return true; }, is | _ = [] { return false; } ); } - constexpr auto dsVia = [](auto... members) { + constexpr fn dsVia = [](auto... members) { return [members...](auto... pats) { return and_(app(members, pats)...); }; }; template - constexpr auto asDsVia = - [](auto... members) { return [members...](auto... pats) { return as(and_(app(members, pats)...)); }; }; + constexpr fn asDsVia = [](auto... members) { return [members...](auto... pats) { return as(and_(app(members, pats)...)); }; }; + constexpr fn within = [](const auto& first, const auto& last) { + return meet([=](auto&& v) { return first <= v && v <= last; }); + }; + + constexpr fn between = [](const auto& first, const auto& last) { + return meet([=](auto&& v) { return first < v && v < last; }); + }; } // namespace impl + + using impl::_; + using impl::and_; + using impl::app; using impl::as; using impl::asDsVia; + using impl::ds; using impl::dsVia; + using impl::expr; + using impl::Id; + using impl::is; + using impl::match; using impl::matched; + using impl::meet; using impl::none; + using impl::not_; + using impl::ooo; + using impl::or_; using impl::some; - // NOLINTEND(*-identifier-naming) + using impl::Subrange; + using impl::SubrangeT; + using impl::when; + using impl::within; } // namespace matchit - -#endif // MATCHIT_UTILITY_H - -#endif // MATCHIT_H +// NOLINTEND(readability-identifier-*, cppcoreguidelines-special-member-functions) \ No newline at end of file diff --git a/src/core/system_data.cpp b/src/core/system_data.cpp index 9db9ac6..7152b3d 100644 --- a/src/core/system_data.cpp +++ b/src/core/system_data.cpp @@ -13,21 +13,26 @@ #include "src/util/error.hpp" #include "src/util/types.hpp" +#include "include/matchit.hpp" + using util::error::DracError, util::error::DracErrorCode; namespace { using util::types::i32, util::types::CStr; fn getOrdinalSuffix(const i32 day) -> CStr { + using matchit::match, matchit::is, matchit::_, matchit::within; + if (day >= 11 && day <= 13) return "th"; - switch (day % 10) { - case 1: return "st"; - case 2: return "nd"; - case 3: return "rd"; - default: return "th"; - } + return match(day % 10)( + is | within(11, 13) = "th", + is | 1 = "st", + is | 2 = "nd", + is | 3 = "rd", + is | _ = "th" + ); } fn getDate() -> Result { diff --git a/src/os/windows.cpp b/src/os/windows.cpp index 5f7b02c..fbb7363 100644 --- a/src/os/windows.cpp +++ b/src/os/windows.cpp @@ -76,8 +76,7 @@ namespace { } template - fn FindShellInProcessTree(const DWORD startPid, const Array, sz>& shellMap) - -> Option { + fn FindShellInProcessTree(const DWORD startPid, const Array, sz>& shellMap) -> Option { if (startPid == 0) return None; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index e137dc7..95a25a6 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -77,8 +77,10 @@ namespace ui { auto colorView = std::views::iota(0, 16) | std::views::transform([](i32 colorIndex) { return ftxui::hbox( - { ftxui::text("◯") | ftxui::bold | ftxui::color(static_cast(colorIndex)), - ftxui::text(" ") } + { + ftxui::text("◯") | ftxui::bold | ftxui::color(static_cast(colorIndex)), + ftxui::text(" "), + } ); }); @@ -104,8 +106,24 @@ namespace ui { const String& name = config.general.name; const Weather& weather = config.weather; - const auto& [userIcon, paletteIcon, calendarIcon, hostIcon, kernelIcon, osIcon, memoryIcon, weatherIcon, musicIcon, diskIcon, shellIcon, packageIcon, deIcon, wmIcon] = - ui::ICON_TYPE; + // clang-format off + const auto& [ + userIcon, + paletteIcon, + calendarIcon, + hostIcon, + kernelIcon, + osIcon, + memoryIcon, + weatherIcon, + diskIcon, + shellIcon, + packageIcon, + deIcon, + wmIcon, + musicIcon + ] = ui::ICON_TYPE; + // clang-format on std::vector initialRows; // Date, Weather std::vector systemInfoRows; // Host, Kernel, OS, RAM, Disk, Shell, Packages @@ -115,10 +133,12 @@ namespace ui { initialRows.push_back({ .icon = calendarIcon, .label = "Date", .value = *data.date }); if (weather.enabled && data.weather) { - const weather::Output& weatherInfo = *data.weather; - String weatherValue = weather.showTownName - ? std::format("{}°F in {}", std::lround(weatherInfo.main.temp), weatherInfo.name) - : std::format("{}°F, {}", std::lround(weatherInfo.main.temp), weatherInfo.weather[0].description); + const weather::Output& weatherInfo = *data.weather; + + String weatherValue = weather.showTownName + ? std::format("{}°F in {}", std::lround(weatherInfo.main.temp), weatherInfo.name) + : std::format("{}°F, {}", std::lround(weatherInfo.main.temp), weatherInfo.weather[0].description); + initialRows.push_back({ .icon = weatherIcon, .label = "Weather", .value = std::move(weatherValue) }); } else if (weather.enabled && !data.weather.has_value()) debug_at(data.weather.error()); @@ -133,9 +153,7 @@ namespace ui { systemInfoRows.push_back({ .icon = kernelIcon, .label = "Kernel", .value = *data.kernelVersion }); if (data.memInfo) - systemInfoRows.push_back( - { .icon = memoryIcon, .label = "RAM", .value = std::format("{}", BytesToGiB { *data.memInfo }) } - ); + systemInfoRows.push_back({ .icon = memoryIcon, .label = "RAM", .value = std::format("{}", BytesToGiB { *data.memInfo }) }); else if (!data.memInfo.has_value()) debug_at(data.memInfo.error()); @@ -144,8 +162,7 @@ namespace ui { { .icon = diskIcon, .label = "Disk", - .value = - std::format("{}/{}", BytesToGiB { data.diskUsage->usedBytes }, BytesToGiB { data.diskUsage->totalBytes }), + .value = std::format("{}/{}", BytesToGiB { data.diskUsage->usedBytes }, BytesToGiB { data.diskUsage->totalBytes }), } ); @@ -154,9 +171,7 @@ namespace ui { if (data.packageCount) { if (*data.packageCount > 0) - systemInfoRows.push_back( - { .icon = packageIcon, .label = "Packages", .value = std::format("{}", *data.packageCount) } - ); + systemInfoRows.push_back({ .icon = packageIcon, .label = "Packages", .value = std::format("{}", *data.packageCount) }); else debug_log("Package count is 0, skipping"); } @@ -184,13 +199,11 @@ namespace ui { usize maxContentWidth = 0; - const usize greetingWidth = get_visual_width_sv(userIcon) + get_visual_width_sv("Hello ") + get_visual_width(name) + - get_visual_width_sv("! "); - maxContentWidth = std::max(maxContentWidth, greetingWidth); + const usize greetingWidth = get_visual_width_sv(userIcon) + get_visual_width_sv("Hello ") + get_visual_width(name) + get_visual_width_sv("! "); + maxContentWidth = std::max(maxContentWidth, greetingWidth); - const usize paletteWidth = - get_visual_width_sv(userIcon) + (16 * (get_visual_width_sv("◯") + get_visual_width_sv(" "))); - maxContentWidth = std::max(maxContentWidth, paletteWidth); + const usize paletteWidth = get_visual_width_sv(userIcon) + (16 * (get_visual_width_sv("◯") + get_visual_width_sv(" "))); + maxContentWidth = std::max(maxContentWidth, paletteWidth); const usize iconActualWidth = get_visual_width_sv(userIcon); @@ -228,8 +241,7 @@ namespace ui { i32 paragraphLimit = 1; if (nowPlayingActive) { - i32 availableForParagraph = - static_cast(targetBoxWidth) - static_cast(npFixedWidthLeft) - static_cast(npFixedWidthRight); + i32 availableForParagraph = static_cast(targetBoxWidth) - static_cast(npFixedWidthLeft) - static_cast(npFixedWidthRight); availableForParagraph -= 2; diff --git a/src/util/logging.hpp b/src/util/logging.hpp index 2774919..dbc648b 100644 --- a/src/util/logging.hpp +++ b/src/util/logging.hpp @@ -5,7 +5,6 @@ #include // std::filesystem::path #include // std::format #include // ftxui::Color -#include // std::{mutex, lock_guard} #include // std::forward #ifdef __cpp_lib_print @@ -22,8 +21,6 @@ #include "src/util/error.hpp" #include "src/util/types.hpp" -#include "ftxui/dom/elements.hpp" - namespace util::logging { using types::usize, types::u8, types::i32, types::i64, types::CStr, types::String, types::StringView, types::Array, types::Option, types::None, types::Mutex, types::LockGuard;