-
https://github.com/llvm-mirror/libcxx/commit/42e55e932e173eb224997fe11f0d15a1d74b29dc
-
https://github.com/llvm-mirror/libcxx/commit/a3ccd96ede26a2f383328234e01eb7a9f870691e
前面的uuu make u tuple u index实现导致了O(N)个实例化
而且效率很低。C++14 uu生成u整数u序列的实现
richard smith提供的一个非常好的Log8(N)实现。
由于libc++无法在C++11中公开名称“integer_sequence”,因此此修补程序
还引入了生成时使用的伪类型“\uuuu integer\u sequence”
顺序。生成的序列中的一个“\u整数\u序列”可以是
转换为所需类型;“元组索引”或“整数序列”。
从提交中,我知道这是一个Log8(N)实现,它手动展开循环(如果不正确,请纠正我,thx)。但我不明白怎么做
namespace detail
合作
__integer_sequence
. 我尝试过使用调试器,但它总是使用
__has_builtin(__make_integer_seq) branch
.
所以,请帮助我理解这个实现,主要代码在
this commit
和
this part of
<utility>
:
// <utility>
template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked =
typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
template <class _Tp, _Tp _Ep>
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 <class _Tp, _Tp _Ep>
using __make_integer_sequence = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
// <__tuple>
template <class _IdxType, _IdxType... _Values>
struct __integer_sequence {
template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
using __convert = _ToIndexSeq<_ToIndexType, _Values...>;
template <size_t _Sp>
using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
};
template<typename _Tp, size_t ..._Extra> struct __repeat;
template<typename _Tp, _Tp ..._Np, size_t ..._Extra> 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<size_t _Np> struct __parity;
template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
template<> struct __make<0> { typedef __integer_sequence<size_t> type; };
template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; };
template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; };
template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; };
template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; };
template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
} // namespace detail
提前谢谢。
如果你觉得这个问题太过分了,请告诉我。我很快就会删除,尽管这个问题确实让我很烦恼。