diff --git a/fsm/examples/tutorial/door_1.cpp b/fsm/examples/tutorial/door_1.cpp index 0b04f5e..7a7b4ba 100644 --- a/fsm/examples/tutorial/door_1.cpp +++ b/fsm/examples/tutorial/door_1.cpp @@ -4,10 +4,10 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include - #include +#include + using asap::fsm::ByDefault; using asap::fsm::DoNothing; using asap::fsm::On; diff --git a/fsm/examples/tutorial/door_2.cpp b/fsm/examples/tutorial/door_2.cpp index 34613e3..0d900c4 100644 --- a/fsm/examples/tutorial/door_2.cpp +++ b/fsm/examples/tutorial/door_2.cpp @@ -4,10 +4,10 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include - #include +#include + using asap::fsm::ByDefault; using asap::fsm::Continue; using asap::fsm::DoNothing; @@ -28,7 +28,8 @@ struct ClosedState : Will, On>> { using Will::Handle; - template auto OnEnter(const Event & /*event*/) -> Status { + template + static auto OnEnter(const Event & /*event*/) -> Status { std::cout << " > door is closed\n"; return Continue{}; } @@ -43,12 +44,14 @@ struct OpenState : Will, On>> { using Will::Handle; - template auto OnEnter(const Event & /*event*/) -> Status { + template + static auto OnEnter(const Event & /*event*/) -> Status { std::cout << " > door is open\n"; return Continue{}; } - [[nodiscard]] static auto Handle(const OpenEvent & /*event*/) -> DoNothing { + [[nodiscard]] [[maybe_unused]] static auto Handle(const OpenEvent & /*event*/) + -> DoNothing { std::cerr << "Error: the door is already open!\n"; return DoNothing{}; } diff --git a/fsm/examples/tutorial/door_3.cpp b/fsm/examples/tutorial/door_3.cpp index 4bb77b6..7e17b86 100644 --- a/fsm/examples/tutorial/door_3.cpp +++ b/fsm/examples/tutorial/door_3.cpp @@ -4,10 +4,10 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include - #include +#include + using asap::fsm::ByDefault; using asap::fsm::Continue; using asap::fsm::DoNothing; @@ -39,17 +39,20 @@ struct ClosedState On>> { using Will::Handle; - static auto OnEnter(const UnlockEvent & /*event*/) -> Status { + [[maybe_unused]] static auto OnEnter(const UnlockEvent & /*event*/) + -> Status { std::cout << " > door is closed - unlocked\n"; return Continue{}; } - template auto OnEnter(const Event & /*event*/) -> Status { + template + static auto OnEnter(const Event & /*event*/) -> Status { std::cout << " > door is closed\n"; return Continue{}; } - [[nodiscard]] static auto Handle(const CloseEvent & /*event*/) -> DoNothing { + [[nodiscard]] [[maybe_unused]] static auto Handle( + const CloseEvent & /*event*/) -> DoNothing { std::cerr << "Error: the door is already closed!\n"; return DoNothing{}; } @@ -59,12 +62,14 @@ struct OpenState : Will, On>> { using Will::Handle; - template auto OnEnter(const Event & /*event*/) -> Status { + template + static auto OnEnter(const Event & /*event*/) -> Status { std::cout << " > door is open\n"; return Continue{}; } - [[nodiscard]] static auto Handle(const OpenEvent & /*event*/) -> DoNothing { + [[nodiscard]] [[maybe_unused]] static auto Handle(const OpenEvent & /*event*/) + -> DoNothing { std::cerr << "Error: the door is already open!\n"; return DoNothing{}; } @@ -76,13 +81,13 @@ struct LockedState : ByDefault { explicit LockedState(uint32_t key) : key_(key) { } - auto OnEnter(const LockEvent &event) -> Status { + [[maybe_unused]] auto OnEnter(const LockEvent &event) -> Status { std::cout << " > door is locked with new code(" << event.newKey << ")\n"; key_ = event.newKey; return Continue{}; } - [[nodiscard]] auto Handle(const UnlockEvent &event) const + [[nodiscard]] [[maybe_unused]] auto Handle(const UnlockEvent &event) const -> Maybe> { if (event.key == key_) { return TransitionTo{}; diff --git a/fsm/include/fsm/fsm.h b/fsm/include/fsm/fsm.h index a140827..28386d6 100644 --- a/fsm/include/fsm/fsm.h +++ b/fsm/include/fsm/fsm.h @@ -17,18 +17,16 @@ #pragma once -#include - #include -#include #include #include -#include #include #include #include #include +#include + /// Namespace for the State Machine library. namespace asap::fsm { @@ -129,7 +127,7 @@ class ASAP_FSM_API StateMachineError { * \brief Called from derived exception classes to populate the error message * with meaningful information. */ - void What(std::string description); + void What(std::string description) const; private: // Internal implementation class. @@ -364,28 +362,28 @@ template struct TransitionTo { private: // This overload is always in the set of overloads. Ellipsis parameter has the // lowest ranking for overload resolution. - template auto Leave(Args... /*unused*/) -> Status { + template static auto Leave(Args... /*unused*/) -> Status { return Continue{}; } // SFINAE: This overload is for states that implement `onLeave` with an event // parameter. template - [[maybe_unused]] auto Leave(State &state, const Event &event) + [[maybe_unused]] static auto Leave(State &state, const Event &event) -> decltype(state.OnLeave(event)) { return state.OnLeave(event); } // This overload is always in the set of overloads. Ellipsis parameter has the // lowest ranking for overload resolution. - template auto Enter(Args... /*unused*/) -> Status { + template static auto Enter(Args... /*unused*/) -> Status { return Continue{}; } // SFINAE: This overload is for states that implement `onEnter` with an event // parameter. Data from the previous event, if any, will be discarded. template - [[maybe_unused]] auto Enter(State &state, const Event &event) + [[maybe_unused]] static auto Enter(State &state, const Event &event) -> decltype(state.OnEnter(event)) { return state.OnEnter(event); } @@ -417,7 +415,7 @@ template struct TransitionTo { */ struct ASAP_FSM_API DoNothing { template - auto Execute(Machine & /*unused*/, State & /*unused*/, + static auto Execute(Machine & /*unused*/, State & /*unused*/, const Event & /*unused*/) -> Status { return Continue{}; } @@ -517,8 +515,8 @@ constexpr auto supports_alternative() -> bool { */ template struct OneOf { template ::type>::value> * = nullptr> + std::enable_if>> * = + nullptr> // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions,bugprone-forwarding-reference-overload) OneOf(T &&arg) : option(std::forward(arg)) { } @@ -616,7 +614,7 @@ struct is_one_of> : std::true_type {}; */ template struct ByDefault { template - auto Handle(const Event & /*unused*/) const -> Action { + static auto Handle(const Event & /*unused*/) -> Action { return Action{}; } }; @@ -630,7 +628,7 @@ template struct ByDefault { * \snippet fsm_test.cpp On example */ template struct On { - auto Handle(const Event & /*event*/) const -> Action { + static auto Handle(const Event & /*event*/) -> Action { return {}; } }; diff --git a/fsm/src/fsm.cpp b/fsm/src/fsm.cpp index ed2bafb..fd25230 100644 --- a/fsm/src/fsm.cpp +++ b/fsm/src/fsm.cpp @@ -10,15 +10,17 @@ * \brief Implementation details of the StateMachine and related types. */ -#include -#include +#include "fsm/fsm.h" +#include #include #include +#include + // Warnings free memory allocation without full dependency on GSL implementation namespace gsl { -template ::value>> +template >> using owner = T; } // namespace gsl @@ -50,7 +52,8 @@ class StateMachineError::Impl { // warning :-) StateMachineError::Impl::~Impl() = default; -StateMachineError::StateMachineError() : pimpl(gsl::owner(new Impl())) { +StateMachineError::StateMachineError() + : pimpl(static_cast>(new Impl())) { } StateMachineError::StateMachineError(std::string description) @@ -58,7 +61,7 @@ StateMachineError::StateMachineError(std::string description) } StateMachineError::StateMachineError(const StateMachineError &other) - : pimpl(gsl::owner(new Impl(*other.pimpl))) { + : pimpl(static_cast>(new Impl(*other.pimpl))) { } StateMachineError::StateMachineError(StateMachineError &&other) noexcept @@ -72,7 +75,7 @@ auto StateMachineError::operator=(const StateMachineError &rhs) return *this; } delete pimpl; - pimpl = gsl::owner(new Impl(*rhs.pimpl)); + pimpl = static_cast>(new Impl(*rhs.pimpl)); return *this; } @@ -99,7 +102,7 @@ auto StateMachineError::What() const -> const char * { return nullptr; } -void StateMachineError::What(std::string description) { +void StateMachineError::What(std::string description) const { pimpl->What(std::move(description)); } diff --git a/fsm/test/fsm_example_test.cpp b/fsm/test/fsm_example_test.cpp index 468653f..32f2b83 100644 --- a/fsm/test/fsm_example_test.cpp +++ b/fsm/test/fsm_example_test.cpp @@ -4,28 +4,13 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include +#include "fsm/fsm.h" -#include #include #include #include -// Disable compiler and linter warnings originating from the unit test framework -// and for which we cannot do anything. Additionally, every TEST or TEST_X macro -// usage must be preceded by a '// NOLINTNEXTLINE'. -ASAP_DIAGNOSTIC_PUSH -#if defined(__clang__) && ASAP_HAS_WARNING("-Wused-but-marked-unused") -#pragma clang diagnostic ignored "-Wused-but-marked-unused" -#pragma clang diagnostic ignored "-Wglobal-constructors" -#pragma clang diagnostic ignored "-Wunused-member-function" -#endif -// NOLINTBEGIN(used-but-marked-unused) - -using testing::Eq; -using testing::IsTrue; - namespace asap::fsm { namespace { @@ -65,13 +50,13 @@ struct LockedState : ByDefault { explicit LockedState(uint32_t key) : key_(key) { } - auto OnEnter(const LockEvent &event) -> Status { + [[maybe_unused]] auto OnEnter(const LockEvent &event) -> Status { key_ = event.newKey; return Continue{}; } //! [State Handle method] - [[nodiscard]] auto Handle(const UnlockEvent &event) const + [[nodiscard]] [[maybe_unused]] auto Handle(const UnlockEvent &event) const -> Maybe> { if (event.key == key_) { return TransitionTo{}; @@ -102,6 +87,3 @@ TEST(StateMachine, ExampleTest) { } // namespace } // namespace asap::fsm - -// NOLINTEND(used-but-marked-unused) -ASAP_DIAGNOSTIC_POP diff --git a/fsm/test/fsm_test.cpp b/fsm/test/fsm_test.cpp index ec16ad3..43382f1 100644 --- a/fsm/test/fsm_test.cpp +++ b/fsm/test/fsm_test.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include +#include "fsm/fsm.h" #include #include @@ -13,20 +13,6 @@ #include #include -#include - -// Disable compiler and linter warnings originating from the unit test framework -// and for which we cannot do anything. Additionally, every TEST or TEST_X macro -// usage must be preceded by a '// NOLINTNEXTLINE'. -ASAP_DIAGNOSTIC_PUSH -#if defined(__clang__) && ASAP_HAS_WARNING("-Wused-but-marked-unused") -#pragma clang diagnostic ignored "-Wused-but-marked-unused" -#pragma clang diagnostic ignored "-Wglobal-constructors" -#pragma clang diagnostic ignored "-Wexit-time-destructors" -#pragma clang diagnostic ignored "-Wunused-member-function" -#endif -// NOLINTBEGIN(used-but-marked-unused) - using testing::ByRef; using testing::Eq; using testing::IsFalse; @@ -51,9 +37,6 @@ TEST(StateMachine, MachineHandleEventRelaysToStateAndExecutesReturnedAction) { struct Action { // NOLINT virtual auto Execute(Machine &machine, FirstState &state, const TestEvent &event) -> Status = 0; - - protected: - ~Action() = default; }; struct TestAction { @@ -87,8 +70,8 @@ TEST(StateMachine, MachineHandleEventRelaysToStateAndExecutesReturnedAction) { Status, Execute, (Machine &, FirstState &, const TestEvent &), ()); }; - auto mock_state = std::make_shared(); - auto mock_action = std::make_shared(); + const auto mock_state = std::make_shared(); + const auto mock_action = std::make_shared(); Machine machine{FirstState{mock_state}}; @@ -104,7 +87,7 @@ TEST(StateMachine, MachineHandleEventRelaysToStateAndExecutesReturnedAction) { // An event falling under a ByDefault rule will not trigger a call to the // state Handle method - DefaultedEvent event{}; + const DefaultedEvent event{}; EXPECT_CALL(*mock_state, Handle).Times(0); machine.Handle(event); } @@ -120,9 +103,6 @@ TEST(StateMachine, MachineHandleEventCatchesUnhandledExceptions) { struct Action { // NOLINT virtual auto Execute(Machine &machine, FirstState &state, const TestEvent &event) -> Status = 0; - - protected: - ~Action() = default; }; struct TestAction { @@ -416,8 +396,8 @@ TEST(StateMachine, TransitionToExample) { const std::shared_ptr mock_; }; - auto mock_initial_state = std::make_shared(); - auto mock_another_state = std::make_shared(); + const auto mock_initial_state = std::make_shared(); + const auto mock_another_state = std::make_shared(); Machine machine{ FirstState{mock_initial_state}, SecondState{mock_another_state}}; @@ -490,8 +470,8 @@ TEST(StateMachine, TransitionToWithDataExample) { const std::shared_ptr mock_; }; - auto mock_initial_state = std::make_shared(); - auto mock_another_state = std::make_shared(); + const auto mock_initial_state = std::make_shared(); + const auto mock_another_state = std::make_shared(); Machine machine{ FirstState{mock_initial_state}, SecondState{mock_another_state}}; @@ -528,7 +508,7 @@ struct StateMachineTransitionToErrors : public ::testing::Test { } // We only implement the OnLeave method, but that's ok. // The action will only call whatever is implemented. - auto OnLeave(const TransitionEvent &event) -> Status { + [[maybe_unused]] auto OnLeave(const TransitionEvent &event) -> Status { return mock_->OnLeave(event); } @@ -542,7 +522,7 @@ struct StateMachineTransitionToErrors : public ::testing::Test { } // We only implement the OnEnter method, but that's ok. // The action will only call whatever is implemented. - auto OnEnter(const TransitionEvent &event) -> Status { + [[maybe_unused]] auto OnEnter(const TransitionEvent &event) -> Status { return mock_->OnEnter(event); } @@ -566,7 +546,7 @@ TEST_F(StateMachineTransitionToErrors, OnLeaveReturnsTerminate) { .Times(1) .WillOnce(Return(Terminate{})); EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))).Times(0); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsFalse()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); } @@ -579,7 +559,7 @@ TEST_F(StateMachineTransitionToErrors, OnLeaveReturnsTerminateWithError) { .Times(1) .WillOnce(Return(TerminateWithError{"error"})); EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))).Times(0); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsFalse()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT(std::get(status).error_message, Eq("error")); @@ -593,7 +573,7 @@ TEST_F(StateMachineTransitionToErrors, OnLeaveThrowsStateMachineError) { .Times(1) .WillOnce(testing::Throw(StateMachineError("error"))); EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))).Times(0); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsFalse()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT(std::get(status).error_message, Eq("error")); @@ -607,7 +587,7 @@ TEST_F(StateMachineTransitionToErrors, OnLeaveThrowsOtherError) { .Times(1) .WillOnce(testing::Throw(std::runtime_error("error"))); EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))).Times(0); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsFalse()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT( @@ -624,7 +604,7 @@ TEST_F(StateMachineTransitionToErrors, OnEnterReturnsTerminate) { EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))) .Times(1) .WillOnce(Return(Terminate{})); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsTrue()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); } @@ -639,7 +619,7 @@ TEST_F(StateMachineTransitionToErrors, OnEnterReturnsTerminateWithError) { EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))) .Times(1) .WillOnce(Return(TerminateWithError{"error"})); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsTrue()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT(std::get(status).error_message, Eq("error")); @@ -655,7 +635,7 @@ TEST_F(StateMachineTransitionToErrors, OnEnterReturnsReissueEvent) { EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))) .Times(1) .WillOnce(Return(ReissueEvent{})); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsTrue()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); } @@ -670,7 +650,7 @@ TEST_F(StateMachineTransitionToErrors, OnEnterThrowsStateMachineError) { EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))) .Times(1) .WillOnce(::testing::Throw(StateMachineError("error"))); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsTrue()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT(std::get(status).error_message, Eq("error")); @@ -686,7 +666,7 @@ TEST_F(StateMachineTransitionToErrors, OnEnterThrowsOtherError) { EXPECT_CALL(*mock_another_state, OnEnter(Ref(event))) .Times(1) .WillOnce(::testing::Throw(std::runtime_error("error"))); - auto status = machine.Handle(event); + const auto status = machine.Handle(event); ASSERT_THAT(machine.IsIn(), IsTrue()); EXPECT_THAT(std::holds_alternative(status), IsTrue()); EXPECT_THAT( @@ -701,7 +681,7 @@ TEST(StateMachine, TransitionToIsATest) { ASSERT_THAT(action.IsA>(), IsTrue()); ASSERT_THAT(action.IsA(), IsFalse()); - auto specific_ok = action.GetAs>(); + const auto specific_ok = action.GetAs>(); EXPECT_THAT(std::any_cast(specific_ok.data()), Eq(data)); const auto &const_specific_ok = // NOLINTNEXTLINE @@ -725,7 +705,7 @@ TEST(StateMachine, DoNothingIsATest) { // NOLINTNEXTLINE TEST(StateMachine, ReportErrorIsATest) { struct State {}; - auto error = StateMachineError{}; + const auto error = StateMachineError{}; auto action = ReportError{error}; EXPECT_THAT(action.IsA(), IsTrue()); @@ -733,7 +713,7 @@ TEST(StateMachine, ReportErrorIsATest) { [[maybe_unused]] const auto &const_specific_ok = // NOLINTNEXTLINE const_cast(action).GetAs(); - auto stored_error = + const auto stored_error = std::any_cast(const_specific_ok.data()); EXPECT_THAT(stored_error.What(), Eq(error.What())); } @@ -830,6 +810,3 @@ std::vector> DynamicActionTest::test_actions{{DoNothing{}, false}}; } // namespace asap::fsm - -// NOLINTEND(used-but-marked-unused) -ASAP_DIAGNOSTIC_POP diff --git a/fsm/test/state_machine_error_test.cpp b/fsm/test/state_machine_error_test.cpp index 86c6022..6ba5c10 100644 --- a/fsm/test/state_machine_error_test.cpp +++ b/fsm/test/state_machine_error_test.cpp @@ -4,27 +4,12 @@ // SPDX-License-Identifier: BSD-3-Clause //===----------------------------------------------------------------------===// -#include +#include "fsm/fsm.h" -#include - -#include +#include #include -// Disable compiler and linter warnings originating from the unit test framework -// and for which we cannot do anything. Additionally, every TEST or TEST_X macro -// usage must be preceded by a '// NOLINTNEXTLINE'. -ASAP_DIAGNOSTIC_PUSH -#if defined(__clang__) && ASAP_HAS_WARNING("-Wused-but-marked-unused") -#pragma clang diagnostic ignored "-Wused-but-marked-unused" -#pragma clang diagnostic ignored "-Wglobal-constructors" -#pragma clang diagnostic ignored "-Wexit-time-destructors" -#pragma clang diagnostic ignored "-Wunused-member-function" -#endif -// NOLINTBEGIN(used-but-marked-unused) - using testing::Eq; -using testing::IsNull; using testing::Ne; using testing::StrEq; @@ -34,34 +19,34 @@ namespace { // NOLINTNEXTLINE TEST(StateMachineError, DefaultConstructor) { - StateMachineError err; + const StateMachineError err; EXPECT_THAT(err.What(), Ne("")); } // NOLINTNEXTLINE TEST(StateMachineError, ConstructWithMessage) { - StateMachineError err("__error__"); + const StateMachineError err("__error__"); EXPECT_THAT(err.What(), StrEq("__error__")); } // NOLINTNEXTLINE TEST(StateMachineError, CopyConstructor) { - StateMachineError err("__error__"); - StateMachineError copy(err); // NOLINT + const StateMachineError err("__error__"); + const StateMachineError copy(err); // NOLINT EXPECT_THAT(std::string(copy.What()), Eq(std::string(err.What()))); } // NOLINTNEXTLINE TEST(StateMachineError, MoveConstructor) { StateMachineError err("__error__"); - StateMachineError copy(std::move(err)); + const StateMachineError copy(std::move(err)); EXPECT_THAT(copy.What(), StrEq("__error__")); } // NOLINTNEXTLINE TEST(StateMachineError, Assign) { - StateMachineError err("__error__"); - StateMachineError copy = err; // NOLINT + const StateMachineError err("__error__"); + const StateMachineError copy = err; // NOLINT EXPECT_THAT(copy.What(), StrEq("__error__")); EXPECT_THAT(err.What(), StrEq("__error__")); } @@ -69,13 +54,10 @@ TEST(StateMachineError, Assign) { // NOLINTNEXTLINE TEST(StateMachineError, MoveAssign) { StateMachineError err("__error__"); - StateMachineError copy = std::move(err); + const StateMachineError copy = std::move(err); EXPECT_THAT(copy.What(), StrEq("__error__")); } } // namespace } // namespace asap::fsm - -// NOLINTEND(used-but-marked-unused) -ASAP_DIAGNOSTIC_POP