BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_isenum.h
Go to the documentation of this file.
1/// @file bslmf_isenum.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_isenum.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISENUM
9#define INCLUDED_BSLMF_ISENUM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_isenum bslmf_isenum
15/// @brief Provide compile-time check for determining enumerated types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_isenum
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_isenum-purpose"> Purpose</a>
25/// * <a href="#bslmf_isenum-classes"> Classes </a>
26/// * <a href="#bslmf_isenum-description"> Description </a>
27/// * <a href="#bslmf_isenum-usage"> Usage </a>
28/// * <a href="#bslmf_isenum-example-1-verify-enumerated-types"> Example 1: Verify Enumerated Types </a>
29///
30/// # Purpose {#bslmf_isenum-purpose}
31/// Provide compile-time check for determining enumerated types.
32///
33/// # Classes {#bslmf_isenum-classes}
34///
35/// - bsl::is_enum: standard meta-function for determining enumerated types
36/// - bsl::is_enum_v: the result value of the `bsl::is_enum` meta-function
37/// - bslmf::IsEnum: meta-function for determining enumerated types
38///
39/// @see bslmf_isfundamental
40///
41/// # Description {#bslmf_isenum-description}
42/// This component defines two meta-functions, `bsl::is_enum` and
43/// `BloombergLP::bslmf::IsEnum` and a template variable `bsl::is_enum_v`, that
44/// represents the result value of the `bsl::is_enum` meta-function. All these
45/// meta-functions may be used to query whether a type is an enumerated type,
46/// optionally qualified with `const` or `volatile`.
47///
48/// `bsl::is_enum` meets the requirements of the `is_enum` template defined in
49/// the C++11 standard [meta.unary.cat], while `bslmf::IsEnum` was devised
50/// before `is_enum` was standardized.
51///
52/// The two meta-functions are functionally equivalent. The major difference
53/// between them is that the result for `bsl::is_enum` is indicated by the class
54/// member `value`, while the result for `bslmf::IsEnum` is indicated by the
55/// class member `value`.
56///
57/// Note that `bsl::is_enum` should be preferred over `bslmf::IsEnum`, and in
58/// general, should be used by new components.
59///
60/// Also note that the template variable `is_enum_v` is defined in the C++17
61/// standard as an inline variable. If the current compiler supports the inline
62/// variable C++17 compiler feature, `bsl::is_enum_v` is defined as an
63/// `inline constexpr bool` variable. Otherwise, if the compiler supports the
64/// variable templates C++14 compiler feature, `bsl::is_enum_v` is defined
65/// as a non-inline `constexpr bool` variable. See
66/// `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
67/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in
68/// bsls_compilerfeatures component for details.
69///
70/// ## Usage {#bslmf_isenum-usage}
71///
72///
73/// In this section we show intended use of this component.
74///
75/// ### Example 1: Verify Enumerated Types {#bslmf_isenum-example-1-verify-enumerated-types}
76///
77///
78/// Suppose that we want to assert whether a set of types are `enum` types.
79///
80/// First, we create an enumerated type, `MyEnum`, and a class type, `MyClass`:
81/// @code
82/// enum MyEnum { MY_ENUMERATOR = 5 };
83/// class MyClass { explicit MyClass(MyEnum); };
84/// @endcode
85/// Now, we instantiate the `bsl::is_enum` template for both types we defined
86/// previously, and assert the `value` static data member of each instantiation:
87/// @code
88/// assert(true == bsl::is_enum<MyEnum>::value);
89/// assert(false == bsl::is_enum<MyClass>::value);
90/// @endcode
91/// Note that if the current compiler supports the variable templates C++14
92/// feature, then we can re-write the snippet of code above as follows:
93/// @code
94/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
95/// assert(true == bsl::is_enum_v<MyEnum>);
96/// assert(false == bsl::is_enum_v<MyClass>);
97/// #endif
98/// @endcode
99/// @}
100/** @} */
101/** @} */
102
103/** @addtogroup bsl
104 * @{
105 */
106/** @addtogroup bslmf
107 * @{
108 */
109/** @addtogroup bslmf_isenum
110 * @{
111 */
112
113#include <bslscm_version.h>
114
115#include <bslmf_conditional.h>
117#include <bslmf_isclass.h>
118#include <bslmf_isconvertible.h>
120#include <bslmf_isfundamental.h>
121#include <bslmf_isreference.h>
122#include <bslmf_removecv.h>
123
125#include <bsls_keyword.h>
126
127#if defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
128# include <type_traits>
129#endif // BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
130
131#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
132#include <bsls_nativestd.h>
133#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
134
135#if defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
136# define BSLS_ISENUM_USE_NATIVE_TRAIT 1
137#endif
138
139namespace bsl {
140
141 // ==============
142 // struct is_enum
143 // ==============
144
145/// This `struct` template implements the `is_enum` meta-function defined in
146/// the C++11 standard [meta.unary.cat] to determine if the (template
147/// parameter) `t_TYPE` is an enumerated type. This `struct` derives from
148/// `bsl::true_type` if the `t_TYPE` is an enumerated type, and from
149/// `bsl::false_type` otherwise.
150template <class t_TYPE>
151struct is_enum;
152
153} // close namespace bsl
154
155
156namespace bslmf {
157
158 // =============
159 // struct IsEnum
160 // =============
161
162/// This `struct` provides a meta-function that computes, at compile time,
163/// whether the (template parameter) `t_TYPE` is an enumerated type. It
164/// derives from `bsl::true_type` if `t_TYPE` is an enumerated type, and
165/// from `bsl::false_type` otherwise.
166///
167/// Enumerated types are the only user-defined types that have the
168/// characteristics of a native arithmetic type (i.e., they can be converted
169/// to an integral type without invoking user-defined conversions). This
170/// class takes advantage of this property to distinguish `enum` types from
171/// class types that are convertible to an integral or enumerated type.
172template <class t_TYPE>
173struct IsEnum : bsl::is_enum<t_TYPE>::type {
174};
175
176} // close package namespace
177
178
179// ============================================================================
180// CLASS TEMPLATE DEFINITIONS
181// ============================================================================
182
183#if defined(BSLS_ISENUM_USE_NATIVE_TRAIT)
184
185namespace bsl {
186
187 // ======================
188 // struct is_enum (C++11)
189 // ======================
190
191/// This specialisation defers entirely to the native trait on supported
192/// C++11 compilers.
193template <class t_TYPE>
194struct is_enum : bsl::integral_constant<bool, ::std::is_enum<t_TYPE>::value> {
195};
196
197#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
198/// This template variable represents the result value of the `bsl::is_enum`
199/// meta-function.
200template <class t_TYPE>
202#endif
203
204} // namespace bsl
205
206#else
207
208
209namespace bslmf {
210
211 // ===============================
212 // struct IsEnum_AnyArithmeticType
213 // ===============================
214
215/// This `struct` provides a type that is convertible from any arithmetic
216/// (i.e., integral or floating-point) type, or any enumerated type.
217/// Converting any type to an `IsEnum_AnyArithmeticType` is a user-defined
218/// conversion and cannot be combined with any other implicit user-defined
219/// conversions. Thus, even class types that have conversion operators to
220/// arithmetic types or enumerated types will not be implicitly convertible
221/// to `IsEnum_AnyArithmeticType`.
223
224 // NOT IMPLEMENTED
225
226 /// Create an `IsEnum_AnyArithmeticType` object from a value of one of
227 /// the indicated arithmetic types. Note that it is not necessary to
228 /// provide overloads taking `bool`, `char`, or `short` because they are
229 /// automatically promoted to `int`; nor is a `float` overload needed
230 /// because it is automatically promoted to `double`. Also note that
231 /// the other variants are necessary because a conversion from, e.g., a
232 /// `long double` to a `double` does not take precedence over a
233 /// conversion from `long double` to `int` and, therefore, would be
234 /// ambiguous.
235 IsEnum_AnyArithmeticType(wchar_t); // IMPLICIT
236 IsEnum_AnyArithmeticType(int); // IMPLICIT
237 IsEnum_AnyArithmeticType(unsigned int); // IMPLICIT
238 IsEnum_AnyArithmeticType(long); // IMPLICIT
239 IsEnum_AnyArithmeticType(unsigned long); // IMPLICIT
240 IsEnum_AnyArithmeticType(long long); // IMPLICIT
241 IsEnum_AnyArithmeticType(unsigned long long); // IMPLICIT
242 IsEnum_AnyArithmeticType(double); // IMPLICIT
243 IsEnum_AnyArithmeticType(long double); // IMPLICIT
244};
245
246template <class COMPLETE_TYPE>
249 bsl::is_convertible<COMPLETE_TYPE, IsEnum_AnyArithmeticType>::value
250 && !IsConvertibleToAny<COMPLETE_TYPE>::value>::type {
251};
252
253} // close package namespace
254
255
256namespace bsl {
257
258 // ======================
259 // struct is_enum (C++03)
260 // ======================
261
262/// This formula determines whether or not most (complete) types are, or are
263/// not, enumerations using only facilities available to a C++03 compiler;
264/// additional specializations will handle the remaining corner cases.
265template <class t_TYPE>
267: conditional<!is_fundamental<t_TYPE>::value && !is_reference<t_TYPE>::value &&
268 !is_class<t_TYPE>::value,
269 BloombergLP::bslmf::IsEnum_TestConversions<t_TYPE>,
270 false_type>::type {
271};
272
273/// Pointers are not enumerated types. This is captured above without this
274/// partial specialization, but the convertability tests can trigger ADL
275/// such that the compiler will want t_TYPE to be complete, breaking some
276/// desirable usages involving forward-declarations.
277template <class t_TYPE>
278struct is_enum<t_TYPE *> : false_type {
279};
280
281template <>
282struct is_enum<void>
284};
285
286// Additional partial specializations for cv-qualified types ensure that the
287// correct result is obtained for cv-qualified 'enum's. Note that there is a
288// peculiar bug with the IBM xlC compiler that requires an additional use of
289// the 'remove_cv' trait to obtain the correct result (without infinite
290// recursion) for arrays of more than one dimension.
291
292template <class t_TYPE>
293struct is_enum<const t_TYPE>
294: is_enum<typename bsl::remove_cv<t_TYPE>::type>::type {
295};
296
297template <class t_TYPE>
298struct is_enum<volatile t_TYPE>
299: is_enum<typename bsl::remove_cv<t_TYPE>::type>::type {
300};
301
302template <class t_TYPE>
303struct is_enum<const volatile t_TYPE>
304: is_enum<typename bsl::remove_cv<t_TYPE>::type>::type {
305};
306
307} // close namespace bsl
308
309#endif // BSLS_ISENUM_USE_NATIVE_TRAIT
310
311#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
312// ============================================================================
313// BACKWARD COMPATIBILITY
314// ============================================================================
315
316#ifdef bslmf_IsEnum
317#undef bslmf_IsEnum
318#endif
319/// This alias is defined for backward compatibility.
320#define bslmf_IsEnum bslmf::IsEnum
321#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
322
323#endif
324
325// ----------------------------------------------------------------------------
326// Copyright 2013 Bloomberg Finance L.P.
327//
328// Licensed under the Apache License, Version 2.0 (the "License");
329// you may not use this file except in compliance with the License.
330// You may obtain a copy of the License at
331//
332// http://www.apache.org/licenses/LICENSE-2.0
333//
334// Unless required by applicable law or agreed to in writing, software
335// distributed under the License is distributed on an "AS IS" BASIS,
336// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
337// See the License for the specific language governing permissions and
338// limitations under the License.
339// ----------------------------- END-OF-FILE ----------------------------------
340
341/** @} */
342/** @} */
343/** @} */
static const t_TYPE value
Definition bslmf_integralconstant.h:258
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_INLINE_VARIABLE
Definition bsls_keyword.h:623
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
Definition bslmf_conditional.h:120
Definition bslmf_integralconstant.h:244
Definition bslmf_isenum.h:270
Definition bslmf_isenum.h:222
IsEnum_AnyArithmeticType(unsigned long)
IsEnum_AnyArithmeticType(unsigned int)
IsEnum_AnyArithmeticType(unsigned long long)
Definition bslmf_isenum.h:250
Definition bslmf_isenum.h:173