Speclib  0.1.2
The library for writing better CUDA libraries
sp::integer_sequence< T, Is > Class Template Reference

Encodes a sequence of integral type T. More...

#include <integer_sequence.hpp>

Public Types

using ValueType = T
 
using ThisType = integer_sequence< T, Is... >
 
template<T I>
using prepend = integer_sequence< T, I, Is... >
 An integer_sequence<T> with I added to the start. More...
 
template<T I>
using append = integer_sequence< T, Is..., I >
 An integer_sequence<T> with I added to the end. More...
 
template<int... Qs>
using pick = integer_sequence< T, get(Qs)... >
 An integer_sequence<T> composed of the elements from this list given by Qs.... More...
 
template<int Start, int End = Size>
using slice = decltype(sliceHelper< Start >(std::make_integer_sequence< int, End - Start >()))
 A list formed from elements in the range [Start, End). More...
 
template<typename O >
using cat = decltype(catifier(O{}))
 A list formed by concatenating this list with another one. More...
 
template<int J, T I>
using insert = typename slice< 0, J >::template append< I >::template cat< slice< J > >
 A list formed by adding an element at a given index into this list. More...
 
template<int Index, T NewValue>
using set = typename slice< 0, Index >::template append< NewValue >::template cat< slice< Index+1 > >
 A list equal to this one with one element changed. More...
 
template<int J>
using removeIndex = typename slice< 0, J >::template cat< slice< J+1 > >
 A list formed by removing the element at a given index in this list. More...
 
template<int Start, int End>
using removeRange = typename slice< 0, Start >::template cat< slice< End > >
 Remove a range of values from Start to End - 1 inclusive. More...
 
template<typename OtherList >
using merge = decltype(mergeHelper< OtherList >())
 Merge a sorted list with this also-sorted-list, as in merge sort. More...
 
template<T I>
using remove = removeIndex< Find< sp::tm::Eq< I > >()>
 Remove the first occurrence of value I. More...
 
template<typename Predicate , typename Defer = Deferred>
using filter = decltype(Defer::template indexFilterHelper< AsIndexPredicate< Predicate >::template S, 0 >())
 A list containing elements from this one that were chosen using a functor as a filter. More...
 
template<template< int > typename Predicate, typename Defer = Deferred>
using indexFilter = decltype(Defer::template indexFilterHelper< Predicate, 0 >())
 Filter the list using a predicate that takes index and value, forming a new list. More...
 
template<typename Lambda , typename OutType = T>
using map = integer_sequence< OutType, Lambda{}(Is)... >
 A new list formed by applying a unary functor to every element of this list. More...
 
template<typename TargetType >
using AsType = sp::integer_sequence< TargetType,(TargetType) Is... >
 Convert this to an integer sequence of a different type, relying on whatever conversions are available... More...
 
template<typename Defer = ThisType>
using unique = typename Defer::template indexFilter< UniqueFilter >
 A list formed of the unique elements of this list. More...
 
template<typename Defer = Deferred>
using sortedUnique = decltype(Defer::template sortedUniqueHelper())
 Get unique elements of a sorted list in linear time. More...
 
template<typename Defer = Deferred>
using sort = decltype(Defer::template sortHelper())
 A sorted version of this list. More...
 

Static Public Member Functions

constexpr static int binarySearch (T Needle, int Start=0, int End=Size)
 Find the index of the first value that is >= Needle. More...
 
constexpr static std::pair< int, int > binarySearchRange (T rangeStart, T rangeEnd, int Start=0, int End=Size)
 Find the indices of all values satisfying rangeStart <= X < rangeEnd in logarithmic time. (must be sorted). More...
 
constexpr static T get (int i)
 Get an element from the list. More...
 
constexpr static T last ()
 Get the last element from the list. More...
 
template<typename Predicate >
static constexpr int Find (int FromIndex=0)
 Return the index of the first element for which Predicate<I>::value is true, starting from index I, or -1 if there is no such element. More...
 
template<typename Predicate >
static constexpr int Find (Predicate lambda, int FromIndex=0)
 Return the index of the first element for which lambda(value) is true, starting from index I, or -1 if there is no such element. More...
 
static constexpr int indexOf (T x, int fromIndex=0)
 Find the index of the first occurence of x after index fromIndex, or -1 if it doesn't exist. More...
 
