[libcxx] r185343 - Implement n3658 - Compile-time integer sequences

Richard Smith richard at metafoo.co.uk
Mon Jul 1 17:05:23 PDT 2013


On Mon, Jul 1, 2013 at 12:45 PM, Howard Hinnant <hhinnant at apple.com> wrote:
> On Jul 1, 2013, at 1:43 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
>> On Mon, Jul 1, 2013 at 9:26 AM, Marshall Clow <mclow at qualcomm.com> wrote:
>>> Author: marshall
>>> Date: Mon Jul  1 11:26:55 2013
>>> New Revision: 185343
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=185343&view=rev
>>> Log:
>>> Implement n3658 - Compile-time integer sequences
>>>
>>> +#if _LIBCPP_STD_VER > 11
>>> +
>>> +template<class _Tp, _Tp... _Ip>
>>> +struct integer_sequence
>>> +{
>>> +    typedef _Tp value_type;
>>> +    static_assert( is_integral<_Tp>::value,
>>> +                  "std::integer_sequence can only be instantiated with an integral type" );
>>> +    static
>>> +    _LIBCPP_INLINE_VISIBILITY
>>> +    constexpr
>>> +    size_t
>>> +    size() noexcept { return sizeof...(_Ip); }
>>> +};
>>> +
>>> +template<size_t... _Ip>
>>> +    using index_sequence = integer_sequence<size_t, _Ip...>;
>>> +
>>> +template <class _Tp, _Tp _Sp, _Tp _Ep, class _IntSequence>
>>> +struct __make_integer_sequence_unchecked;
>>> +
>>> +template <class _Tp, _Tp _Sp, _Tp _Ep, _Tp ..._Indices>
>>> +struct __make_integer_sequence_unchecked<_Tp, _Sp, _Ep,
>>> +                                         integer_sequence<_Tp, _Indices...>>
>>> +{
>>> +    typedef typename __make_integer_sequence_unchecked
>>> +                     <
>>> +                        _Tp, _Sp+1, _Ep,
>>> +                        integer_sequence<_Tp, _Indices..., _Sp>
>>
>> This is O(n^2). You can do it in O(n log n):
>>
>> template<typename T, T N, T Parity> struct __make_integer_sequence;
>> template<typename T, T N> using make_integer_sequence =
>> __make_integer_sequence<T, N, N % 2>::type;
>>
>> template<typename T> struct __make_integer_sequence<T, 0, 0> { typedef
>> integer_sequence<T> type; };
>> template<typename T> struct __make_integer_sequence<T, 1, 1> { typedef
>> integer_sequence<T, 0> type; };
>>
>> template<typename T, T ...Extra> struct __make_integer_sequence_impl;
>> template<typename T, T ...N, T ...Extra> struct
>> __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> {
>>  typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
>> };
>>
>> template<typename T, T N> struct __make_integer_sequence<T, N, 0> {
>>  typedef __make_integer_sequence_impl<make_integer_sequence<T, N /
>> 2>>::type type;
>> };
>> template<typename T, T N> struct __make_integer_sequence<T, N, 1> {
>>  typedef __make_integer_sequence_impl<make_integer_sequence<T, N /
>> 2>, N>::type type;
>> };
>
> This is an interesting suggestion, thanks.  I think it has the potential to make make_integer_sequence much more robust against exceeding recursive template instantiation limits.  However as suggested, the above doesn't compile.  After working with it for a while I got it to compile, but then it didn't give the desired results.

Sorry about that, I forgot to mention that the above was just a sketch
and I'd not actually run it through a compiler...




More information about the cfe-commits mailing list