BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmf_integralconstant.h
Go to the documentation of this file.
1/// @file bslmf_integralconstant.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_integralconstant.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_INTEGRALCONSTANT
9#define INCLUDED_BSLMF_INTEGRALCONSTANT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_integralconstant bslmf_integralconstant
15/// @brief Provide a mapping from integral constants to unique types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_integralconstant
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_integralconstant-purpose"> Purpose</a>
25/// * <a href="#bslmf_integralconstant-classes"> Classes </a>
26/// * <a href="#bslmf_integralconstant-description"> Description </a>
27/// * <a href="#bslmf_integralconstant-usage"> Usage </a>
28/// * <a href="#bslmf_integralconstant-example-1-compile-time-function-dispatching"> Example 1: Compile-Time Function Dispatching </a>
29/// * <a href="#bslmf_integralconstant-example-2-base-class-for-metafunctions"> Example 2: Base Class For Metafunctions </a>
30///
31/// # Purpose {#bslmf_integralconstant-purpose}
32/// Provide a mapping from integral constants to unique types.
33///
34/// # Classes {#bslmf_integralconstant-classes}
35///
36/// - bsl::integral_constant: A type representing a specific integer value
37/// - bsl::bool_constant: An alias template for `integral_constant<bool>`
38/// - bsl::false_type: `typedef` for `integral_constant<bool, false>`
39/// - bsl::true_type: `typedef` for `integral_constant<bool, true>`
40///
41/// @see
42///
43/// # Description {#bslmf_integralconstant-description}
44/// This component describes a simple class template,
45/// `bsl::integral_constant`, that is used to map an integer constant to a C++
46/// type. `integral_constant<t_TYPE, t_VALUE>` generates a unique type for each
47/// distinct compile-time integral `t_TYPE` and constant integer `t_VALUE`
48/// parameter. That is, instantiations with different integer types and values
49/// form distinct types, so that `integral_constant<int, 0>` is a different type
50/// from `integral_constant<int, 1>`, which is also distinct from
51/// `integral_constant<unsigned, 1>`, and so on. This mapping of integer values
52/// to types allows for "overloading by value", i.e., multiple functions with
53/// the same name can be overloaded on the "value" of an `integral_constant`
54/// argument, provided that the value is known at compile-time. The typedefs
55/// `bsl::true_type` and `bsl::false_type` map the predicate values `true` and
56/// `false` to C++ types that are frequently useful for compile-time algorithms.
57///
58/// ## Usage {#bslmf_integralconstant-usage}
59///
60///
61/// This section illustrates intended usage of this component
62///
63/// ### Example 1: Compile-Time Function Dispatching {#bslmf_integralconstant-example-1-compile-time-function-dispatching}
64///
65///
66/// The most common use of this structure is to perform compile-time function
67/// dispatching based on a compile-time calculation. Often the calculation is
68/// nothing more than a simple predicate, allowing us to select one of two
69/// functions based on whether the predicate holds. The following function,
70/// `doSomething`, uses a fast implementation (e.g., using `memcpy`) if the
71/// parameterized type allows for such operations, otherwise it will use a more
72/// generic and slower implementation (e.g., using the copy constructor). This
73/// example uses the types `true_type` and `false_type`, which are simple
74/// typedefs for `integral_constant<bool, true>` and
75/// `integral_constant<bool, false>`, respectively.
76/// @code
77/// #include <bslmf_integralconstant.h>
78///
79/// template <class t_T>
80/// int doSomethingImp(t_T *t, bsl::true_type)
81/// {
82/// // slow, generic implementation
83/// // ...
84/// (void) t;
85/// return 11;
86/// }
87///
88/// template <class t_T>
89/// int doSomethingImp(t_T *t, bsl::false_type)
90/// {
91/// // fast implementation that works only for some types of 't_T'
92/// // ...
93/// (void) t;
94/// return 55;
95/// }
96///
97/// template <bool IsSlow, class t_T>
98/// int doSomething(t_T *t)
99/// {
100/// // Dispatch to an implementation depending on the (compile-time)
101/// // value of 'IsSlow'.
102/// return doSomethingImp(t, bsl::integral_constant<bool, IsSlow>());
103/// }
104/// @endcode
105/// For some parameter types, the fast version of `doSomethingImp` is not
106/// legal. The power of this approach is that the compiler will not attempt
107/// semantic analysis on the implementation that does not match the appropriate
108/// `integral_constant` argument.
109/// @code
110/// int main()
111/// {
112/// int r;
113///
114/// int i;
115/// r = doSomething<false>(&i); // select fast version for int
116/// assert(55 == r);
117///
118/// double m;
119/// r = doSomething<true>(&m); // select slow version for double
120/// assert(11 == r);
121///
122/// return 0;
123/// }
124/// @endcode
125///
126/// ### Example 2: Base Class For Metafunctions {#bslmf_integralconstant-example-2-base-class-for-metafunctions}
127///
128///
129/// Hard-coding the value of an `integral_constant` is not especially useful.
130/// Rather, `integral_constant` is typically used as the base class for
131/// "metafunction" classes, classes that yield the value of compile-time
132/// properties, including properties that are associated with types, rather
133/// than with values. For example, the following metafunction can be used at
134/// compile time to determine whether a type is a floating point type:
135/// @code
136/// template <class t_TYPE> struct IsFloatingPoint : bsl::false_type { };
137/// template <> struct IsFloatingPoint<float> : bsl::true_type { };
138/// template <> struct IsFloatingPoint<double> : bsl::true_type { };
139/// template <> struct IsFloatingPoint<long double> : bsl::true_type { };
140/// @endcode
141/// The value `IsFloatingPoint<int>::value` is false and
142/// `IsFloatingPoint<double>::value` is true. The `integral_constant` base
143/// class has a member type, `type`, that refers to itself and is inherited by
144/// `IsFloatingPoint`. Thus `IsFloatingPoint<float>::type` is `true_type` and
145/// `IsFloatingPoint<char>::type` is `false_type`. `IsFloatingPoint` is an a
146/// member of a common category of metafunctions known as "type traits" because
147/// they express certain properties (traits) of a type. Using this
148/// metafunction, we can rewrite the `doSomething` function from first example
149/// so that it does not require the user to specify the `IsSlow` template
150/// argument:
151/// @code
152/// template <class t_T>
153/// int doSomething2(t_T *t)
154/// {
155/// // Automatically detect whether to use slow or fast imp.
156/// const bool isSlow = IsFloatingPoint<t_T>::value;
157/// return doSomethingImp(t, bsl::integral_constant<bool, isSlow>());
158/// }
159///
160/// int main()
161/// {
162/// int r;
163///
164/// int i;
165/// r = doSomething2(&i); // select fast version for int
166/// assert(55 == r);
167///
168/// double m;
169/// r = doSomething2(&m); // select slow version for double
170/// assert(11 == r);
171///
172/// return 0;
173/// }
174/// @endcode
175/// @}
176/** @} */
177/** @} */
178
179/** @addtogroup bsl
180 * @{
181 */
182/** @addtogroup bslmf
183 * @{
184 */
185/** @addtogroup bslmf_integralconstant
186 * @{
187 */
188
189#include <bslscm_version.h>
190
192#include <bsls_keyword.h>
193
194#ifdef BSLS_COMPILERFEATURES_FULL_CPP11
195# include <type_traits>
196#endif // BSLS_COMPILERFEATURES_FULL_CPP11
197
198#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
199# include <bsls_nativestd.h>
200#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
201
202#ifdef BSLS_COMPILERFEATURES_FULL_CPP11
203namespace bsl {
204
205 // ================================
206 // class template integral_constant
207 // ================================
208
209template <class t_TYPE, t_TYPE t_VALUE>
210struct integral_constant : ::std::integral_constant<t_TYPE, t_VALUE> {
211 // PUBLIC TYPES
212 using type = integral_constant;
213
214 public:
215 // CREATORS
216
217 integral_constant() = default;
218 integral_constant(const integral_constant&) = default;
220 ~integral_constant() = default;
221
222 // ACCESSORS
223
224 /// Return a copy of the template argument `t_VALUE`.
225 constexpr t_TYPE operator()() const noexcept;
226};
227
228 // ============================
229 // alias template bool_constant
230 // ============================
231
232template <bool t_VALUE>
233using bool_constant = integral_constant<bool, t_VALUE>;
234
235 // ===============
236 // type false_type
237 // ===============
238
239using false_type = bool_constant<false>;
240
241 // ===============
242 // type true_type
243 // ===============
244
245using true_type = bool_constant<true>;
246
247} // close namespace bsl
248#else // BSLS_COMPILERFEATURES_FULL_CPP11
249namespace bsl {
250
251 // ================================
252 // class template integral_constant
253 // ================================
254
255/// Generate a unique type for the given `t_TYPE` and `t_VALUE`. This
256/// `struct` is used for compile-time dispatch of overloaded functions and
257/// as the base class for many metafunctions.
258///
259/// See @ref bslmf_integralconstant
260template <class t_TYPE, t_TYPE t_VALUE>
262 // PUBLIC TYPES
263 typedef t_TYPE value_type;
265
266 // PUBLIC CLASS DATA
267 static const t_TYPE value = t_VALUE;
268
269 public:
270 // CREATORS
271
272 integral_constant() = default;
276
277 // ACCESSORS
278
279 /// Return a copy of the template argument `t_VALUE`.
280 operator value_type() const;
281
282 /// Return a copy of the template argument `t_VALUE`.
284};
285
286 // ===============
287 // type false_type
288 // ===============
289
291
292 // ===============
293 // type true_type
294 // ===============
295
297
298} // close namespace bsl
299#endif // ! defined(BSLS_COMPILERFEATURES_FULL_CPP11)
300
301// ============================================================================
302// INLINE FUNCTION DEFINITIONS
303// ============================================================================
304
305// ACCESSORS
306#ifdef BSLS_COMPILERFEATURES_FULL_CPP11
307template <class t_TYPE, t_TYPE t_VALUE>
308inline constexpr
310{
311 return t_VALUE;
312}
313
314#else // BSLS_COMPILERFEATURES_FULL_CPP11
315template <class t_TYPE, t_TYPE t_VALUE>
316inline
318{
319 return t_VALUE;
320}
321
322template <class t_TYPE, t_TYPE t_VALUE>
323inline
325{
326 return t_VALUE;
327}
328
329// STATIC MEMBER VARIABLE DEFINITIONS
330template <class t_TYPE, t_TYPE t_VALUE>
332#endif // ! defined(BSLS_COMPILERFEATURES_FULL_CPP11)
333
334#endif // ! defined(INCLUDED_BSLMF_INTEGRALCONSTANT)
335
336// ----------------------------------------------------------------------------
337// Copyright 2013 Bloomberg Finance L.P.
338//
339// Licensed under the Apache License, Version 2.0 (the "License");
340// you may not use this file except in compliance with the License.
341// You may obtain a copy of the License at
342//
343// http://www.apache.org/licenses/LICENSE-2.0
344//
345// Unless required by applicable law or agreed to in writing, software
346// distributed under the License is distributed on an "AS IS" BASIS,
347// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
348// See the License for the specific language governing permissions and
349// limitations under the License.
350// ----------------------------- END-OF-FILE ----------------------------------
351
352/** @} */
353/** @} */
354/** @} */
value_type operator()() const
Return a copy of the template argument t_VALUE.
Definition bslmf_integralconstant.h:317
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlat_valuetypefunctions.h:939
integral_constant< bool, false > false_type
Definition bslmf_integralconstant.h:290
integral_constant< bool, true > true_type
Definition bslmf_integralconstant.h:296
Definition bslmf_integralconstant.h:261
~integral_constant()=default
t_TYPE value_type
Definition bslmf_integralconstant.h:263
integral_constant type
Definition bslmf_integralconstant.h:264
integral_constant(const integral_constant &)=default
integral_constant operator=(const integral_constant &)=default