template<T... Xs>
static constexpr int indexOf (integer_sequence< T, Xs... > seq, int fromIndex=0)
 Find the index of the first time a given integer sequence occurs as a subsequence of this one. More...
 
template<T... Ts>
constexpr static bool StartsWith ()
 Determine if this list starts with the given sequence of values. More...
 
constexpr static bool contains (T I)
 Returns true iff the given element is in the list. More...
 

Static Public Attributes

constexpr static int Size = sizeof...(Is)
 
constexpr static bool Empty = Size == 0
 
constexpr static std::array< T, Size > Values {Is...}
 
template<typename OtherSeq >
constexpr static bool equals = std::is_same_v<ThisType, OtherSeq>
 Compare lists for equality. More...
 
template<typename Predicate >
static constexpr bool All = (Predicate{}(Is) && ...)
 True iff the given functor predicate matches all elements of the list. More...
 
template<typename Predicate >
static constexpr bool Any = (Predicate{}(Is) || ...)
 True iff the given functor predicate matches any element of the list. More...
 

Detailed Description

template<typename T, T... Is>
class sp::integer_sequence< T, Is >

Encodes a sequence of integral type T.

Conceptually similar to std::integer_sequence, but with a rich API that provides high-level list manipulations such as filtering, slicing, sorting, appending, etc.

// Filtering based on constexpr predicates.
// sp::integer_sequence<3>
using LT3 = L::template filter<sp::tm::Greater<2>::S>;
// Slicing
// sp::integer_sequence<1, 2>
using Prefix = L::slice<0, 2>
// Removal by value
// sp::integer_sequence<1, 3>
using Prefix = L::remove<2>
// Sorting (yes, really)
// sp::integer_sequence<1, 2, 3, 4, 5>
using Sorted = P::sort;
Encodes a sequence of integral type T.
Definition: integer_sequence.hpp:113
Template Parameters
TThe type of elements in the sequence.
IsThe elements of the list.

Member Typedef Documentation

◆ append

template<typename T , T... Is>
template<T I>
using sp::integer_sequence< T, Is >::append = integer_sequence<T, Is..., I>

An integer_sequence<T> with I added to the end.

Example

using B = A::append<1>; // 1, 2, 3, 1
using C = B::prepend<5>; // 5, 1, 2, 3, 1
Template Parameters
IThe value to append to this list.

◆ AsType

template<typename T , T... Is>
template<typename TargetType >
using sp::integer_sequence< T, Is >::AsType = sp::integer_sequence<TargetType, (TargetType) Is...>

Convert this to an integer sequence of a different type, relying on whatever conversions are available...

◆ cat

template<typename T , T... Is>
template<typename O >
using sp::integer_sequence< T, Is >::cat = decltype(catifier(O{}))

A list formed by concatenating this list with another one.

This list appears first, followed by the contents of the other one.

Example

using CatAB = A::cat<B>; // 1, 1, 2, 145
using CatBC = B::cat<C>; // 145, 9, 7, 23, 46
See also
cat_integer_sequences() for N-ary concatenation.
Template Parameters
OThe other list to join with this one.

◆ filter

template<typename T , T... Is>
template<typename Predicate , typename Defer = Deferred>
using sp::integer_sequence< T, Is >::filter = decltype(Defer::template indexFilterHelper<AsIndexPredicate<Predicate>::template S, 0>())

A list containing elements from this one that were chosen using a functor as a filter.

Example

// The elements of `AList` that are greater than 1.
using F = A::template filter<sp::tm::Greater<1>>; // 2, 3, 5
// The elements of `AList` that are less than or equal to 1.
using I = A::template filter<sp::tm::LessEq<1>>; // 1, 1
Template Parameters
PredicateThe predicate functor to use.

◆ indexFilter

template<typename T , T... Is>
template<template< int > typename Predicate, typename Defer = Deferred>
using sp::integer_sequence< T, Is >::indexFilter = decltype(Defer::template indexFilterHelper<Predicate, 0>())

Filter the list using a predicate that takes index and value, forming a new list.

◆ insert

template<typename T , T... Is>
template<int J, T I>
using sp::integer_sequence< T, Is >::insert = typename slice<0, J>::template append<I>::template cat<slice<J> >

A list formed by adding an element at a given index into this list.

Example

