#pragma once /* MOUNT CONTROL COMPONENTS LIBRARY */ /* FINITE-STATE MACHINE IMPLEMENTATION */ #include #include #include #include namespace mcc { 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>()); }; } // 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