From d6ff78d4075db7d3e9c5e5cc8e85077ea35d03f4 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Wed, 28 May 2025 18:44:23 +0300 Subject: [PATCH] ... --- cxx/CMakeLists.txt | 5 +- cxx/mcc_fsm.h | 239 +++-------------------------------------- cxx/mcc_fsm_utils.h | 255 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+), 228 deletions(-) create mode 100644 cxx/mcc_fsm_utils.h diff --git a/cxx/CMakeLists.txt b/cxx/CMakeLists.txt index 162326a..25cad4a 100644 --- a/cxx/CMakeLists.txt +++ b/cxx/CMakeLists.txt @@ -123,10 +123,9 @@ set(CNTR_PROTO_LIB comm_proto) add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC}) set(MOUNT_SERVER_APP_SRC mount.h mount_state.h mount_server.cpp comm_server.h comm_server_endpoint.h comm_server_configfile.h mount_astrom.h - mount_astrom_default.h mcc_coord.h mount_pz.h) + mount_astrom_default.h mcc_coord.h mount_pz.h mcc_fsm.h mcc_fsm_utils.h) set(MOUNT_SERVER_APP mount_server) -add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC} - mcc_fsm.h) +add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}) # target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR}) target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only ERFA_LIB) diff --git a/cxx/mcc_fsm.h b/cxx/mcc_fsm.h index 6db743e..0add90f 100644 --- a/cxx/mcc_fsm.h +++ b/cxx/mcc_fsm.h @@ -1,243 +1,32 @@ #pragma once - /* MOUNT CONTROL COMPONENTS LIBRARY */ /* FINITE-STATE MACHINE IMPLEMENTATION */ -#include -#include -#include -#include +#include +#include "mcc_fsm_utils.h" -namespace mcc + +namespace mcc::fsm { -namespace traits -{ - -template -concept std_pair_c = requires(T t) { - [](std::type_identity>) { - - }(std::type_identity>()); -}; - - -} // namespace traits - - -namespace fsm -{ - -/* A TYPE TO HOLD COMPILE-TIME SEQUENCE OF std::pair */ -template -struct pair_holder_t; - -template -struct pair_holder_t { - // using self_t = pair_holder_t; - // using self_data_t = std::tuple; - typedef pair_holder_t self_t; - typedef std::tuple sequence_t; -}; - -template <> -struct pair_holder_t<> { - // using self_data_t = std::tuple<>; - typedef std::tuple<> sequence_t; - constexpr static bool valid = true; -}; - -} // namespace fsm - - -namespace traits -{ -template -concept pair_holder_c = requires { - [](std::type_identity>) { - // - }(std::type_identity>()); -}; - -} // namespace traits - - -namespace fsm -{ - -/* A CLASS TO FIND TYPE OF pair.second ELEMENT BY ITS pair.first one IN PAIR-SEQUENCE */ - -template -struct pair_holder_find_t; - -template -struct pair_holder_find_t, tail...>> - : pair_holder_find_t> { -}; - -template -struct pair_holder_find_t> { - typedef std::nullptr_t result_t; -}; - -template -struct pair_holder_find_t, tail...>> { - typedef SecondT result_t; -}; - - - -/* A CLASS TO GET ALL pair.first TYPES IN PAIR-SEQUENCE */ - -template -struct pair_holder_first_t; - -template -struct pair_holder_first_t, tail...>> { - typedef decltype(std::tuple_cat( - std::declval>(), - std::declval>::first_t>())) first_t; -}; - - -template <> -struct pair_holder_first_t> { - typedef std::tuple<> first_t; -}; - - -/* A CLASS TO GET ALL pair.second TYPES IN PAIR-SEQUENCE */ - -template -struct pair_holder_second_t; - -template -struct pair_holder_second_t, tail...>> { - typedef decltype(std::tuple_cat( - std::declval>(), - std::declval>::second_t>())) second_t; -}; - - -template <> -struct pair_holder_second_t> { - typedef std::tuple<> second_t; -}; - - - -/* A TYPE TO IMPLEMENT TUPLE OF UNIQUE TYPES */ - -template -class unique_tuple_t -{ - template - struct in_tuple : in_tuple { - }; - - template - struct in_tuple> : std::disjunction...> { - }; - - // insert - template ::value> - struct insert; - - template - struct insert, false> { - typedef std::tuple tuple_t; - typedef std::tuple<> non_unique_t; - }; - - template - struct insert, true> { - typedef std::tuple tuple_t; - typedef std::tuple non_unique_t; - }; - - - // merge - template - struct merge; - - template - struct merge, std::tuple> { - typedef merge, std::tuple> tail_t; - typedef insert curr_tuple_t; - - typedef typename curr_tuple_t::tuple_t tuple_t; - typedef decltype(std::tuple_cat(std::declval(), - std::declval())) non_unique_t; - }; - - template - struct merge, std::tuple> { - typedef std::tuple tuple_t; - typedef std::tuple<> non_unique_t; - }; - -public: - typedef typename merge, std::tuple<>>::tuple_t tuple_t; - typedef typename merge, std::tuple<>>::non_unique_t non_unique_t; -}; - -} // namespace fsm - namespace traits { template -concept unique_tuple_c = requires { - [](std::type_identity>) {}(std::type_identity>()); -}; +concept fsm_event_c = std::is_default_constructible_v && std::is_move_constructible_v && std::movable; + +template +concept fsm_state_c = + std::is_default_constructible_v && std::is_move_constructible_v && std::movable && requires { + [](std::type_identity) {}(T::transition_t); + + { T::name } -> std::same_as; // static constant of state name + }; } // namespace traits - -namespace fsm -{ - -// GET INDEX OF GIVEN TYPE IN UNIQUE TUPLE -namespace details -{ - -// template -template -struct unique_tuple_type_index_helper_t; - - -template -struct unique_tuple_type_index_helper_t, I> { - constexpr static std::size_t index = unique_tuple_type_index_helper_t, I + 1>::index; -}; - - -template -struct unique_tuple_type_index_helper_t, I> { - constexpr static std::size_t index = I; -}; - -template -struct unique_tuple_type_index_helper_t, I> { - constexpr static std::size_t index = std::numeric_limits::max(); - static_assert(false, "INVALID INPUT TYPE!"); -}; - -} // namespace details - - -template -struct unique_tuple_type_index_t : details::unique_tuple_type_index_helper_t { -}; - -template -constexpr static std::size_t unique_tuple_type_index_v = unique_tuple_type_index_t::index; - -} // namespace fsm - - -} // namespace mcc +} // namespace mcc::fsm diff --git a/cxx/mcc_fsm_utils.h b/cxx/mcc_fsm_utils.h new file mode 100644 index 0000000..0a1a984 --- /dev/null +++ b/cxx/mcc_fsm_utils.h @@ -0,0 +1,255 @@ +#pragma once + + +/* MOUNT CONTROL COMPONENTS LIBRARY */ + +/* FINITE-STATE MACHINE UTILITY TYPES DEFINITIONS: + * std::pair sequence holder, unique-type tuple ... */ + + +#include +#include +#include +#include + +namespace mcc +{ + +namespace traits +{ + +// A CONCEPT DEFINITION FOR std::pair +template +concept std_pair_c = requires(T t) { + [](std::type_identity>) { + + }(std::type_identity>()); +}; + + +} // namespace traits + + +namespace fsm +{ + +/* A TYPE TO HOLD COMPILE-TIME SEQUENCE OF std::pair (PAIR-SEQUENCE HOLDER) + * internaly sequence is a std::tuple, std::pair, ... std::pair,> + i.e. std::pair.first field type of sequence elements may be of different types, + the same is for std::pair.second field +*/ +// template +// struct pair_holder_t; + +// template +// struct pair_holder_t { +// // using self_t = pair_holder_t; +// // using self_data_t = std::tuple; +// typedef pair_holder_t self_t; +// typedef std::tuple sequence_t; +// }; + +// template <> +// struct pair_holder_t<> { +// // using self_data_t = std::tuple<>; +// typedef std::tuple<> sequence_t; +// constexpr static bool valid = true; +// }; + +template +using pair_holder_t = std::tuple; + +} // namespace fsm + + +namespace traits +{ + +// PAIR-SEQUENCE HOLDER CONCEPT DEFINITION +template +concept pair_holder_c = requires { + [](std::type_identity>) { + // + }(std::type_identity>()); +}; + +} // namespace traits + + +namespace fsm +{ + +/* A CLASS TO FIND TYPE OF pair.second FIELD BY ITS pair.first ONE IN PAIR-SEQUENCE */ + +template +struct pair_holder_find_t; + +template +struct pair_holder_find_t, tail...>> + : pair_holder_find_t> { +}; + +template +struct pair_holder_find_t> { + typedef std::nullptr_t result_t; +}; + +template +struct pair_holder_find_t, tail...>> { + typedef SecondT result_t; +}; + + + +/* A CLASS TO GET ALL pair.first FIELD TYPES IN PAIR-SEQUENCE */ + +template +struct pair_holder_first_t; + +template +struct pair_holder_first_t, tail...>> { + typedef decltype(std::tuple_cat( + std::declval>(), + std::declval>::first_t>())) first_t; +}; + + +template <> +struct pair_holder_first_t> { + typedef std::tuple<> first_t; +}; + + +/* A CLASS TO GET ALL pair.second TYPES IN PAIR-SEQUENCE */ + +template +struct pair_holder_second_t; + +template +struct pair_holder_second_t, tail...>> { + typedef decltype(std::tuple_cat( + std::declval>(), + std::declval>::second_t>())) second_t; +}; + + +template <> +struct pair_holder_second_t> { + typedef std::tuple<> second_t; +}; + + + +/* A TYPE TO IMPLEMENT TUPLE OF UNIQUE TYPES */ + +template +class unique_tuple_t +{ + template + struct in_tuple : in_tuple { + }; + + template + struct in_tuple> : std::disjunction...> { + }; + + // insert + template ::value> + struct insert; + + template + struct insert, false> { + typedef std::tuple tuple_t; + typedef std::tuple<> non_unique_t; + }; + + template + struct insert, true> { + typedef std::tuple tuple_t; + typedef std::tuple non_unique_t; + }; + + + // merge + template + struct merge; + + template + struct merge, std::tuple> { + typedef merge, std::tuple> tail_t; + typedef insert curr_tuple_t; + + typedef typename curr_tuple_t::tuple_t tuple_t; + typedef decltype(std::tuple_cat(std::declval(), + std::declval())) non_unique_t; + }; + + template + struct merge, std::tuple> { + typedef std::tuple tuple_t; + typedef std::tuple<> non_unique_t; + }; + +public: + typedef typename merge, std::tuple<>>::tuple_t tuple_t; + typedef typename merge, std::tuple<>>::non_unique_t non_unique_t; +}; + +} // namespace fsm + + +namespace traits +{ + +// UNIQUE-TYPES TUPLE CONCEPT DEFINITION +template +concept unique_tuple_c = requires { + [](std::type_identity>) {}(std::type_identity>()); +}; + +} // namespace traits + + +namespace fsm +{ + +// GET INDEX OF GIVEN TYPE IN UNIQUE TUPLE +namespace details +{ + +// template +template +struct unique_tuple_type_index_helper_t; + + +template +struct unique_tuple_type_index_helper_t, I> { + constexpr static std::size_t index = unique_tuple_type_index_helper_t, I + 1>::index; +}; + + +template +struct unique_tuple_type_index_helper_t, I> { + constexpr static std::size_t index = I; +}; + +template +struct unique_tuple_type_index_helper_t, I> { + constexpr static std::size_t index = std::numeric_limits::max(); + static_assert(false, "INVALID INPUT TYPE!"); +}; + +} // namespace details + + +template +struct unique_tuple_type_index_t : details::unique_tuple_type_index_helper_t { +}; + +template +constexpr static std::size_t unique_tuple_type_index_v = unique_tuple_type_index_t::index; + +} // namespace fsm + + +} // namespace mcc