sách gpt4 ăn đã đi

c++ - 如何理解libcxx对make_integer_sequence的实现?

In lại 作者:太空狗 更新时间:2023-10-29 20:50:44 26 4
mua khóa gpt4 giày nike

我发现了两个相关的提交:

  1. https://github.com/llvm-mirror/libcxx/commit/42e55e932e173eb224997fe11f0d15a1d74b29dc
  2. https://github.com/llvm-mirror/libcxx/commit/a3ccd96ede26a2f383328234e01eb7a9f870691e

The previous __make_tuple_indices implementation caused O(N) instantiations and was pretty inefficient. The C++14 __make_integer_sequence implementation is much better, since it either uses a builtin to generate the sequence or a very nice Log8(N) implementation provided by richard smith.

This patch moves the __make_integer_sequence implementation into __tuple and uses it to implement __make_tuple_indices.

Since libc++ can't expose the name 'integer_sequence' in C++11 this patch also introduces a dummy type '__integer_sequence' which is used when generating the sequence. One the sequence is generated '__integer_sequence' can be converted into the required type; either '__tuple_indices' or 'integer_sequence'.


从提交中,我知道它是一个 Log8(N) 实现,它手动展开循环(如果不正确,请纠正我,thx)。但我无法理解 namespace detail __integer_sequence 一起工作.我曾尝试使用调试器,但它始终使用 __has_builtin(__make_integer_seq) branch .


所以,请帮助我理解这个实现,主要代码在this committhis part of :

// 
template using __make_integer_sequence_unchecked =
typename __detail::__make<_Np>::type::template __convert;

template
struct __make_integer_sequence_checked
{
static_assert(is_integral<_Tp>::value,
"std::make_integer_sequence can only be instantiated with an integral type" );
static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
// Workaround GCC bug by preventing bad installations when 0 <= _Ep
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
typedef __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
};

template
using __make_integer_sequence = typename __make_integer_sequence_checked<_Tp, _Ep>::type;

// <__tuple>

template
struct __integer_sequence {
template class _ToIndexSeq, class _ToIndexType>
using __convert = _ToIndexSeq<_ToIndexType, _Values...>;

template
using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
};

template struct __repeat;
template struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> {
typedef __integer_sequence<_Tp,
_Np...,
sizeof...(_Np) + _Np...,
2 * sizeof...(_Np) + _Np...,
3 * sizeof...(_Np) + _Np...,
4 * sizeof...(_Np) + _Np...,
5 * sizeof...(_Np) + _Np...,
6 * sizeof...(_Np) + _Np...,
7 * sizeof...(_Np) + _Np...,
_Extra...> type;
};

template struct __parity;
template struct __make : __parity<_Np % 8>::template __pmake<_Np> {};

template<> struct __make<0> { typedef __integer_sequence type; };
template<> struct __make<1> { typedef __integer_sequence type; };
template<> struct __make<2> { typedef __integer_sequence type; };
template<> struct __make<3> { typedef __integer_sequence type; };
template<> struct __make<4> { typedef __integer_sequence type; };
template<> struct __make<5> { typedef __integer_sequence type; };
template<> struct __make<6> { typedef __integer_sequence type; };
template<> struct __make<7> { typedef __integer_sequence type; };

template<> struct __parity<0> { template struct __pmake : __repeat::type> {}; };
template<> struct __parity<1> { template struct __pmake : __repeat::type, _Np - 1> {}; };
template<> struct __parity<2> { template struct __pmake : __repeat::type, _Np - 2, _Np - 1> {}; };
template<> struct __parity<3> { template struct __pmake : __repeat::type, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<4> { template struct __pmake : __repeat::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<5> { template struct __pmake : __repeat::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<6> { template struct __pmake : __repeat::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<7> { template struct __pmake : __repeat::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };

} // namespace detail

Cảm ơn trước.

如果您认为这个问题太边界/粗鲁,请随时告诉我。我会尽快删除,虽然这个问题确实很困扰我。

câu trả lời hay nhất

你还需要了解__repeat看看这是如何工作的:

template struct __repeat;
template struct __repeat, _Extra...> {
typedef integer_sequence<_Tp,
_Np...,
sizeof...(_Np) + _Np...,
2 * sizeof...(_Np) + _Np...,
3 * sizeof...(_Np) + _Np...,
4 * sizeof...(_Np) + _Np...,
5 * sizeof...(_Np) + _Np...,
6 * sizeof...(_Np) + _Np...,
7 * sizeof...(_Np) + _Np...,
_Extra...> type;
}

它需要两个模板参数:一个整数序列和一个参数包 _Extra值(value)观。

它有一个成员 typedef kiểu是与初始整数序列类型相同的整数序列。

它的成员如下:

_Np..., // The original values


sizeof...(_Np) + _Np...,
// sizeof...(_Np) is the number of integers in the sequence. This is a fold expression
// that adds the sizeof...(_Np) to every integer.

// So (_Np..., sizeof...(_Np) + _Np...) for <0, 1, 2> would be
// (<0, 1, 2>..., <3 + 0, 3 + 1, 3 + 2>...), which is `<0, 1, 2, 3, 4, 5>`.

// The rest of the lines are the same, but starting with a different
// multiple of sizeof...(_Np)

// `<0, 1, ..., N>` into an integer sequence of `<0, 1, ..., 8N>`.

_Extra...
// And then add `_Extra` to the end

__make<_Np>từ _Np = 0_Np = 7是硬编码的。否则,它使用 __parity作为辅助类型。

这将使用 __repeat重复 __make<_Np / 8> 8 次,创建所需的长度,然后根据它比最后一个 8 的倍数(此处称为“奇偶校验”)大多少来使用额外的项添加为 _Extra .

与其说是“手动展开循环”,倒不如说是“手动展开循环”。就是递归除make_integer_sequenceĐi vàorepeat_8_times<>> /* + remainder */ ,所以它是“基于基本情况的递归”

关于c++ - 如何理解libcxx对make_integer_sequence的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53350706/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress