...
This commit is contained in:
parent
156dfb13ba
commit
d6ff78d407
@ -123,10 +123,9 @@ set(CNTR_PROTO_LIB comm_proto)
|
|||||||
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
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
|
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)
|
set(MOUNT_SERVER_APP mount_server)
|
||||||
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}
|
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC})
|
||||||
mcc_fsm.h)
|
|
||||||
# target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR})
|
# 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)
|
target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only ERFA_LIB)
|
||||||
|
|
||||||
|
|||||||
239
cxx/mcc_fsm.h
239
cxx/mcc_fsm.h
@ -1,243 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
||||||
|
|
||||||
/* FINITE-STATE MACHINE IMPLEMENTATION */
|
/* FINITE-STATE MACHINE IMPLEMENTATION */
|
||||||
|
|
||||||
|
|
||||||
#include <limits>
|
#include <string_view>
|
||||||
#include <tuple>
|
#include "mcc_fsm_utils.h"
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace mcc
|
|
||||||
|
namespace mcc::fsm
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace traits
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept std_pair_c = requires(T t) {
|
|
||||||
[]<typename T1, typename T2>(std::type_identity<std::pair<T1, T2>>) {
|
|
||||||
|
|
||||||
}(std::type_identity<std::remove_cvref_t<T>>());
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace traits
|
|
||||||
|
|
||||||
|
|
||||||
namespace fsm
|
|
||||||
{
|
|
||||||
|
|
||||||
/* A TYPE TO HOLD COMPILE-TIME SEQUENCE OF std::pair */
|
|
||||||
template <traits::std_pair_c... pairs>
|
|
||||||
struct pair_holder_t;
|
|
||||||
|
|
||||||
template <traits::std_pair_c head, traits::std_pair_c... tail>
|
|
||||||
struct pair_holder_t<head, tail...> {
|
|
||||||
// using self_t = pair_holder_t<head, tail...>;
|
|
||||||
// using self_data_t = std::tuple<head, tail...>;
|
|
||||||
typedef pair_holder_t<head, tail...> self_t;
|
|
||||||
typedef std::tuple<head, tail...> 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 <typename T>
|
|
||||||
concept pair_holder_c = requires {
|
|
||||||
[]<mcc::traits::std_pair_c... Ts>(std::type_identity<fsm::pair_holder_t<Ts...>>) {
|
|
||||||
//
|
|
||||||
}(std::type_identity<std::remove_cvref_t<T>>());
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace traits
|
|
||||||
|
|
||||||
|
|
||||||
namespace fsm
|
|
||||||
{
|
|
||||||
|
|
||||||
/* A CLASS TO FIND TYPE OF pair.second ELEMENT BY ITS pair.first one IN PAIR-SEQUENCE */
|
|
||||||
|
|
||||||
template <typename FirstT, traits::pair_holder_c PHLDT>
|
|
||||||
struct pair_holder_find_t;
|
|
||||||
|
|
||||||
template <typename FirstT, typename CurrentFirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
|
||||||
struct pair_holder_find_t<FirstT, pair_holder_t<std::pair<CurrentFirstT, SecondT>, tail...>>
|
|
||||||
: pair_holder_find_t<FirstT, pair_holder_t<tail...>> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FirstT>
|
|
||||||
struct pair_holder_find_t<FirstT, pair_holder_t<>> {
|
|
||||||
typedef std::nullptr_t result_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
|
||||||
struct pair_holder_find_t<FirstT, pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
|
||||||
typedef SecondT result_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A CLASS TO GET ALL pair.first TYPES IN PAIR-SEQUENCE */
|
|
||||||
|
|
||||||
template <traits::pair_holder_c PHLDT>
|
|
||||||
struct pair_holder_first_t;
|
|
||||||
|
|
||||||
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
|
||||||
struct pair_holder_first_t<pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
|
||||||
typedef decltype(std::tuple_cat(
|
|
||||||
std::declval<std::tuple<FirstT>>(),
|
|
||||||
std::declval<typename pair_holder_first_t<pair_holder_t<tail...>>::first_t>())) first_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct pair_holder_first_t<pair_holder_t<>> {
|
|
||||||
typedef std::tuple<> first_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* A CLASS TO GET ALL pair.second TYPES IN PAIR-SEQUENCE */
|
|
||||||
|
|
||||||
template <traits::pair_holder_c PHLDT>
|
|
||||||
struct pair_holder_second_t;
|
|
||||||
|
|
||||||
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
|
||||||
struct pair_holder_second_t<pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
|
||||||
typedef decltype(std::tuple_cat(
|
|
||||||
std::declval<std::tuple<SecondT>>(),
|
|
||||||
std::declval<typename pair_holder_second_t<pair_holder_t<tail...>>::second_t>())) second_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct pair_holder_second_t<pair_holder_t<>> {
|
|
||||||
typedef std::tuple<> second_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A TYPE TO IMPLEMENT TUPLE OF UNIQUE TYPES */
|
|
||||||
|
|
||||||
template <typename... TYPEs>
|
|
||||||
class unique_tuple_t
|
|
||||||
{
|
|
||||||
template <typename IT, typename UniqTupleT>
|
|
||||||
struct in_tuple : in_tuple<IT, typename UniqTupleT::tuple_t> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IT, typename... Ts>
|
|
||||||
struct in_tuple<IT, std::tuple<Ts...>> : std::disjunction<std::is_same<IT, Ts>...> {
|
|
||||||
};
|
|
||||||
|
|
||||||
// insert
|
|
||||||
template <typename IT, typename UniqTupleT, bool = in_tuple<IT, UniqTupleT>::value>
|
|
||||||
struct insert;
|
|
||||||
|
|
||||||
template <typename IT, typename... Ts>
|
|
||||||
struct insert<IT, std::tuple<Ts...>, false> {
|
|
||||||
typedef std::tuple<IT, Ts...> tuple_t;
|
|
||||||
typedef std::tuple<> non_unique_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IT, typename... Ts>
|
|
||||||
struct insert<IT, std::tuple<Ts...>, true> {
|
|
||||||
typedef std::tuple<Ts...> tuple_t;
|
|
||||||
typedef std::tuple<IT> non_unique_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// merge
|
|
||||||
template <typename ITupleT, typename OTupleT>
|
|
||||||
struct merge;
|
|
||||||
|
|
||||||
template <typename MT, typename... MTs, typename... OTs>
|
|
||||||
struct merge<std::tuple<MT, MTs...>, std::tuple<OTs...>> {
|
|
||||||
typedef merge<std::tuple<MTs...>, std::tuple<OTs...>> tail_t;
|
|
||||||
typedef insert<MT, typename tail_t::tuple_t> curr_tuple_t;
|
|
||||||
|
|
||||||
typedef typename curr_tuple_t::tuple_t tuple_t;
|
|
||||||
typedef decltype(std::tuple_cat(std::declval<typename curr_tuple_t::non_unique_t>(),
|
|
||||||
std::declval<typename tail_t::non_unique_t>())) non_unique_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename... MTs>
|
|
||||||
struct merge<std::tuple<>, std::tuple<MTs...>> {
|
|
||||||
typedef std::tuple<MTs...> tuple_t;
|
|
||||||
typedef std::tuple<> non_unique_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename merge<std::tuple<TYPEs...>, std::tuple<>>::tuple_t tuple_t;
|
|
||||||
typedef typename merge<std::tuple<TYPEs...>, std::tuple<>>::non_unique_t non_unique_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace fsm
|
|
||||||
|
|
||||||
|
|
||||||
namespace traits
|
namespace traits
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept unique_tuple_c = requires {
|
concept fsm_event_c = std::is_default_constructible_v<T> && std::is_move_constructible_v<T> && std::movable<T>;
|
||||||
[]<typename... Ts>(std::type_identity<fsm::unique_tuple_t<Ts...>>) {}(std::type_identity<std::remove_cvref_t<T>>());
|
|
||||||
};
|
template <typename T>
|
||||||
|
concept fsm_state_c =
|
||||||
|
std::is_default_constructible_v<T> && std::is_move_constructible_v<T> && std::movable<T> && requires {
|
||||||
|
[]<mcc::traits::pair_holder_c PHT>(std::type_identity<PHT>) {}(T::transition_t);
|
||||||
|
|
||||||
|
{ T::name } -> std::same_as<const std::string_view>; // static constant of state name
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace traits
|
} // namespace traits
|
||||||
|
|
||||||
|
} // namespace mcc::fsm
|
||||||
namespace fsm
|
|
||||||
{
|
|
||||||
|
|
||||||
// GET INDEX OF GIVEN TYPE IN UNIQUE TUPLE
|
|
||||||
namespace details
|
|
||||||
{
|
|
||||||
|
|
||||||
// template <typename T, mcc::traits::unique_tuple_c UT, std::size_t I = 0>
|
|
||||||
template <typename T, typename TupleT, std::size_t I = 0>
|
|
||||||
struct unique_tuple_type_index_helper_t;
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename HeadT, typename... TailT, std::size_t I>
|
|
||||||
struct unique_tuple_type_index_helper_t<T, std::tuple<HeadT, TailT...>, I> {
|
|
||||||
constexpr static std::size_t index = unique_tuple_type_index_helper_t<T, std::tuple<TailT...>, I + 1>::index;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename... TailT, std::size_t I>
|
|
||||||
struct unique_tuple_type_index_helper_t<T, std::tuple<T, TailT...>, I> {
|
|
||||||
constexpr static std::size_t index = I;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, std::size_t I>
|
|
||||||
struct unique_tuple_type_index_helper_t<T, std::tuple<>, I> {
|
|
||||||
constexpr static std::size_t index = std::numeric_limits<std::size_t>::max();
|
|
||||||
static_assert(false, "INVALID INPUT TYPE!");
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace details
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, mcc::traits::unique_tuple_c UT>
|
|
||||||
struct unique_tuple_type_index_t : details::unique_tuple_type_index_helper_t<T, typename UT::tuple_t, 0> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, mcc::traits::unique_tuple_c UT>
|
|
||||||
constexpr static std::size_t unique_tuple_type_index_v = unique_tuple_type_index_t<T, typename UT::tuple_t>::index;
|
|
||||||
|
|
||||||
} // namespace fsm
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc
|
|
||||||
|
|||||||
255
cxx/mcc_fsm_utils.h
Normal file
255
cxx/mcc_fsm_utils.h
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
||||||
|
|
||||||
|
/* FINITE-STATE MACHINE UTILITY TYPES DEFINITIONS:
|
||||||
|
* std::pair sequence holder, unique-type tuple ... */
|
||||||
|
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace mcc
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace traits
|
||||||
|
{
|
||||||
|
|
||||||
|
// A CONCEPT DEFINITION FOR std::pair
|
||||||
|
template <typename T>
|
||||||
|
concept std_pair_c = requires(T t) {
|
||||||
|
[]<typename T1, typename T2>(std::type_identity<std::pair<T1, T2>>) {
|
||||||
|
|
||||||
|
}(std::type_identity<std::remove_cvref_t<T>>());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // 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<F1, S1>, std::pair<F2, S2>, ... std::pair<FN, SN>,>
|
||||||
|
i.e. std::pair.first field type of sequence elements may be of different types,
|
||||||
|
the same is for std::pair.second field
|
||||||
|
*/
|
||||||
|
// template <traits::std_pair_c... pairs>
|
||||||
|
// struct pair_holder_t;
|
||||||
|
|
||||||
|
// template <traits::std_pair_c head, traits::std_pair_c... tail>
|
||||||
|
// struct pair_holder_t<head, tail...> {
|
||||||
|
// // using self_t = pair_holder_t<head, tail...>;
|
||||||
|
// // using self_data_t = std::tuple<head, tail...>;
|
||||||
|
// typedef pair_holder_t<head, tail...> self_t;
|
||||||
|
// typedef std::tuple<head, tail...> sequence_t;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// template <>
|
||||||
|
// struct pair_holder_t<> {
|
||||||
|
// // using self_data_t = std::tuple<>;
|
||||||
|
// typedef std::tuple<> sequence_t;
|
||||||
|
// constexpr static bool valid = true;
|
||||||
|
// };
|
||||||
|
|
||||||
|
template <traits::std_pair_c... pairs>
|
||||||
|
using pair_holder_t = std::tuple<pairs...>;
|
||||||
|
|
||||||
|
} // namespace fsm
|
||||||
|
|
||||||
|
|
||||||
|
namespace traits
|
||||||
|
{
|
||||||
|
|
||||||
|
// PAIR-SEQUENCE HOLDER CONCEPT DEFINITION
|
||||||
|
template <typename T>
|
||||||
|
concept pair_holder_c = requires {
|
||||||
|
[]<mcc::traits::std_pair_c... Ts>(std::type_identity<fsm::pair_holder_t<Ts...>>) {
|
||||||
|
//
|
||||||
|
}(std::type_identity<std::remove_cvref_t<T>>());
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace traits
|
||||||
|
|
||||||
|
|
||||||
|
namespace fsm
|
||||||
|
{
|
||||||
|
|
||||||
|
/* A CLASS TO FIND TYPE OF pair.second FIELD BY ITS pair.first ONE IN PAIR-SEQUENCE */
|
||||||
|
|
||||||
|
template <typename FirstT, traits::pair_holder_c PHLDT>
|
||||||
|
struct pair_holder_find_t;
|
||||||
|
|
||||||
|
template <typename FirstT, typename CurrentFirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
||||||
|
struct pair_holder_find_t<FirstT, pair_holder_t<std::pair<CurrentFirstT, SecondT>, tail...>>
|
||||||
|
: pair_holder_find_t<FirstT, pair_holder_t<tail...>> {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FirstT>
|
||||||
|
struct pair_holder_find_t<FirstT, pair_holder_t<>> {
|
||||||
|
typedef std::nullptr_t result_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
||||||
|
struct pair_holder_find_t<FirstT, pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
||||||
|
typedef SecondT result_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A CLASS TO GET ALL pair.first FIELD TYPES IN PAIR-SEQUENCE */
|
||||||
|
|
||||||
|
template <traits::pair_holder_c PHLDT>
|
||||||
|
struct pair_holder_first_t;
|
||||||
|
|
||||||
|
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
||||||
|
struct pair_holder_first_t<pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
||||||
|
typedef decltype(std::tuple_cat(
|
||||||
|
std::declval<std::tuple<FirstT>>(),
|
||||||
|
std::declval<typename pair_holder_first_t<pair_holder_t<tail...>>::first_t>())) first_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct pair_holder_first_t<pair_holder_t<>> {
|
||||||
|
typedef std::tuple<> first_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* A CLASS TO GET ALL pair.second TYPES IN PAIR-SEQUENCE */
|
||||||
|
|
||||||
|
template <traits::pair_holder_c PHLDT>
|
||||||
|
struct pair_holder_second_t;
|
||||||
|
|
||||||
|
template <typename FirstT, typename SecondT, mcc::traits::std_pair_c... tail>
|
||||||
|
struct pair_holder_second_t<pair_holder_t<std::pair<FirstT, SecondT>, tail...>> {
|
||||||
|
typedef decltype(std::tuple_cat(
|
||||||
|
std::declval<std::tuple<SecondT>>(),
|
||||||
|
std::declval<typename pair_holder_second_t<pair_holder_t<tail...>>::second_t>())) second_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct pair_holder_second_t<pair_holder_t<>> {
|
||||||
|
typedef std::tuple<> second_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A TYPE TO IMPLEMENT TUPLE OF UNIQUE TYPES */
|
||||||
|
|
||||||
|
template <typename... TYPEs>
|
||||||
|
class unique_tuple_t
|
||||||
|
{
|
||||||
|
template <typename IT, typename UniqTupleT>
|
||||||
|
struct in_tuple : in_tuple<IT, typename UniqTupleT::tuple_t> {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename IT, typename... Ts>
|
||||||
|
struct in_tuple<IT, std::tuple<Ts...>> : std::disjunction<std::is_same<IT, Ts>...> {
|
||||||
|
};
|
||||||
|
|
||||||
|
// insert
|
||||||
|
template <typename IT, typename UniqTupleT, bool = in_tuple<IT, UniqTupleT>::value>
|
||||||
|
struct insert;
|
||||||
|
|
||||||
|
template <typename IT, typename... Ts>
|
||||||
|
struct insert<IT, std::tuple<Ts...>, false> {
|
||||||
|
typedef std::tuple<IT, Ts...> tuple_t;
|
||||||
|
typedef std::tuple<> non_unique_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename IT, typename... Ts>
|
||||||
|
struct insert<IT, std::tuple<Ts...>, true> {
|
||||||
|
typedef std::tuple<Ts...> tuple_t;
|
||||||
|
typedef std::tuple<IT> non_unique_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// merge
|
||||||
|
template <typename ITupleT, typename OTupleT>
|
||||||
|
struct merge;
|
||||||
|
|
||||||
|
template <typename MT, typename... MTs, typename... OTs>
|
||||||
|
struct merge<std::tuple<MT, MTs...>, std::tuple<OTs...>> {
|
||||||
|
typedef merge<std::tuple<MTs...>, std::tuple<OTs...>> tail_t;
|
||||||
|
typedef insert<MT, typename tail_t::tuple_t> curr_tuple_t;
|
||||||
|
|
||||||
|
typedef typename curr_tuple_t::tuple_t tuple_t;
|
||||||
|
typedef decltype(std::tuple_cat(std::declval<typename curr_tuple_t::non_unique_t>(),
|
||||||
|
std::declval<typename tail_t::non_unique_t>())) non_unique_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... MTs>
|
||||||
|
struct merge<std::tuple<>, std::tuple<MTs...>> {
|
||||||
|
typedef std::tuple<MTs...> tuple_t;
|
||||||
|
typedef std::tuple<> non_unique_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename merge<std::tuple<TYPEs...>, std::tuple<>>::tuple_t tuple_t;
|
||||||
|
typedef typename merge<std::tuple<TYPEs...>, std::tuple<>>::non_unique_t non_unique_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fsm
|
||||||
|
|
||||||
|
|
||||||
|
namespace traits
|
||||||
|
{
|
||||||
|
|
||||||
|
// UNIQUE-TYPES TUPLE CONCEPT DEFINITION
|
||||||
|
template <typename T>
|
||||||
|
concept unique_tuple_c = requires {
|
||||||
|
[]<typename... Ts>(std::type_identity<fsm::unique_tuple_t<Ts...>>) {}(std::type_identity<std::remove_cvref_t<T>>());
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace traits
|
||||||
|
|
||||||
|
|
||||||
|
namespace fsm
|
||||||
|
{
|
||||||
|
|
||||||
|
// GET INDEX OF GIVEN TYPE IN UNIQUE TUPLE
|
||||||
|
namespace details
|
||||||
|
{
|
||||||
|
|
||||||
|
// template <typename T, mcc::traits::unique_tuple_c UT, std::size_t I = 0>
|
||||||
|
template <typename T, typename TupleT, std::size_t I = 0>
|
||||||
|
struct unique_tuple_type_index_helper_t;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, typename HeadT, typename... TailT, std::size_t I>
|
||||||
|
struct unique_tuple_type_index_helper_t<T, std::tuple<HeadT, TailT...>, I> {
|
||||||
|
constexpr static std::size_t index = unique_tuple_type_index_helper_t<T, std::tuple<TailT...>, I + 1>::index;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, typename... TailT, std::size_t I>
|
||||||
|
struct unique_tuple_type_index_helper_t<T, std::tuple<T, TailT...>, I> {
|
||||||
|
constexpr static std::size_t index = I;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, std::size_t I>
|
||||||
|
struct unique_tuple_type_index_helper_t<T, std::tuple<>, I> {
|
||||||
|
constexpr static std::size_t index = std::numeric_limits<std::size_t>::max();
|
||||||
|
static_assert(false, "INVALID INPUT TYPE!");
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace details
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, mcc::traits::unique_tuple_c UT>
|
||||||
|
struct unique_tuple_type_index_t : details::unique_tuple_type_index_helper_t<T, typename UT::tuple_t, 0> {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, mcc::traits::unique_tuple_c UT>
|
||||||
|
constexpr static std::size_t unique_tuple_type_index_v = unique_tuple_type_index_t<T, typename UT::tuple_t>::index;
|
||||||
|
|
||||||
|
} // namespace fsm
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mcc
|
||||||
Loading…
x
Reference in New Issue
Block a user