#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