using InsertStart = A::insert<0, 42>;
using InsertEnd = A::insert<3, 42>;
using InsertEmpty = sp::int_sequence<>::insert<0, 42>; // 42
typename slice< 0, J >::template append< I >::template cat< slice< J > > insert
A list formed by adding an element at a given index into this list.
Definition: integer_sequence.hpp:336
Template Parameters
JThe target index. The new element is inserted at this position and all other elements shift to the right by one position. This index may be one beyond the end of this list, in which case the element is appended to the list. If it is otherwise out of bounds, the program refuses to compile.
IThe new element.

◆ map

template<typename T , T... Is>
template<typename Lambda , typename OutType = T>
using sp::integer_sequence< T, Is >::map = integer_sequence<OutType, Lambda{}(Is)...>

A new list formed by applying a unary functor to every element of this list.

Example

using IncrementedY = typename Y::template map<sp::tm::Add<1>>;
Template Parameters
LambdaA unary functor.

◆ merge

template<typename T , T... Is>
template<typename OtherList >
using sp::integer_sequence< T, Is >::merge = decltype(mergeHelper<OtherList>())

Merge a sorted list with this also-sorted-list, as in merge sort.

◆ pick

template<typename T , T... Is>
template<int... Qs>
using sp::integer_sequence< T, Is >::pick = integer_sequence<T, get(Qs)...>

An integer_sequence<T> composed of the elements from this list given by Qs....

If you want to use another integer_sequence to provide Qs..., you will have to use pattern matching to extract the template parameter.

Example

using PickedList = A::pick<0, 2, 4>;
Template Parameters
QsA parameter pack listing elements to take from this list.

◆ prepend

template<typename T , T... Is>
template<T I>
using sp::integer_sequence< T, Is >::prepend = integer_sequence<T, I, Is...>

An integer_sequence<T> with I added to the start.

Example

using B = A::append<1>; // 1, 2, 3, 1
using C = B::prepend<5>; // 5, 1, 2, 3, 1
Template Parameters
IThe value to prepend to this list.

◆ remove

template<typename T , T... Is>
template<T I>
using sp::integer_sequence< T, Is >::remove = removeIndex<Find<sp::tm::Eq<I> >()>

Remove the first occurrence of value I.

The value must be present in the list, otherwise the program will refuse to compile.

Example

using RemoveStartV = A::remove<1>; // 2, 3
using RemoveMiddleV = A::remove<2>; // 1, 3
using RemoveEndV = A::remove<3>; // 1, 2
using RemoveDup = B::remove<1>; // 2, 3, 1, 1, 2, 3
Template Parameters
IThe value to remove.

◆ removeIndex

template<typename T , T... Is>
template<int J>
using sp::integer_sequence< T, Is >::removeIndex = typename slice<0, J>::template cat<slice<J + 1> >

A list formed by removing the element at a given index in this list.

Example

using RemoveStart = A::removeIndex<0>; // 2, 3
using RemoveMiddle = A::removeIndex<2>; // 1, 3
using RemoveEnd = A::removeIndex<1>; // 1, 2
Template Parameters
JThe index of the element to remove.

◆ removeRange

template<typename T , T... Is>
template<int Start, int End>
using sp::integer_sequence< T, Is >::removeRange = typename slice<0, Start>::template cat<slice<End> >

Remove a range of values from Start to End - 1 inclusive.

◆ set

template<typename T , T... Is>
template<int Index, T NewValue>
using sp::integer_sequence< T, Is >::set = typename slice<0, Index>::template append<NewValue>::template cat<slice<Index + 1> >

A list equal to this one with one element changed.

Template Parameters
IndexThe element to change. If out-of-bounds, the program will not compile
NewValueThe new value to store.

Example

using B = AList::set<0, 4>; // 4, 2, 3
using C = AList::set<1, 4>; // 1, 4, 3
using D = AList::set<2, 4>; // 1, 2, 4

◆ slice

template<typename T , T... Is>
template<int Start, int End = Size>
using sp::integer_sequence< T, Is >::slice = decltype(sliceHelper<Start>(std::make_integer_sequence<int, End - Start>()))

A list formed from elements in the range [Start, End).

Example

using SlicedList = A::slice<2, 3>; // 18, 54
using SlicedList2 = A::slice<0, 3>; // 27, 30, 18
using Last = A::slice<3>; // 54 (that's numberwang!)
Template Parameters
StartThe index of the element to include in the output list.
EndThe index of the element to exclude from the output list.

◆ sort

template<typename T , T... Is>
template<typename Defer = Deferred>
using sp::integer_sequence< T, Is >::sort = decltype(Defer::template sortHelper())

