BDE 4.14.0 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::false_type: `typedef` for `integral_constant<bool, false>`
38/// - bsl::true_type: `typedef` for `integral_constant<bool, true>`
39///
40/// @see
41///
42/// # Description {#bslmf_integralconstant-description}
43/// This component describes a simple class template,
44/// `bsl::integral_constant`, that is used to map an integer constant to a C++
45/// type. `integral_constant<t_TYPE, t_VAL>` generates a unique type for each
46/// distinct compile-time integral `t_TYPE` and constant integer `t_VAL`
47/// parameter. That is, instantiations with different integer types and values
48/// form distinct types, so that `integral_constant<int, 0>` is a different type
49/// from `integral_constant<int, 1>`, which is also distinct from
50/// `integral_constant<unsigned, 1>`, and so on. This mapping of integer values
51/// to types allows for "overloading by value", i.e., multiple functions with
52/// the same name can be overloaded on the "value" of an `integral_constant`
53/// argument, provided that the value is known at compile-time. The typedefs
54/// `bsl::true_type` and `bsl::false_type` map the predicate values `true` and
55/// `false` to C++ types that are frequently useful for compile-time algorithms.
56///
57/// ## Usage {#bslmf_integralconstant-usage}
58///
59///
60/// This section illustrates intended usage of this component
61///
62/// ### Example 1: Compile-Time Function Dispatching {#bslmf_integralconstant-example-1-compile-time-function-dispatching}
63///
64///
65/// The most common use of this structure is to perform compile-time function
66/// dispatching based on a compile-time calculation. Often the calculation is
67/// nothing more than a simple predicate, allowing us to select one of two
68/// functions based on whether the predicate holds. The following function,
69/// `doSomething`, uses a fast implementation (e.g., using `memcpy`) if the
70/// parameterized type allows for such operations, otherwise it will use a more
71/// generic and slower implementation (e.g., using the copy constructor). This
72/// example uses the types `true_type` and `false_type`, which are simple
73/// typedefs for `integral_constant<bool, true>` and
74/// `integral_constant<bool, false>`, respectively.
75/// @code
76/// #include <bslmf_integralconstant.h>
77///
78/// template <class t_T>
79/// int doSomethingImp(t_T *t, bsl::true_type)
80/// {
81/// // slow, generic implementation
82/// // ...
83/// (void) t;
84/// return 11;
85/// }
86///
87/// template <class t_T>
88/// int doSomethingImp(t_T *t, bsl::false_type)
89/// {
90/// // fast implementation that works only for some types of 't_T'
91/// // ...
92/// (void) t;
93/// return 55;
94/// }
95///
96/// template <bool IsSlow, class t_T>
97/// int doSomething(t_T *t)
98/// {
99/// // Dispatch to an implementation depending on the (compile-time)
100/// // value of 'IsSlow'.
101/// return doSomethingImp(t, bsl::integral_constant<bool, IsSlow>());
102/// }
103/// @endcode
104/// For some parameter types, the fast version of `doSomethingImp` is not
105/// legal. The power of this approach is that the compiler will not attempt
106/// semantic analysis on the implementation that does not match the appropriate
107/// `integral_constant` argument.
108/// @code
109/// int main()
110/// {
111/// int r;
112///
113/// int i;
114/// r = doSomething<false>(&i); // select fast version for int
115/// assert(55 == r);
116///
117/// double m;
118/// r = doSomething<true>(&m); // select slow version for double
119/// assert(11 == r);
120///
121/// return 0;
122/// }
123/// @endcode
124///
125/// ### Example 2: Base Class For Metafunctions {#bslmf_integralconstant-example-2-base-class-for-metafunctions}
126///
127///
128/// Hard-coding the value of an `integral_constant` is not especially useful.
129/// Rather, `integral_constant` is typically used as the base class for
130/// "metafunction" classes, classes that yield the value of compile-time
131/// properties, including properties that are associated with types, rather
132/// than with values. For example, the following metafunction can be used at
133/// compile time to determine whether a type is a floating point type:
134/// @code
135/// template <class t_TYPE> struct IsFloatingPoint : bsl::false_type { };
136/// template <> struct IsFloatingPoint<float> : bsl::true_type { };
137/// template <> struct IsFloatingPoint<double> : bsl::true_type { };
138/// template <> struct IsFloatingPoint<long double> : bsl::true_type { };
139/// @endcode
140/// The value `IsFloatingPoint<int>::value` is false and
141/// `IsFloatingPoint<double>::value` is true. The `integral_constant` base
142/// class has a member type, `type`, that refers to itself and is inherited by
143/// `IsFloatingPoint`. Thus `IsFloatingPoint<float>::type` is `true_type` and
144/// `IsFloatingPoint<char>::type` is `false_type`. `IsFloatingPoint` is an a
145/// member of a common category of metafunctions known as "type traits" because
146/// they express certain properties (traits) of a type. Using this
147/// metafunction, we can rewrite the `doSomething` function from first example
148/// so that it does not require the user to specify the `IsSlow` template
149/// argument:
150/// @code
151/// template <class t_T>
152/// int doSomething2(t_T *t)
153/// {
154/// // Automatically detect whether to use slow or fast imp.
155/// const bool isSlow = IsFloatingPoint<t_T>::value;
156/// return doSomethingImp(t, bsl::integral_constant<bool, isSlow>());
157/// }
158///
159/// int main()
160/// {
161/// int r;
162///
163/// int i;
164/// r = doSomething2(&i); // select fast version for int
165/// assert(55 == r);
166///
167/// double m;
168/// r = doSomething2(&m); // select slow version for double
169/// assert(11 == r);
170///
171/// return 0;
172/// }
173/// @endcode
174/// @}
175/** @} */
176/** @} */
177
178/** @addtogroup bsl
179 * @{
180 */
181/** @addtogroup bslmf
182 * @{
183 */
184/** @addtogroup bslmf_integralconstant
185 * @{
186 */
187
188#include <bslscm_version.h>
189
192#include <bsls_keyword.h>
193#include <bsls_libraryfeatures.h>
194
195#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
196# include <type_traits>
197#endif // BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
198
199#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
200#include <bsls_nativestd.h>
201#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
202
203#define BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE \
204 BSLS_DEPRECATE_FEATURE("bsl", "legacy_true_and_false_VALUE", \
205 "use standard, lower-case, 'value' instead")
206
207namespace bsl {
208
209 // ================================
210 // class template integral_constant
211 // ================================
212
213#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
214template <class t_TYPE, t_TYPE t_VAL>
215struct integral_constant : ::std::integral_constant<t_TYPE, t_VAL> {
216 typedef integral_constant type;
217};
218
219template <>
220struct integral_constant<bool, false> : ::std::false_type
221{
222 typedef integral_constant type;
223
224 // COMPATIBILITY MEMBERS
226 static const bool VALUE = false;
227};
228
229template <>
230struct integral_constant<bool, true> : ::std::true_type
231{
232 typedef integral_constant type;
233
234 // COMPATIBILITY MEMBERS
236 static const bool VALUE = true;
237};
238
239#else
240/// Generate a unique type for the given `t_TYPE` and `t_VAL`. This
241/// `struct` is used for compile-time dispatch of overloaded functions and
242/// as the base class for many metafunctions.
243template <class t_TYPE, t_TYPE t_VAL>
245
246 public:
247 // CREATORS
248 integral_constant() = default;
252
253 // PUBLIC TYPES
254 typedef t_TYPE value_type;
256
257 // PUBLIC CLASS DATA
258 static const t_TYPE value = t_VAL;
259
260 // ACCESSORS
261
262 /// Return `t_VAL`.
264};
265
266template <bool t_VAL>
267struct integral_constant<bool, t_VAL> {
268 public:
269 // CREATORS
270 integral_constant() = default;
274
275 // PUBLIC TYPES
276 typedef bool value_type;
278
279 // PUBLIC CLASS DATA
280 static const bool value = t_VAL;
281
282 // ACCESSORS
283
284 /// Return `t_VAL`.
286
287 // COMPATIBILITY MEMBERS
289 static const bool VALUE = t_VAL;
290};
291#endif // defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
292
293 // ===============
294 // type false_type
295 // ===============
296
298
299 // ===============
300 // type true_type
301 // ===============
302
304
305 // ======================
306 // template bool_constant
307 // ======================
308
309#ifdef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
310template <bool t_VALUE>
311using bool_constant = integral_constant<bool, t_VALUE>;
312
313# if !defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BOOL_CONSTANT)
314# define BSLS_LIBRARYFEATURES_HAS_CPP17_BOOL_CONSTANT 1
315# endif
316#endif
317
318} // close namespace bsl
319
320// ============================================================================
321// INLINE FUNCTION DEFINITIONS
322// ============================================================================
323// STATIC MEMBER VARIABLE DEFINITIONS
324// Note that these definitions are deprecated under C++17, when 'constexpr'
325// data members are implicitly 'inline'.
326#if !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
327// This variable will be supplied by the platform header, when available.
328template <class t_TYPE, t_TYPE t_VAL>
330
331template <bool t_VAL>
333template <bool t_VAL>
335
336// ACCESSORS
337template <class t_TYPE, t_TYPE t_VAL>
338inline
341{
342 return t_VAL;
343}
344
345template <bool t_VAL>
346inline
349{
350 return t_VAL;
351}
352#endif // ! defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
353
354#undef BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE
355
356#endif // ! defined(INCLUDED_BSLMF_INTEGRALCONSTANT)
357
358// ----------------------------------------------------------------------------
359// Copyright 2013 Bloomberg Finance L.P.
360//
361// Licensed under the Apache License, Version 2.0 (the "License");
362// you may not use this file except in compliance with the License.
363// You may obtain a copy of the License at
364//
365// http://www.apache.org/licenses/LICENSE-2.0
366//
367// Unless required by applicable law or agreed to in writing, software
368// distributed under the License is distributed on an "AS IS" BASIS,
369// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
370// See the License for the specific language governing permissions and
371// limitations under the License.
372// ----------------------------- END-OF-FILE ----------------------------------
373
374/** @} */
375/** @} */
376/** @} */
static const t_TYPE value
Definition bslmf_integralconstant.h:258
#define BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE
Definition bslmf_integralconstant.h:203
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
Definition bdlb_printmethods.h:283
integral_constant< bool, false > false_type
Definition bslmf_integralconstant.h:297
integral_constant< bool, true > true_type
Definition bslmf_integralconstant.h:303
bool value_type
Definition bslmf_integralconstant.h:276
integral_constant type
Definition bslmf_integralconstant.h:277
integral_constant(const integral_constant &)=default
integral_constant operator=(const integral_constant &)=default
Definition bslmf_integralconstant.h:244
~integral_constant()=default
integral_constant operator=(const integral_constant &)=default
integral_constant type
Definition bslmf_integralconstant.h:255
integral_constant(const integral_constant &)=default
t_TYPE value_type
Definition bslmf_integralconstant.h:254