Not every compiler defines these macros. Let alone, not every compiler properly implements what it advertises. I think it depends on the compiler - the current crop of the latest are
pretty good at getting these right.
Also, library-defined macros are worthless as they only allow one to know the feature is/isn't supported after including the header, i.e. after the fact. C++20 <version> fixes this, but C++20 is a too high minimum bar to target. Sort of, you know that Boost.Config uses <version> wherever possible already? It does so even in non-C++20 mode since the header is just a bunch of #defines and is perfectly usable back to C++98 if it exists.
So no, feature macros do not replace Boost.Config. In fact, I'd prefer to continue using Boost.Config in new libraries.
There are still plenty of things Boost.Config is good for: particularly where getting the configuration correct is tricky - for example if you want to use <header> then you need to know both that it exists via __has_include, but also that the current language standard is sufficient to parse the header, and that it has been been fully implemented. On the other hand, for the suggested BOOST_NO_CXX20_CONSTEXPR, Boost.Config would implement this trivially as (__cpp_constexpr < 201907L) which is a less obvious win - except perhaps to save folks having to look up the value - which now I come to think about it, might be a win after all given that it's value is not 202002L ;) John.