A sorted version of this list.

Note
This function is relatively slow, and O(n²). It may cause very long compile times if used too much.

Example

using SortedA = A::template sort<>; // 1, 1, 1, 2, 2, 3, 3
using B = sp::int_sequence<5, 4, 3, 2, 1>::sort<>; // 1, 2, 3, 4, 5
using C = sp::int_sequence<1, 2, 3, 4, 5>::sort<>; // 1, 2, 3, 4, 5
using D = sp::int_sequence<1, 1, 1, 1, 2, 2, 3, 3, 5>::sort<>; // 1, 1, 1, 1, 2, 2, 3, 3, 5
using SortedEmpty = sp::int_sequence<>::sort<>; // []
decltype(Defer::template sortHelper()) sort
A sorted version of this list.
Definition: integer_sequence.hpp:600

◆ sortedUnique

template<typename T , T... Is>
template<typename Defer = Deferred>
using sp::integer_sequence< T, Is >::sortedUnique = decltype(Defer::template sortedUniqueHelper())

Get unique elements of a sorted list in linear time.

This is exactly like unique, except:

  • It is much faster
  • It requires the input list to be sorted into ascending order.

Note that calling sort<> and then using this function is more expensive than using unique.

Example

using UniqueX = X::sortedUnique<>;
using UniqueY = Y::sortedUnique<>;
See also
unique

◆ unique

template<typename T , T... Is>
template<typename Defer = ThisType>
using sp::integer_sequence< T, Is >::unique = typename Defer::template indexFilter<UniqueFilter>

A list formed of the unique elements of this list.

The first occurrence of each element is retained, and their relative ordering preserved. The input list does not have to be sorted.

Note
This function is relatively slow, and O(n²). It may cause very long compile times if used too much.

Example

using UList = typename B::template unique<>; // 1, 2, 3
See also
sortedUnique

Member Function Documentation

◆ binarySearch()

template<typename T , T... Is>
constexpr static int sp::integer_sequence< T, Is >::binarySearch ( Needle,
int  Start = 0,
int  End = Size 
)
staticconstexpr

Find the index of the first value that is >= Needle.

◆ binarySearchRange()

template<typename T , T... Is>
constexpr static std::pair< int, int > sp::integer_sequence< T, Is >::binarySearchRange ( rangeStart,
rangeEnd,
int  Start = 0,
int  End = Size 
)
staticconstexpr

Find the indices of all values satisfying rangeStart <= X < rangeEnd in logarithmic time. (must be sorted).

◆ contains()

template<typename T , T... Is>
constexpr static bool sp::integer_sequence< T, Is >::contains ( I)
staticconstexpr

Returns true iff the given element is in the list.

Example

constexpr bool cX2 = X::contains(2); // true
constexpr bool cX42 = X::contains(42); // false
constexpr bool cX5 = X::contains(5); // true
constexpr bool cY0 = Y::contains(0); // false
constexpr bool cY17 = Y::contains(17); // true
Parameters
IThe element to look for. Check if an element is in the list

◆ Find() [1/2]

template<typename T , T... Is>
template<typename Predicate >
static constexpr int sp::integer_sequence< T, Is >::Find ( int  FromIndex = 0)
staticconstexpr

Return the index of the first element for which Predicate<I>::value is true, starting from index I, or -1 if there is no such element.

Example

constexpr int IndexOf19 = Y::Find<sp::tm::Eq<19>>(); // 0
See also
indexOf()
Template Parameters
PredicateThe functor to use.

◆ Find() [2/2]

template<typename T , T... Is>
template<typename Predicate >
static constexpr int sp::integer_sequence< T, Is >::Find ( Predicate  lambda,
int  FromIndex = 0 
)
staticconstexpr

Return the index of the first element for which lambda(value) is true, starting from index I, or -1 if there is no such element.

This version is more efficient than the functor-based one.

Example

constexpr int FoundOne = X::Find([](int x) constexpr {return x == 1;}); // 0
constexpr int FoundTwo = X::Find([](int x) constexpr {return x == 2;}); // 1
constexpr int FoundThree = X::Find([](int x) constexpr {return x == 3;}); // 2
constexpr int FoundNinetySix = X::Find([](int x) constexpr {return x == 96;}); // -1
See also
indexOf()
Parameters
lambdaA lambda that accepts one T and returns a bool.
FromIndexThe first index to start searching from.

