GCC STL源码学习(四) —— tuple

tuple

1主要代码

1.1 __empty_not_final

template <typename _Tp>
struct __is_empty_non_tuple : is_empty<_Tp> {
   };

// Using EBO for elements that are tuples causes ambiguous base errors.
template <typename _El0, typename... _El>
struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type {
   };

// Use the Empty Base-class Optimization for empty, non-final types.
template <typename _Tp>
using __empty_not_final = typename conditional<__is_final(_Tp), false_type, __is_empty_non_tuple<_Tp>>::type;

1.2 _Head_base

template <size_t _Idx, typename _Head, bool = __empty_not_final<_Head>::value>
struct _Head_base;

template <size_t _Idx, typename _Head>
struct _Head_base<_Idx, _Head, true> : public _Head {
   
    constexpr _Head_base() : _Head() {
   }

    constexpr _Head_base(const _Head &__h) : _Head(__h) {
   }

    constexpr _Head_base(const _Head_base &) = default;
    constexpr _Head_base(_Head_base &&) = default;

    template <typename _UHead>
    constexpr _Head_base(_UHead &&__h) : _Head(std::forward<_UHead>(__h)) {
   }

    // 省去allocator相关的内容

    static constexpr _Head &_M_head(_Head_base &__b) noexcept {
    return __b; }

    static constexpr const _Head &_M_head(const _Head_base &__b) noexcept {
    return __b; }
};

template <size_t _Idx, typename _Head>
struct _Head_base<_Idx, _Head, false> {
   
    constexpr _Head_base() : _M_head_impl() {
   }

    constexpr _Head_base(const _Head &__h) : _M_head_impl(__h) {
   }

    constexpr _Head_base(const _Head_base &) = default;
    constexpr _Head_base(_Head_base &&) = default;

    template <typename _UHead>
    constexpr _Head_base(_UHead &&__h) : _M_head_impl(std::forward<_UHead>(__h)) {
   }

	// 省去了一些allocator相关的内容
    
    static constexpr _Head &_M_head(_Head_base &__b) noexcept {
    return __b._M_head_impl; }

    static constexpr const _Head &_M_head(const _Head_base &__b) noexcept {
    return __b._M_head_impl; }

    _Head _M_head_impl;
};

这个类是为下面的impl服务的,保存的是tuple中模板参数类型的第一个类型数据。对于__empty_not_finalfalse的场景,模板参数_Idx为impl的当前索引,_Head为当前索引对应的类型,成员变量_M_head_impl为它的实际,即tuple中对应索引的类型的实际值。注意到其中的_M_head函数,返回的就是这个值。

1.3 impl

impl0
/**
 * Contains the actual implementation of the @c tuple template, stored
 * as a recursive inheritance hierarchy from the first element (most
 * derived class) to the last (least derived class). The @c Idx
 * parameter gives the 0-based index of the element stored at this
 * point in the hierarchy; we use it to implement a constant-time
 * get() operation.
 */
template <size_t _Idx, typename... _Elements>
struct _Tuple_impl;

_Tuple_impl包含了对tuple模板的真正实现,用的是递归继承的方式。_Idx是元素的索引。结合下面的叙述,举个例子讲述一下这里面提到的“递归继承”。

// 如果我们定义了这么一个tuple
tuple<int, float, string>;

// 那么,在tuple类里面,会有这样的对impl的一个调用。
_Tuple_impl<0, int, float, string>; // 这里调用的是impl1

// 递归地,有:
_Tuple_impl<1, float, string>; // 仍然调用impl1
_Tuple_impl<2, string>;        // 这里是impl2,即这个递归的基本项(basic case)
impl1
/**
 * Recursive tuple implementation. Here we store the @c Head element
 * and derive from a @c Tuple_impl containing the remaining elements
 * (which contains the @c Tail).
 */
template <size_t _Idx, typename _Head, typename... _Tail>
struct _Tuple_impl<_Idx, _Head, _Tail...> : public _Tuple_impl<_Idx + 1, _Tail...>,
                                            private _Head_base<_Idx, _Head> {
   
    template <size_t, typename...>
    friend struct _Tuple_impl;

    typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
    typedef _Head_base<_Idx, _Head> _Base;

    static constexpr _Head &_M_head(_Tuple_impl &__t) noexcept {
    return _Base::_M_head(__t); }

    static constexpr const _Head &_M_head(const _Tuple_impl &__t) noexcept {
    return _Base::_M_head(__t); }

    static constexpr _Inherited &_M_tail(_Tuple_impl &__t) noexcept {
    return __t; }

    static constexpr const _Inherited &_M_tail(const _Tuple_impl &__t) noexcept {
    return __t; }

    constexpr _Tuple_impl() : _Inherited(), _Base() {
   }

    explicit constexpr _Tuple_impl(const _Head &__head, const _Tail &...__tail)
        : _Inherited(__tail...), _Base(__head) {
   }

    template <typename _UHead, typename... _UTail, typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
    explicit constexpr _Tuple_impl(_UHead &&__head, _UTail &&...__tail)
        : _Inherited(std::forward<_UTail>(__tail)...), _Base(std::forward<_UHead>(__head)) {
   }

    constexpr _Tuple_impl(const _Tuple_impl &) = default;

    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 2729. Missing SFINAE on std::pair::operator=
    _Tuple_impl &operator=(const _Tuple_impl &) = delete;

    constexpr _Tuple_impl(_Tuple_impl &&__in) noexcept(
        __and_<is_nothrow_move_constructible<_Head>, is_nothrow_move_constructible<_Inherited>>::value)
        : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) {
   }

    template <typename... _UElements>
    constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...> &__in)
        : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
          _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) {
   }

    template <typename _UHead, typename... _UTails>
    constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...> &&__in)
        : _Inherited(std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
          _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) {
   }

    // 省去一些allocator相关的东西,区别主要在内存分配上,整体逻辑相似。
                                                
    template <typename... _UElements>
    _GLIBCXX20_CONSTEXPR void _M_assign(const _Tuple_impl<_Idx, _UElements...> &__in) {
   
        _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
        _M_tail(*thi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值