Skip to content

Commit 61c0251

Browse files
optimize integer_sequence when no builtin is available
when `T` is other than `std::size_t` (here `int`): compiler | gcc-15 | clang-20 before | 0:00.14s - 47220K | 0:00.23s - 107632K after | 0:00.12s - 42344K | 0:00.23s - 107344K when `T` is `std::size_t`: compiler | gcc-15 | clang-20 before | 0:00.13s - 46600K | 0:00.22s - 107228K after | 0:00.09s - 39808K | 0:00.15s - 94860K ```cpp using T = int; template<class I> using test = make_integer_sequence<T, I::value>; using r1 = mp_transform<test, mp_iota_c<200>>; ```
1 parent 60b4fd3 commit 61c0251

1 file changed

Lines changed: 17 additions & 35 deletions

File tree

include/boost/mp11/integer_sequence.hpp

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -47,60 +47,42 @@ template<class T, T N> using make_integer_sequence = integer_sequence<T, __integ
4747
// detail::make_integer_sequence_impl
4848
namespace detail
4949
{
50+
template<bool, std::size_t N, class L>
51+
struct iseq_expand;
5052

51-
// iseq_if_c
52-
template<bool C, class T, class E> struct iseq_if_c_impl;
53-
54-
template<class T, class E> struct iseq_if_c_impl<true, T, E>
55-
{
56-
using type = T;
57-
};
58-
59-
template<class T, class E> struct iseq_if_c_impl<false, T, E>
53+
template<std::size_t N, std::size_t... I>
54+
struct iseq_expand<false, N, integer_sequence<std::size_t, I...>>
6055
{
61-
using type = E;
56+
using type = integer_sequence<std::size_t, I..., (N+I)...>;
6257
};
6358

64-
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
65-
66-
// iseq_identity
67-
template<class T> struct iseq_identity
59+
template<std::size_t N, std::size_t... I>
60+
struct iseq_expand<true, N, integer_sequence<std::size_t, I...>>
6861
{
69-
using type = T;
62+
using type = integer_sequence<std::size_t, I..., (N+I)..., N * 2>;
7063
};
7164

72-
template<class S1, class S2> struct append_integer_sequence;
65+
template<class T, class L> struct convert_integer_sequence;
7366

74-
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
67+
template<class T, std::size_t... I> struct convert_integer_sequence<T, integer_sequence<std::size_t, I...>>
7568
{
76-
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
69+
using type = integer_sequence<T, I...>;
7770
};
7871

79-
template<class T, T N> struct make_integer_sequence_impl;
80-
81-
template<class T, T N> struct make_integer_sequence_impl_
72+
template<class T, T N> struct make_integer_sequence_impl
8273
{
83-
private:
84-
8574
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
8675

87-
static T const M = N / 2;
88-
static T const R = N % 2;
89-
90-
using S1 = typename make_integer_sequence_impl<T, M>::type;
91-
using S2 = typename append_integer_sequence<S1, S1>::type;
92-
using S3 = typename make_integer_sequence_impl<T, R>::type;
93-
using S4 = typename append_integer_sequence<S2, S3>::type;
94-
95-
public:
96-
97-
using type = S4;
76+
using type = typename convert_integer_sequence<T, typename make_integer_sequence_impl<std::size_t, N>::type>::type;
9877
};
9978

100-
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
79+
template<std::size_t N> struct make_integer_sequence_impl<std::size_t, N> : iseq_expand<N & 1, N / 2, typename make_integer_sequence_impl<std::size_t, N / 2>::type>
10180
{
10281
};
10382

83+
template<> struct make_integer_sequence_impl<std::size_t, 0> { using type = integer_sequence<std::size_t>; };
84+
template<> struct make_integer_sequence_impl<std::size_t, 1> { using type = integer_sequence<std::size_t, 0>; };
85+
10486
} // namespace detail
10587

10688
// make_integer_sequence

0 commit comments

Comments
 (0)