template<class _Ptr,
class _Ty>
using _Rebind_pointer_t = typename pointer_traits<_Ptr>::template rebind<_Ty>;
template<class _Ty>
struct pointer_traits
{ // defines traits for arbitrary pointers
using element_type = typename _Get_element_type<_Ty>::type;
using pointer = _Ty;
using difference_type = typename _Get_ptr_difference_type<_Ty>::type;
template<class _Other>
using rebind = typename _Get_rebind_alias<_Ty, _Other>::type;
using _Reftype = conditional_t<is_void_v<element_type>,
char&,
add_lvalue_reference_t<element_type>>;
_NODISCARD static pointer pointer_to(_Reftype _Val)
{ // convert raw reference to pointer
return (_Ty::pointer_to(_Val));
}
};
// STRUCT TEMPLATE _Get_rebind_alias
template<class _Ty,
class _Other,
class = void>
struct _Get_rebind_alias
{ // provide fallback
using type = typename _Replace_first_parameter<_Other, _Ty>::type;
};
template<class _Newfirst,
class _Ty>
struct _Replace_first_parameter;
template<class _Newfirst,
template<class, class...> class _Ty,
class _First,
class... _Rest>
struct _Replace_first_parameter<_Newfirst, _Ty<_First, _Rest...>>
{ // given _Ty<_First, _Rest...>, replace _First
using type = _Ty<_Newfirst, _Rest...>;
};