BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_integersequence

Outline

Purpose

Provide a template parameter pack of integers.

Classes

Description

This component defines a class template, bslmf::IntegerSequence, which can be used in parameter pack expansions.

bslmf::IntegerSequence meets the requirements of the integer_sequence template introduced in the C++14 standard [intseq.intseq] and can be used in a client's code if the compiler supports the C++11 standard.

Note, that this component has no (emulated) support for pre-standard C++11 compilers, as its only purpose is to be used in deduction with template parameter packs. There is no language support to emulate in earlier compilers.

Usage

In this section we show intended use of this component.

Example 1: Pass C-array as a parameter to a function with variadic template

Suppose we want to initialize a C-Array of known size t_N with data read from a data source using a library class that provides a variadic template interface that loads a data of variable length into the supplied parameter pack.

First, define a class template DataReader,

template <std::size_t t_N>
class DataReader {
public:

Then, implement a method that loads the specified parameter pack args with data read from a data source.

template <class ...t_T>
void read(t_T*... args) const
{
static_assert(sizeof...(args) == t_N, "");
read_impl(args...);
}

Next, for the test purpose provide simple implementation of the recursive variadic read_impl function that streams the index of the C-Array's element to stdout.

private:
template <class t_U, class ...t_T>
void read_impl(t_U*, t_T*... args) const
{
printf("read element #%i\n",
static_cast<int>(t_N - 1 - sizeof...(args)));
read_impl(args...);
}

Then, implement the recursion break condition.

void read_impl() const
{
}
};

Next, define a helper function template readData that expands the parameter pack of indices t_I and invokes the variadic template read method of the specified reader object.

namespace {
template<class t_R, class t_T, std::size_t... t_I>
void readData(const t_R& reader,
t_T *data,
bslmf::IntegerSequence<std::size_t, t_I...>)
{
reader.read(&data[t_I]...);
// In pseudocode, this is equivalent to:
// reader.read(&data[0],
// &data[1],
// &data[2],
// ...
// &data[t_N-1]);
}
}

Finally, define a data C-Array and reader variables and pass them to the readData function as parameters.

constexpr int k_SIZE = 5;
DataReader<k_SIZE> reader;
int data[k_SIZE] = {0};
readData(reader,
data,
bslmf::IntegerSequence<size_t, 0, 1, 2, 3, 4>());

Note that using a direct call to the bslmf::IntegerSequence constructor looks a bit clumsy here. The better approach is to use alias template bslmf::MakeIntegerSequence, that creates a collection of increasing integer values, having the specified t_N-value length. The usage example in that component shows this method more clearly. But we can not afford its presence here to avoid a cycle/levelization violation.

The streaming operator produces output in the following format on stdout:

read element #0
read element #1
read element #2
read element #3
read element #4