非特殊说明所有定义均在boost::detail名称空间下定义
1. ptr_none,ptr_valid,ptr_first
struct ptr_none { };
template<class>
struct ptr_valid {
using type = void;
};
ptr_none可能是以后用来占位使用,ptr_valid是来当作判断条件的,条件成立后类型等同于void。
ptr_valid<T::xx>::type
比如上面这个例子,如果T类有xx就选择某个偏特化模板。
template<class>
struct ptr_first {
using type = ptr_none;
};
template<template<class, class...> class T, class U, class... Args>
struct ptr_first<T<U, Args...> > {
using type = U;
};
ptr_first就是说如果参数是个类模板,type=类模板第一个参数的类型,否则type=占位类型
2. ptr_element,ptr_difference
template<class T, class = void>
struct ptr_element {
using type = typename ptr_first<T>::type;
};
template<class T>
struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
using type = typedef typename T::element_type;
};
ptr_element就是说如果类定义了element_type,type就是element_type定义的类型,否则就是类第一个参数类型。
template<class, class = void>
struct ptr_difference {
using type = std::ptrdiff_t;
};
template<class T>
struct ptr_difference<T,
typename ptr_valid<typename T::difference_type>::type> {
using type = typename T::difference_type;
};
跟上面差不多,不解释
3.ptr_transform,ptr_rebind
template<class, class>
struct ptr_transform { };
template<template<class, class...> class T, class U, class... Args, class V>
struct ptr_transform<T<U, Args...>, V> {
using type = T<V, Args...>;
};
ptr_transform,第一个参数是类模板,第二个参数是替换进去的类型,会替换类模板中第一个参数类型。
template<class T, class U, class = void>
struct ptr_rebind
: ptr_transform<T, U> { };
template<class T, class U>
struct ptr_rebind<T, U,
typename ptr_valid<typename T::template rebind<U> >::type> {
using type = typename T::template rebind<U>;
};
ptr_rebind,如果类型T定义了rebind<U>,类型参数为T,U是type为所定义的rebind<U>类型,否则按照ptr_transform来处理用U替换掉类型T中第一个类型参数。
4.ptr_to_expr,ptr_has_to,ptr_to
template<class T, class E>
class ptr_to_expr {
template<class>
struct result {
char x, y;
};
static E& source();
template<class O>
static auto check(int) -> result<decltype(O::pointer_to(source()))>;
template<class>
static char check(long);
public:
static constexpr bool value = sizeof(check<T>(0)) > 1;
};
template<class T, class E>
struct ptr_to_expr<T*, E> {
static constexpr bool value = true;
};
template<class T, class E>
struct ptr_has_to {
static constexpr bool value = ptr_to_expr<T, E>::value;
};
template<class T>
struct ptr_has_to<T, void> {
static constexpr bool value = false;
};
template<class T>
struct ptr_has_to<T, const void> {
static constexpr bool value = false;
};
template<class T>
struct ptr_has_to<T, volatile void> {
static constexpr bool value = false;
};
template<class T>
struct ptr_has_to<T, const volatile void> {
static constexpr bool value = false;
};
首先分析一下,下面这段
static E& source();
template<class O>
static auto check(int) -> result<decltype(O::pointer_to(source()))>;template<class>
static char check(long);public:
static constexpr bool value = sizeof(check<T>(0)) > 1;
这里利用的是0先匹配int的优先级更高,如果O::pointer_to()可以使用E&作为参数,那么得到的类型就是他的返回值类型,否则匹配long,返回char类型。
template<class T, class E, bool = ptr_has_to<T, E>::value>
struct ptr_to { };
template<class T, class E>
struct ptr_to<T, E, true> {
static T pointer_to(E& v) {
return T::pointer_to(v);
}
};
template<class T>
struct ptr_to<T*, T, true> {
static T* pointer_to(T& v) noexcept {
return boost::addressof(v);
}
};
ptr_to_expr和ptr_has_to都是为了ptr_to服务,ptr_to应该是从E中获取指针T的操作,如果获取的是就是本类型的指针,则使用boost::addressof直接取地址,否则就使用T的静态函数pointer_to,将类型E转化。
5.ptr_traits,to_address
template<class T, class E>
struct ptr_traits
: ptr_to<T, E> {
using pointer = T;
using element_type = E;
using difference_type = typename ptr_difference<T>::type;
template<class U>
struct rebind_to
: ptr_rebind<T, U> { };
template<class U>
using rebind = typename rebind_to<U>::type;
};
template<class T>
struct ptr_traits<T, ptr_none> { };
/*定义在boost名称空间下*/
template<class T>
struct pointer_traits
: detail::ptr_traits<T, typename ptr_element<T>::type> { };
template<class T>
struct pointer_traits<T*>
: detail::ptr_to<T*, T> {
using pointer = T*;
using element_type = T;
using difference_type = std::ptrdiff_t;
template<class U>
struct rebind_to {
typedef U* type;
};
template<class U>
using rebind = typename rebind_to<U>::type;
};
相当于合集,不解释。注意pointer_traits是定义在boost名称空间下面的,不是boost::detail名称空间。
namespace detail {
template<class T>
inline T* ptr_address(T* v, int) noexcept
{
return v;
}
template<class T>
inline auto ptr_address(const T& v, long) noexcept
{
return boost::detail::ptr_address(v.operator->(), 0);
}
} /* detail */
template<class T>
constexpr inline T* to_address(T* v) noexcept
{
return v;
}
template<class T>
inline auto to_address(const T& v) noexcept
{
return boost::detail::ptr_address(v, 0);
}
to_address取地址,如果类型不符就调用->获取对象,再次调用。