boost源码阅读笔记1 - core\pointer_traits.hpp

 非特殊说明所有定义均在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取地址,如果类型不符就调用->获取对象,再次调用。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值