MSVC recently implemented the following intrinsics needed for P0466R5 Layout-compatibility and Pointer-interconvertibility Traits: * __builtin_is_layout_compatible * __builtin_is_pointer_interconvertible_base_of * __builtin_is_pointer_interconvertible_with_class * __builtin_is_corresponding_member MSVC STL is planning to use them in <type_traits> as follows (PR: https://github.com/microsoft/STL/pull/1575): // STRUCT TEMPLATE is_layout_compatible template <class _Ty1, class _Ty2> struct is_layout_compatible : bool_constant<__builtin_is_layout_compatible(_Ty1, _Ty2)> {}; template <class _Ty1, class _Ty2> inline constexpr bool is_layout_compatible_v = __builtin_is_layout_compatible(_Ty1, _Ty2); // STRUCT TEMPLATE is_pointer_interconvertible_base_of template <class _Base, class _Derived> struct is_pointer_interconvertible_base_of : bool_constant<__builtin_is_pointer_interconvertible_base_of(_Base, _Derived)> {}; template <class _Base, class _Derived> inline constexpr bool is_pointer_interconvertible_base_of_v = __builtin_is_pointer_interconvertible_base_of( _Base, _Derived); // FUNCTION TEMPLATE is_pointer_interconvertible_with_class template <class _ClassTy, class _MemberTy> _NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::*_Pm) noexcept { return __builtin_is_pointer_interconvertible_with_class(_ClassTy, _Pm); } // FUNCTION TEMPLATE is_corresponding_member template <class _ClassTy1, class _ClassTy2, class _MemberTy1, class _MemberTy2> _NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::*_Pm1, _MemberTy2 _ClassTy2::*_Pm2) noexcept { return __builtin_is_corresponding_member(_ClassTy1, _ClassTy2, _Pm1, _Pm2);
Do we know why MSVC has deviated from the longstanding rule that compiler intrinsic forms of type traits are named by prefixing simply __ to the name? (Eg, __is_layout_compatible, __is_pointer_interconvertible_base_of, __is_pointer_interconvertible_with_class, __is_corresponding_member.) In particular, if MSVC is avoiding name collisions with something, will we need to avoid adding the normal name in addition to the __builtin_ name?
(In reply to Richard Smith from comment #1) > Do we know why MSVC has deviated from the longstanding rule that compiler > intrinsic forms of type traits are named by prefixing simply __ to the name? > (Eg, __is_layout_compatible, __is_pointer_interconvertible_base_of, > __is_pointer_interconvertible_with_class, __is_corresponding_member.) > > In particular, if MSVC is avoiding name collisions with something, will we > need to avoid adding the normal name in addition to the __builtin_ name? Agree and thanks for catching this. In the past we've used the __builtin* form; e.g. __builtin_zero_non_value_bits, however not in <type_traits>. We will rename the intrinsics to follow the __is_* form instead. The change should appear in Visual Studio 2019 version 16.10 preview 1. I will update this bug report once those renames are shipped.
Update: The C++ toolset update renaming the intrinsics (removing the __builtin prefix) has shipped with VS 2019 preview 1. MSVC STL moved to the new names as well: https://github.com/microsoft/STL/pull/1711/files
With the latest MSVC update, the intrinsic names are: * __is_layout_compatible * __is_pointer_interconvertible_base_of * __is_pointer_interconvertible_with_class * __is_corresponding_member