:
template<class...>struct types {};
template<class lhs, class rhs>struct e{};
template<class types, class lhs>
struct find{};
template<class types, class lhs>
using find_t=typename find<types,lhs>::type;
template<class T0, class R0, class...Ts>
struct find< types<e<T0,R0>,Ts...>, T0>{
using type=R0;
};
template<class T0, class R0, class...Ts, class lhs>
struct find< types<e<T0,R0>,Ts...>, lhs>:
find< types<Ts...>, lhs >
{};
:
template<PinEnum e>
using PinEnum_t = std::integral_constant<PinEnum, e>;
template<uint16_t i>
using uint16 = std::integral_constant<uint16_t, i>;
using PinGetPin_t = types<
e<PinEnum_t<kPinA0>, uint16<GPIOA>>,
e<PinEnum_t<kPinA1>, uint16<GPIOA>>,
e<PinEnum_t<kPinC1>, uint16<GPIOC>>
>;
static_assert( find_t<PinGetPin_t, PinEnum_t<kPinA0>>{}==GPIOA, "oops");
.
.
, "--". "--" PinEnum_t
..