◆ get()

template<typename T , T... Is>
constexpr static T sp::integer_sequence< T, Is >::get ( int  i)
staticconstexpr

Get an element from the list.

Example

constexpr int first = AList::get(0); // 1
constexpr int second = AList::get(1); // 2
constexpr int third = AList::get(2); // 3
Returns
The i'th element of the list.

◆ indexOf() [1/2]

template<typename T , T... Is>
template<T... Xs>
static constexpr int sp::integer_sequence< T, Is >::indexOf ( integer_sequence< T, Xs... >  seq,
int  fromIndex = 0 
)
staticconstexpr

Find the index of the first time a given integer sequence occurs as a subsequence of this one.

This is particularly useful for finding substrings when using integer_sequence<char> as a compile-time string.

Example

constexpr int AIndexA = A::template indexOf(A{}); // 0
constexpr int AIndexB = A::template indexOf(A{}, 1); // -1
constexpr int AIndex23 = A::template indexOf(sp::int_sequence<2, 3>{}); // 1
static constexpr int indexOf(T x, int fromIndex=0)
Find the index of the first occurence of x after index fromIndex, or -1 if it doesn't exist.
Definition: integer_sequence.hpp:418
Parameters
seqAn integer_sequence of the same type.
fromIndexThe first index to start searching from.

◆ indexOf() [2/2]

template<typename T , T... Is>
static constexpr int sp::integer_sequence< T, Is >::indexOf ( x,
int  fromIndex = 0 
)
staticconstexpr

Find the index of the first occurence of x after index fromIndex, or -1 if it doesn't exist.

Example

constexpr int FoundOne = X::Find([](int x) constexpr {return x == 1;}); // 0
constexpr int FoundTwo = X::Find([](int x) constexpr {return x == 2;}); // 1
constexpr int FoundThree = X::Find([](int x) constexpr {return x == 3;}); // 2
constexpr int FoundNinetySix = X::Find([](int x) constexpr {return x == 96;}); // -1
See also
indexOf()
Parameters
xA lambda that accepts one T and returns a bool.
fromIndexThe first index to start searching from.

◆ last()

template<typename T , T... Is>
constexpr static T sp::integer_sequence< T, Is >::last ( )
staticconstexpr

Get the last element from the list.

◆ StartsWith()

template<typename T , T... Is>
template<T... Ts>
constexpr static bool sp::integer_sequence< T, Is >::StartsWith ( )
staticconstexpr

Determine if this list starts with the given sequence of values.

This is more efficient than using the multi-elemeent indexOf() function, where this is applicable.

Example

static_assert(A::template StartsWith<1>());
static_assert(A::template StartsWith<1, 2>());
static_assert(A::template StartsWith<1, 2, 3>());
static_assert(!A::template StartsWith<1, 2, 3, 4>());
Template Parameters
TsThe elements to look for.

Member Data Documentation

◆ All

template<typename T , T... Is>
template<typename Predicate >
constexpr bool sp::integer_sequence< T, Is >::All = (Predicate{}(Is) && ...)
staticconstexpr

True iff the given functor predicate matches all elements of the list.

Example

constexpr bool Is42 = A::All<sp::tm::Eq<42>>; // false
constexpr bool Is42Really = All42::All<sp::tm::Eq<42>>; // true
Template Parameters
PredicateThe functor predicate to use.

◆ Any

template<typename T , T... Is>
template<typename Predicate >
constexpr bool sp::integer_sequence< T, Is >::Any = (Predicate{}(Is) || ...)
staticconstexpr

True iff the given functor predicate matches any element of the list.

Example

constexpr bool Any1 = A::Any<sp::tm::Eq<1>>; // true
constexpr bool Any2 = A::Any<sp::tm::Eq<2>>; // true
constexpr bool Any0 = A::Any<sp::tm::Eq<0>>; // false
Template Parameters
PredicateThe functor predicate to use.

◆ equals

template<typename T , T... Is>
template<typename OtherSeq >
constexpr static bool sp::integer_sequence< T, Is >::equals = std::is_same_v<ThisType, OtherSeq>
staticconstexpr

Compare lists for equality.

Constant-time.

Example

static_assert(A::template equals<A>);
static_assert(!A::template equals<B>);
static_assert(A::template equals<typename B::template slice<1>>);
Template Parameters
OtherSeqThe sequence to compare to.