If all you want are textual substitutions, you can use the C preprocessor in front of any language.
You will be paddling upriver if that language doesn't have a mostly C-compatible token structure, or has white space sensitivities that C preprocessing doesn't preserve and such.
C macros operate on arbitrary tokens, which get converted to code or constants. For example variadic functions can be implemented to act on token arglists that act as abstract tuples: https://github.com/FrozenVoid/C-headers/blob/main/argmanip.h
It's an explicit goal of the language that you can tell what the local control flow is by reading the code, but of course one is free to run the C preprocessor as part of the build if one disagrees.
I don't think C++ constexpr/consteval can be used to write things like generic json serializers and deserializers, which Zig does in the standard library using comptime, but I'm not sure.
It could be fixing shortcomings of the languages without a huge complicated system that needs to be built into the language (and if it isn't, you can't just switch languages).
It could be dirty hacks that abstract a problem at the syntactic level (this is the kind of macro that is most likely to be replaced).