...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The header <boost/core/pointer_traits.hpp> provides the class template
boost::pointer_traits
to facilitate use of pointer-like
types. The C++11 standard library introduced std::pointer_traits
along with an allocator model which supported pointer-like types in addition
to plain raw pointers. This implementation also supports C++98.
It also provides the function template boost::to_address
to obtain a raw pointer from an object of any pointer-like type.
The following example allocates storage and constructs an object in that storage using an allocator.
template<class Allocator> void function(Allocator& a) { auto p = a.allocate(1); std::allocator_traits<Allocator>::construct(a, boost::to_address(p)); }
namespace boost { template<class T> struct pointer_traits { typedef T pointer; typedef see below element_type; typedef see below difference_type; template<class U> struct rebind_to { typedef see below type; }; template<class U> using rebind = typename rebind_to<U>::type; static pointer pointer_to(element_type& v); }; template<class T> struct pointer_traits<T*> { typedef T* pointer; typedef T element_type; typedef std::ptrdiff_t difference_type; template<class U> struct rebind_to { typedef U* type; }; template<class U> using rebind = typename rebind_to<U>::type; static pointer pointer_to(see below v) noexcept; }; template<class T> constexpr T* to_address(T* v) noexcept; template<class T> auto to_address(const T& v) noexcept; } // boost
If the member type element_type
is not defined, then all other members are also not defined (pointer_traits
is SFINAE-friendly).
typedef
see
below element_type;
T::element_type
if such a type exists;
otherwise U
if T
is a class template instantiation
of the form Pointer<U, Args>
, where Args
is zero or more type arguments; otherwise the member is not defined.
typedef
see
below difference_type;
T::difference_type
if such a type
exists; otherwise std::ptrdiff_t
.
template<class U> struct
rebind_to {
typedef
see below
type;
};
type
is T::rebind<U>
if such a type exists; otherwise, Pointer<V, Args>
if T
is a class template instantiation of the form Pointer<T, Args>
, where Args
is zero or more type arguments; otherwise, the member is not defined.
Note | |
---|---|
When C++11 template aliases are not supported, the |
static pointer
pointer_traits::pointer_to(element_type&
v);
If element_type
is a void type, or if T::pointer_to(v)
is not well formed, this member
is not defined.
A pointer to v
obtained by calling T::pointer_to(v)
.
static pointer
pointer_traits<T*>::pointer_to(element_type&
v)
noexcept;
If element_type
is a void type, this member is not defined.
addressof(v)
.
static element_type* to_address(pointer
v)
noexcept;
A pointer of type element_type*
that references the same location
as the argument p
.
This function should be the inverse of pointer_to
.
If defined, it customizes the behavior of the non-member function
to_address
.
template<class T> constexpr
T*
to_address(T* v) noexcept;
v
.
template<class T> auto to_address(const T& v) noexcept;
pointer_traits<T>::to_address(v)
if that expression is well-formed,
otherwise to_address(v.operator->())
.
Glen Fernandes implemented pointer_traits
and to_address
with reviews
and guidance from Peter Dimov.