BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_makeintegersequence.h
Go to the documentation of this file.
1/// @file bslmf_makeintegersequence.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_makeintegersequence.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_MAKEINTEGERSEQUENCE
9#define INCLUDED_BSLMF_MAKEINTEGERSEQUENCE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_makeintegersequence bslmf_makeintegersequence
15/// @brief Provide a template parameter pack of integers.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_makeintegersequence
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_makeintegersequence-purpose"> Purpose</a>
25/// * <a href="#bslmf_makeintegersequence-classes"> Classes </a>
26/// * <a href="#bslmf_makeintegersequence-description"> Description </a>
27/// * <a href="#bslmf_makeintegersequence-usage"> Usage </a>
28/// * <a href="#bslmf_makeintegersequence-example-1-pass-c-array-as-a-parameter-to-a-function-with-variadic-template"> Example 1: Pass C-array as a parameter to a function with variadic template </a>
29///
30/// # Purpose {#bslmf_makeintegersequence-purpose}
31/// Provide a template parameter pack of integers.
32///
33/// # Classes {#bslmf_makeintegersequence-classes}
34///
35/// - bslmf::MakeIntegerSequence: compile-time integer sequence factory function
36///
37/// # Description {#bslmf_makeintegersequence-description}
38/// This component defines a factory function
39/// `bslmf::MakeIntegerSequence` that generate a compile-time sequence of
40/// increasing integer values starting with 0.
41///
42/// `bslmf::MakeIntegerSequence` meets the requirements of the
43/// `make_integer_sequence` template introduced in the C++14 standard
44/// [intseq.intseq] and can be used in a client's code if the compiler supports
45/// the C++11 standard.
46///
47/// Note, that this component has no (emulated) support for pre-standard C++11
48/// compilers, as its only purpose is to be used in deduction with template
49/// parameter packs. There is no language support to emulate in earlier
50/// compilers.
51///
52/// ## Usage {#bslmf_makeintegersequence-usage}
53///
54///
55/// In this section we show intended use of this component.
56///
57/// ### Example 1: Pass C-array as a parameter to a function with variadic template {#bslmf_makeintegersequence-example-1-pass-c-array-as-a-parameter-to-a-function-with-variadic-template}
58///
59///
60/// Suppose we want to initialize a C-Array of known size `t_N` with data read
61/// from a data source using a library class that provides a variadic template
62/// interface that loads a data of variable length into the supplied parameter
63/// pack.
64///
65/// First, define a class template `DataReader`,
66/// @code
67/// template <std::size_t t_N>
68/// class DataReader {
69/// public:
70/// @endcode
71/// Then, implement a method that loads the specified parameter pack `args` with
72/// data read from a data source.
73/// @code
74/// template <class ...t_T>
75/// void read(t_T*... args) const
76/// {
77/// static_assert(sizeof...(args) == t_N, "");
78/// read_impl(args...);
79/// }
80/// @endcode
81/// Next, for the test purpose provide simple implementation of the recursive
82/// variadic @ref read_impl function that streams the index of the C-Array's
83/// element to `stdout`.
84/// @code
85/// private:
86/// template <class U, class ...t_T>
87/// void read_impl(U*, t_T*... args) const
88/// {
89/// printf("read element #%i\n",
90/// static_cast<int>(t_N - 1 - sizeof...(args)));
91/// read_impl(args...);
92/// }
93/// @endcode
94/// Then, implement the recursion break condition.
95/// @code
96/// void read_impl() const
97/// {
98/// }
99/// };
100/// @endcode
101/// Next, define a helper function template `readData` that expands the
102/// parameter pack of indices `I` and invokes the variadic template `read`
103/// method of the specified `reader` object.
104/// @code
105/// namespace {
106/// template<class R, class t_T, std::size_t... I>
107/// void readData(const R& reader,
108/// t_T *data,
109/// bslmf::IntegerSequence<std::size_t, I...>)
110/// {
111/// reader.read(&data[I]...);
112/// // In pseudocode, this is equivalent to:
113/// // reader.read(&data[0],
114/// // &data[1],
115/// // &data[2],
116/// // ...
117/// // &data[t_N-1]);
118/// }
119/// }
120/// @endcode
121/// Now, define function template `readData` that invokes the helper function
122/// Note, that the `bslmf::MakeIntegerSequence<std::size_t, t_N>` function
123/// generates an object of an integer sequence class instantiated with a
124/// template parameter pack of integers that will be expanded and used as an
125/// array's indices in the helper function when calling the
126/// `Reader::read(t_T*...)` variadic template function.
127/// @code
128/// template<class t_T, std::size_t t_N>
129/// void readData(const DataReader<t_N>& reader, t_T *data)
130/// {
131/// readData(reader, data, bslmf::MakeIntegerSequence<std::size_t, t_N>());
132/// }
133/// @endcode
134/// Finally, define a `data` C-Array and `reader` variables and pass them to the
135/// `readData` function as parameters.
136/// @code
137/// constexpr int k_SIZE = 5;
138/// DataReader<k_SIZE> reader;
139/// int data[k_SIZE] = {0};
140///
141/// readData(reader, data);
142/// @endcode
143/// The streaming operator produces output in the following format on `stdout`:
144/// @code
145/// read element #0
146/// read element #1
147/// read element #2
148/// read element #3
149/// read element #4
150/// @endcode
151/// @}
152/** @} */
153/** @} */
154
155/** @addtogroup bsl
156 * @{
157 */
158/** @addtogroup bslmf
159 * @{
160 */
161/** @addtogroup bslmf_makeintegersequence
162 * @{
163 */
164
165#include <bslscm_version.h>
166
169
170#include <bsls_libraryfeatures.h>
171
172#include <cstddef> // 'std::size_t'
173
174#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE
175
176
177namespace bslmf {
178 // =============================================
179 // private struct MakeIntegerSequence_ConcatUtil
180 // =============================================
181
182/// This component-private class template provides a specialization that
183/// concatenates two integer sequences. This template is not defined unless
184/// the (template parameter) types `t_S1` and `t_S2` are specializations of
185/// the class template `bslmf::IntegerSequence`.
186template <class t_S1, class t_S2>
187struct MakeIntegerSequence_ConcatUtil;
188
189/// This partial specialization of `bslmf::MakeIntegerSequence_ConcatUtil`
190/// appends all indices from the specified `t_I2` sequence at the end of the
191/// indices of the specified `t_I1` sequence.
192template <class t_T, t_T... t_I1, t_T... t_I2>
193struct MakeIntegerSequence_ConcatUtil<bslmf::IntegerSequence<t_T, t_I1...>,
194 bslmf::IntegerSequence<t_T, t_I2...> >
195{
196 /// `type` is an alias to an integer sequence type that represents the
197 /// result of concatenation of two integer sequences `t_I1` and `t_I2`.
198 ///
199 /// Consider `t_I1 = {0, 1, 2}` and `t_I2 = {0, 1, 2}`, then the result
200 /// of concatenation is `type = {0, 1, 2, 3 + 0, 3 + 1, 3 + 2}`. That is
201 /// `type = {0, 1, 2, 3, 4, 5}`.
202 using type =
203 bslmf::IntegerSequence<t_T, t_I1..., (sizeof...(t_I1) + t_I2)...>;
204};
205
206/// `bslmf::MakeIntegerSequence_ConcatUtil_t` is an alias to the result type
207/// of the `bslmf::MakeIntegerSequence_ConcatUtil` meta-function.
208template <class t_S1, class t_S2>
209using MakeIntegerSequence_ConcatUtil_t =
210 typename MakeIntegerSequence_ConcatUtil<t_S1, t_S2>::type;
211
212 // =======================================
213 // private struct MakeIntegerSequence_Impl
214 // =======================================
215
216/// This is recursive meta-function that generates a sequence of increasing
217/// integer values in a range of [0..t_N::value) having the specified length
218/// `t_N::value`.
219template <class t_T, class t_N>
220struct MakeIntegerSequence_Impl
221{
222 using FirstPart = bsl::integral_constant<std::size_t, t_N::value / 2>;
223 using SecondPart =
224 bsl::integral_constant<std::size_t, t_N::value - t_N::value / 2>;
225
226 /// `type` is an alias to the result of the
227 /// `bslmf::MakeIntegerSequence_ConcatUtil_t` meta-function instantiated
228 /// with two integer sequences of two lengths `t_N/2` and `t_N - t_N/2`,
229 /// that implies logarithmic depth of the
230 /// `bslmf::MakeIntegerSequence_Impl` meta-function instantiation.
231 using type = MakeIntegerSequence_ConcatUtil_t<
232 typename MakeIntegerSequence_Impl<t_T, FirstPart>::type,
233 typename MakeIntegerSequence_Impl<t_T, SecondPart>::type>;
234};
235
236/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
237/// meta-function is a recursion break condition for an empty integer
238/// sequence.
239template <class t_T>
240struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 0> >
241{
242 using type = bslmf::IntegerSequence<t_T>;
243};
244
245/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
246/// meta-function is a recursion break condition for an integer sequence
247/// having the length 1.
248template <class t_T>
249struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 1> >
250{
251 using type = bslmf::IntegerSequence<t_T, 0>;
252};
253
254/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
255/// meta-function is a recursion break condition for an integer sequence
256/// having the length 2.
257template <class t_T>
258struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 2> >
259{
260 using type = bslmf::IntegerSequence<t_T, 0, 1>;
261};
262
263/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
264/// meta-function is a recursion break condition for an integer sequence
265/// having the length 3.
266template <class t_T>
267struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 3> >
268{
269 using type = bslmf::IntegerSequence<t_T, 0, 1, 2>;
270};
271
272/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
273/// meta-function is a recursion break condition for an integer sequence
274/// having the length 4.
275template <class t_T>
276struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 4> >
277{
278 using type = bslmf::IntegerSequence<t_T, 0, 1, 2, 3>;
279};
280
281/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
282/// meta-function is a recursion break condition for an integer sequence
283/// having the length 5.
284template <class t_T>
285struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 5> >
286{
287 using type = bslmf::IntegerSequence<t_T, 0, 1, 2, 3, 4>;
288};
289
290/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
291/// meta-function is a recursion break condition for an integer sequence
292/// having the length 6.
293template <class t_T>
294struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 6> >
295{
296 using type = bslmf::IntegerSequence<t_T, 0, 1, 2, 3, 4, 5>;
297};
298
299/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
300/// meta-function is a recursion break condition for an integer sequence
301/// having the length 7.
302template <class t_T>
303struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 7> >
304{
305 using type = bslmf::IntegerSequence<t_T, 0, 1, 2, 3, 4, 5, 6>;
306};
307
308/// This partial specialization of the `bslmf::MakeIntegerSequence_Impl`
309/// meta-function is a recursion break condition for an integer sequence
310/// having the length 8.
311template <class t_T>
312struct MakeIntegerSequence_Impl<t_T, bsl::integral_constant<std::size_t, 8> >
313{
314 using type = bslmf::IntegerSequence<t_T, 0, 1, 2, 3, 4, 5, 6, 7>;
315};
316
317// ALIASES
318
319/// `bslmf::MakeIntegerSequence_Impl_t` is an alias to the result type of
320/// the `bslmf::MakeIntegerSequence_Impl` meta-function.
321template <class t_T, class t_N>
322using MakeIntegerSequence_Impl_t =
323 typename MakeIntegerSequence_Impl<t_T, t_N>::type;
324
325/// `MakeIntegerSequence` is defined to simplify creation of
326/// `bslmf::IntegerSequence` type that represents a collection of increasing
327/// integer values of the specified type `t_T` in a range of [0..t_N) having
328/// the specified t_N-value length.
329template <class t_T, t_T t_N>
330using MakeIntegerSequence = BloombergLP::bslmf::
331 MakeIntegerSequence_Impl_t<t_T, bsl::integral_constant<std::size_t, t_N> >;
332
333} // close package namespace
334
335
336#endif // BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE
337#endif // INCLUDED_BSLMF_INTEGERSEQUENCE
338
339// ----------------------------------------------------------------------------
340// Copyright 2018 Bloomberg Finance L.P.
341//
342// Licensed under the Apache License, Version 2.0 (the "License");
343// you may not use this file except in compliance with the License.
344// You may obtain a copy of the License at
345//
346// http://www.apache.org/licenses/LICENSE-2.0
347//
348// Unless required by applicable law or agreed to in writing, software
349// distributed under the License is distributed on an "AS IS" BASIS,
350// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
351// See the License for the specific language governing permissions and
352// limitations under the License.
353// ----------------------------- END-OF-FILE ----------------------------------
354
355/** @} */
356/** @} */
357/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
Definition bslmf_integralconstant.h:244