For debugging, often it helps to just stop the meta-program at some point and show a type that is the result of some type computation. This can be achieved like this:
template
struct mp_debug : T::MP_DEBUG_FORCE_COMPILE_FAILURE {};
using Foo = int; // type to be inspected
// usage at namespace scope
template struct mp_debug;
// usage at function scope
int main() {
mp_debug{};
}
This causes the compiler to print a compile-time error that shows the evaluated type argument of mp_debug.