BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_metaint.h
Go to the documentation of this file.
1/// @file bslmf_metaint.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_metaint.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_METAINT
9#define INCLUDED_BSLMF_METAINT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_metaint bslmf_metaint
15/// @brief Provide a meta-function to map integral constants to unique types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_metaint
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_metaint-purpose"> Purpose</a>
25/// * <a href="#bslmf_metaint-classes"> Classes </a>
26/// * <a href="#bslmf_metaint-description"> Description </a>
27/// * <a href="#bslmf_metaint-usage"> Usage </a>
28/// * <a href="#bslmf_metaint-example-1-compile-time-function-dispatching"> Example 1: Compile-Time Function Dispatching </a>
29/// * <a href="#bslmf_metaint-example-2-reading-the-value-member"> Example 2: Reading the VALUE Member </a>
30///
31/// # Purpose {#bslmf_metaint-purpose}
32/// Provide a meta-function to map integral constants to unique types.
33///
34/// @deprecated Use @ref bslmf_integralconstant instead.
35///
36/// # Classes {#bslmf_metaint-classes}
37///
38/// - bslmf::MetaInt: meta-function mapping integral constants to C++ types
39///
40/// # Description {#bslmf_metaint-description}
41/// This component defines a simple template structure used to map
42/// an integral constant to a C++ type. `bslmf::MetaInt<int>` defines a
43/// different type for each distinct compile-time constant integral parameter.
44/// That is, instantiations with different integer values form distinct types,
45/// so that `bslmf::MetaInt<0>` is a distinct type from `bslmf::MetaInt<1>`,
46/// which is also distinct from `bslmf::MetaInt<2>`, and so on.
47///
48/// ## Usage {#bslmf_metaint-usage}
49///
50///
51/// This section illustrates intended usage of this component
52///
53/// ### Example 1: Compile-Time Function Dispatching {#bslmf_metaint-example-1-compile-time-function-dispatching}
54///
55///
56/// The most common use of this structure is to perform static function
57/// dispatching based on a compile-time calculation. Often the calculation is
58/// nothing more than a simple predicate, allowing us to select one of two
59/// functions. The following function, `doSomething`, uses a fast
60/// implementation (e.g., `memcpy`) if the parameterized type allows for such
61/// operations, otherwise it will use a more generic and slower implementation
62/// (e.g., copy constructor).
63/// @code
64/// template <class T>
65/// void doSomethingImp(T *t, bslmf::MetaInt<0>)
66/// {
67/// // slow generic implementation
68/// (void) t;
69/// // ...
70/// }
71///
72/// template <class T>
73/// void doSomethingImp(T *t, bslmf::MetaInt<1>)
74/// {
75/// // fast implementation (works only for some T's)
76/// (void) t;
77/// // ...
78/// }
79///
80/// template <class T, bool IsFast>
81/// void doSomething(T *t)
82/// {
83/// doSomethingImp(t, bslmf::MetaInt<IsFast>());
84/// }
85/// @endcode
86/// The power of this approach is that the compiler will compile only the
87/// implementation selected by the `MetaInt` argument. For some parameter
88/// types, the fast version of `doSomethingImp` would be ill-formed. This kind
89/// of compile-time dispatch prevents the ill-formed version from ever being
90/// instantiated.
91/// @code
92/// int main()
93/// {
94/// int i;
95/// doSomething<int, true>(&i); // fast version selected for int
96///
97/// double m;
98/// doSomething<double, false>(&m); // slow version selected for double
99///
100/// return 0;
101/// }
102/// @endcode
103///
104/// ### Example 2: Reading the VALUE Member {#bslmf_metaint-example-2-reading-the-value-member}
105///
106///
107/// In addition to forming new types, the value of the integral parameter to
108/// `MetaInt` is "saved" in the enum member `VALUE`, and is accessible for use
109/// in compile-time or run-time operations.
110/// @code
111/// template <int V>
112/// unsigned g()
113/// {
114/// bslmf::MetaInt<V> i;
115/// assert(V == i.VALUE);
116/// assert(V == bslmf::MetaInt<V>::VALUE);
117/// return bslmf::MetaInt<V>::VALUE;
118/// }
119///
120/// int main()
121/// {
122/// int v = g<1>();
123/// assert(1 == v);
124/// return 0;
125/// }
126/// @endcode
127/// @}
128/** @} */
129/** @} */
130
131/** @addtogroup bsl
132 * @{
133 */
134/** @addtogroup bslmf
135 * @{
136 */
137/** @addtogroup bslmf_metaint
138 * @{
139 */
140
141#include <bslscm_version.h>
142
144#include <bslmf_tag.h>
145
148#include <bsls_platform.h>
149
150
151
152namespace bslmf {
153
154 // ==============
155 // struct MetaInt
156 // ==============
157
158/// Instantiating this template produces a distinct type for each
159/// non-negative integer value. This template has been deprecated in favor
160/// of the standard `integral_constant` template.
161template <int t_INT_VALUE>
162struct
164 "bslmf_MetaInt",
165 "use 'integral_constant' instead")
166MetaInt : public bsl::integral_constant<int, t_INT_VALUE> {
167
168#if defined(BSLS_COMPILERFEATURES_SUPPORT_STATIC_ASSERT)
169 static_assert(t_INT_VALUE >= 0, "t_INT_VALUE must be non-negative");
170#endif
171
172 // TYPES
173 typedef MetaInt<t_INT_VALUE> Type;
174
175#ifdef BSLS_PLATFORM_CMP_IBM
176// Suppress a compile warning on xlc for negative unsigned values.
177#pragma report(disable, "1540-0724")
178#endif
179
180 typedef bslmf::Tag<t_INT_VALUE> Tag;
181
182#ifdef BSLS_PLATFORM_CMP_IBM
183#pragma report(pop)
184#endif
185
186 enum { VALUE = t_INT_VALUE };
187
188 // CREATORS
189
190 /// Does nothing (`MetaInt` is stateless).
191 MetaInt();
192
193 /// Convert from a `bsl::integral_constant<int, t_INT_VALUE>`.
194 MetaInt(bsl::integral_constant<int, t_INT_VALUE>); // IMPLICIT
195
196 MetaInt(const MetaInt&) = default;
197 MetaInt& operator=(const MetaInt&) = default;
198 ~MetaInt() = default;
199
200 // CLASS METHODS
201
202 /// Declared but not defined. Meta-function use only. The tag can be
203 /// used to recover meta-information from an expression. Example:
204 /// `sizeof(f(expr).tag())` returns a different compile-time value
205 /// depending on the type of the result of calling the `f` function but
206 /// does not actually call the `f` function or the `tag` method at
207 /// run-time. Note that `f(expr)::VALUE` or `sizeof(f(expr)::Type)`
208 /// would be ill-formed and that `f(expr).value` is not a compile-time
209 /// expression.
210 static Tag& tag();
211};
212
213/// This specialization of `MetaInt` has a `VAL` of zero and is convertible
214/// to and from `bsl::false_type`.
215template <>
216struct
218 "bslmf_MetaInt",
219 "use 'integral_constant' instead")
220MetaInt<0> : public bsl::false_type {
221
222 // TYPES
223 typedef MetaInt<0> Type;
224 typedef bslmf::Tag<0> Tag;
225
226 enum { VALUE = 0 };
227
228 // CREATORS
229
230 /// Does nothing (`MetaInt` is stateless).
231 MetaInt();
232
233 /// Convert from a `bsl::false_type`.
234 MetaInt(bsl::false_type); // IMPLICIT
235
236 MetaInt(const MetaInt&) = default;
237 MetaInt& operator=(const MetaInt&) = default;
238 ~MetaInt() = default;
239
240 // CLASS METHODS
241
242 /// Declared but not defined. Meta-function use only. The tag can be
243 /// used to recover meta-information from an expression. Example:
244 /// `sizeof(f(expr).tag())` returns a different compile-time value
245 /// depending on the type of the result of calling the `f` function but
246 /// does not actually call the `f` function or the `tag` method at
247 /// run-time. Note that `f(expr)::VALUE` or `sizeof(f(expr)::Type)`
248 /// would be ill-formed and that `f(expr).value` is not a compile-time
249 /// expression.
250 static Tag& tag();
251
252 // ACCESSORS
253
254 /// Return `false`. (This operator is conversion operator to `bool`.)
255 operator bool() const;
256};
257
258/// This specialization of `MetaInt` has a `VAL` of one and is convertible
259/// to and from `bsl::true_type`.
260template <>
261struct
263 "bslmf_MetaInt",
264 "use 'integral_constant' instead")
265MetaInt<1> : public bsl::true_type {
266
267 // TYPES
268 typedef MetaInt<1> Type;
269 typedef bslmf::Tag<1> Tag;
270
271 enum { VALUE = 1 };
272
273 // CREATORS
274
275 /// Does nothing (`MetaInt` is stateless).
276 MetaInt();
277
278 /// Convert from a `bsl::true_type`.
279 MetaInt(bsl::true_type); // IMPLICIT
280
281 MetaInt(const MetaInt&) = default;
282 MetaInt& operator=(const MetaInt&) = default;
283 ~MetaInt() = default;
284
285 // CLASS METHODS
286
287 /// Declared but not defined. Meta-function use only. The tag can be
288 /// used to recover meta-information from an expression. Example:
289 /// `sizeof(f(expr).tag())` returns a different compile-time value
290 /// depending on the type of the result of calling the `f` function but
291 /// does not actually call the `f` function or the `tag` method at
292 /// run-time. Note that `f(expr)::VALUE` or `sizeof(f(expr)::Type)`
293 /// would be ill-formed and that `f(expr).value` is not a compile-time
294 /// expression.
295 static Tag& tag();
296
297 // ACCESSORS
298
299 /// Return `true`. (This operator is conversion operator to `bool`.)
300 operator bool() const;
301};
302
303/// Given an integral value, `V`, and an expression, `expr`, of type
304/// `bslmf::MetaInt<V>`, this macro returns a compile-time constant with
305/// value, `V`. The expression, `expr`, is not evaluated at run-time.
306#define BSLMF_METAINT_TO_INT(expr) BSLMF_TAG_TO_INT((expr).tag())
307
308/// Given an integral value, `V`, and an expression, `expr`, of type
309/// `bslmf::MetaInt<V>`, this macro returns a compile-time constant with
310/// value, `true` or `false`, according to the Boolean value of `V`. The
311/// expression, `expr`, is not evaluated at run-time.
312#define BSLMF_METAINT_TO_BOOL(expr) BSLMF_TAG_TO_BOOL((expr).tag())
313
314#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
315// ============================================================================
316// BACKWARD COMPATIBILITY
317// ============================================================================
318
319#ifdef bslmf_MetaInt
320#undef bslmf_MetaInt
321#endif
322/// This alias is defined for backward compatibility.
323#define bslmf_MetaInt bslmf::MetaInt
324#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
325
326// ============================================================================
327// INLINE FUNCTIONS
328// ============================================================================
329
330// CREATORS
331template <int t_INT_VALUE>
332inline
333MetaInt<t_INT_VALUE>::MetaInt()
334{
335}
336
337template <int t_INT_VALUE>
338inline
339MetaInt<t_INT_VALUE>::MetaInt(bsl::integral_constant<int, t_INT_VALUE>)
340{
341}
342
343inline
344MetaInt<0>::MetaInt()
345{
346}
347
348inline
349MetaInt<0>::MetaInt(bsl::false_type)
350{
351}
352
353inline
354MetaInt<1>::MetaInt()
355{
356}
357
358inline
359MetaInt<1>::MetaInt(bsl::true_type)
360{
361}
362
363// ACCESSORS
364inline
365MetaInt<0>::operator bool() const
366{
367 return false;
368}
369
370inline
371MetaInt<1>::operator bool() const
372{
373 return true;
374}
375
376} // close package namespace
377
378
379#endif
380
381// ----------------------------------------------------------------------------
382// Copyright 2013 Bloomberg Finance L.P.
383//
384// Licensed under the Apache License, Version 2.0 (the "License");
385// you may not use this file except in compliance with the License.
386// You may obtain a copy of the License at
387//
388// http://www.apache.org/licenses/LICENSE-2.0
389//
390// Unless required by applicable law or agreed to in writing, software
391// distributed under the License is distributed on an "AS IS" BASIS,
392// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
393// See the License for the specific language governing permissions and
394// limitations under the License.
395// ----------------------------- END-OF-FILE ----------------------------------
396
397/** @} */
398/** @} */
399/** @} */
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:319
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
Definition bslmf_integralconstant.h:244
Definition bslmf_tag.h:163