BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_ispolymorphic.h
Go to the documentation of this file.
1/// @file bslmf_ispolymorphic.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_ispolymorphic.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISPOLYMORPHIC
9#define INCLUDED_BSLMF_ISPOLYMORPHIC
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_ispolymorphic bslmf_ispolymorphic
15/// @brief Provide a compile-time check for determining polymorphic types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_ispolymorphic
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_ispolymorphic-purpose"> Purpose</a>
25/// * <a href="#bslmf_ispolymorphic-classes"> Classes </a>
26/// * <a href="#bslmf_ispolymorphic-description"> Description </a>
27/// * <a href="#bslmf_ispolymorphic-usage"> Usage </a>
28/// * <a href="#bslmf_ispolymorphic-example-1-verify-polymorphic-types"> Example 1: Verify Polymorphic Types </a>
29///
30/// # Purpose {#bslmf_ispolymorphic-purpose}
31/// Provide a compile-time check for determining polymorphic types.
32///
33/// # Classes {#bslmf_ispolymorphic-classes}
34///
35/// - bsl::is_polymorphic: standard meta-function for detecting polymorphic types
36/// - bsl::is_polymorphic_v: the result value of the meta-function
37/// - bslmf::IsPolymorphic: meta-function for detecting polymorphic types
38///
39/// # Description {#bslmf_ispolymorphic-description}
40/// This component defines two meta-functions,
41/// `bsl::is_polymorphic` and `BloombergLP::bslmf::IsPolymorphic` and a template
42/// variable `bsl::is_polymorphic_v`, that represents the result value of the
43/// `bsl::is_polymorphic` meta-function. All of these meta-functions may be
44/// used to query whether a type is a polymorphic class as defined in the C++11
45/// standard [class.virtual]. A class is polymorphic if it has at least one
46/// virtual function. Note that the destructor of such a class should *always*
47/// be declared `virtual`. Therefore, another definition of polymorphic is
48/// whether a class has a virtual destructor.
49///
50/// `bsl::is_polymorphic` has the same syntax as the `is_polymorphic` template
51/// defined in the C++11 standard [meta.unary.prop], while
52/// `bslmf::IsPolymorphic` was devised before `is_polymorphic` was standardized.
53/// `bsl::is_polymorphic` meets the requirements of the C++11 standard with two
54/// exceptions:
55///
56/// 1. The compilation will fail if the meta-function is used to evaluate a
57/// `union` type, unless one of the following compilers, which provide an
58/// intrinsic operation to detect this specific trait, is used:
59/// - gcc 4.3 or later
60/// - Visual C++ 2008 or later
61/// 2. The meta-function will yield false positives, claiming non-polymorphic
62/// types *are* polymorphic, for types using virtual inheritance. This case
63/// is known to be handled *correctly* for the following compilers only:
64/// - Compilers with intrinsic support, listed above
65/// - IBM XLC
66///
67/// The two meta-functions are functionally equivalent. The major difference
68/// between them is that the result for `bsl::is_polymorphic` is indicated by
69/// the class member `value`, while the result for `bslmf::IsPolymorphic` is
70/// indicated by the class member `value`. `bsl::is_polymorphic` should be
71/// preferred over `bslmf::IsPolymorphic`, and in general, should be used by new
72/// components.
73///
74/// Note that the template variable `is_polymorphic_v` is defined in the C++17
75/// standard as an inline variable. If the current compiler supports the inline
76/// variable C++17 compiler feature, `bsl::is_polymorphic_v` is defined as an
77/// `inline constexpr bool` variable. Otherwise, if the compiler supports the
78/// variable templates C++14 compiler feature, `bsl::is_polymorphic_v` is
79/// defined as a non-inline `constexpr bool` variable. See
80/// `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
81/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in
82/// bsls_compilerfeatures component for details.
83///
84/// ## Usage {#bslmf_ispolymorphic-usage}
85///
86///
87/// In this section we show intended use of this component.
88///
89/// ### Example 1: Verify Polymorphic Types {#bslmf_ispolymorphic-example-1-verify-polymorphic-types}
90///
91///
92/// Suppose that we want to assert whether a particular type is a polymorphic
93/// type.
94///
95/// First, we define two types in a non-polymorphic hierarchy, `MyStruct` and
96/// `MyDerivedStruct`:
97/// @code
98/// struct MyStruct {
99/// void nonvirtualMethod();
100/// };
101/// struct MyDerivedStruct : public MyStruct {
102/// };
103/// @endcode
104/// Then, we define two types in a polymorphic hierarchy, `MyClass` and
105/// `MyDerivedClass`:
106/// @code
107/// class MyClass {
108/// public:
109/// MyClass();
110/// virtual ~MyClass(); // makes 'MyClass' polymorphic
111/// };
112///
113/// class MyDerivedClass : public MyClass {
114/// public:
115/// MyDerivedClass();
116/// virtual ~MyDerivedClass();
117/// };
118/// @endcode
119/// Now, assert that the two types in the non-polymorphic hierarchy are not
120/// polymorphic, and that the two types in the polymorphic hierarchy are
121/// polymorphic using `bsl::is_polymorphic`:
122/// @code
123/// assert(false == bsl::is_polymorphic<MyStruct >::value);
124/// assert(false == bsl::is_polymorphic<MyStruct *>::value);
125/// assert(false == bsl::is_polymorphic<MyDerivedStruct& >::value);
126/// assert(false == bsl::is_polymorphic<MyDerivedStruct *>::value);
127///
128/// assert(true == bsl::is_polymorphic< MyClass >::value);
129/// assert(false == bsl::is_polymorphic<const MyClass& >::value);
130/// assert(false == bsl::is_polymorphic< MyClass *>::value);
131/// assert(true == bsl::is_polymorphic<MyDerivedClass >::value);
132/// assert(false == bsl::is_polymorphic<MyDerivedClass& >::value);
133/// assert(false == bsl::is_polymorphic<MyDerivedClass *>::value);
134/// @endcode
135/// Note that if the current compiler supports the variable templates C++14
136/// feature then we can re-write the snippet of code above using the
137/// `bsl::is_polymorphic_v` variable as follows:
138/// @code
139/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
140/// assert(false == bsl::is_polymorphic_v<MyStruct >);
141/// assert(false == bsl::is_polymorphic_v<MyStruct *>);
142/// assert(false == bsl::is_polymorphic_v<MyDerivedStruct& >);
143/// assert(false == bsl::is_polymorphic_v<MyDerivedStruct *>);
144///
145/// assert(true == bsl::is_polymorphic_v< MyClass >);
146/// assert(false == bsl::is_polymorphic_v<const MyClass& >);
147/// assert(false == bsl::is_polymorphic_v< MyClass *>);
148/// assert(true == bsl::is_polymorphic_v<MyDerivedClass >);
149/// assert(false == bsl::is_polymorphic_v<MyDerivedClass& >);
150/// assert(false == bsl::is_polymorphic_v<MyDerivedClass *>);
151/// #endif
152/// @endcode
153/// @}
154/** @} */
155/** @} */
156
157/** @addtogroup bsl
158 * @{
159 */
160/** @addtogroup bslmf
161 * @{
162 */
163/** @addtogroup bslmf_ispolymorphic
164 * @{
165 */
166
167#include <bslscm_version.h>
168
170#include <bslmf_isclass.h>
171#include <bslmf_removecv.h>
172
174#include <bsls_exceptionutil.h>
175#include <bsls_keyword.h>
176#include <bsls_platform.h>
177
178#if defined(BSLS_PLATFORM_CMP_CLANG) \
179 || defined(BSLS_PLATFORM_CMP_GNU) \
180 || defined(BSLS_PLATFORM_CMP_MSVC) \
181 || (defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION >= 0x5130)
182# define BSLMF_ISPOLYMORPHIC_HAS_INTRINSIC
183#endif
184
185
186namespace bslmf {
187
188 // ========================
189 // struct IsPolymorphic_Imp
190 // ========================
191
192#if defined(BSLMF_ISPOLYMORPHIC_HAS_INTRINSIC)
193
194// Use type traits intrinsic, where available, to give the correct answer for
195// the tricky cases where existing ABIs prevent programmatic detection.
196template <class t_TYPE>
197struct IsPolymorphic_Imp {
198 enum { Value = __is_polymorphic(t_TYPE) };
199};
200
201#else
202
203template <class t_TYPE, bool t_IS_CLASS = bsl::is_class<t_TYPE>::value>
205 // This 'struct' template provides a meta-function to determine whether the
206 // (template parameter) 't_TYPE' is a (non-cv-qualified) polymorphic type.
207 // This generic default template defines a static data member, 'Value',
208 // that is set to 'false'. A template specialization is provided (below)
209 // to handle the case where 't_TYPE' is a class type that may be
210 // polymorphic.
211
212 enum { Value = false };
213};
214
215template <class t_TYPE>
216struct IsPolymorphic_Imp<t_TYPE, true> {
217 // This partial specialization of 'IsPolymorphic_Imp', for when the
218 // (template parameter) 't_TYPE' is a (non-cv-qualified) class type,
219 // provides a static data member, 'Value', that is set to 'true' if
220 // 't_TYPE' is polymorphic and 'false' otherwise.
221
222 struct IsPoly : public t_TYPE {
225
226 char dummy[256];
227 };
228
229 struct MaybePoly : public t_TYPE {
232 char dummy[256];
233 };
234
235 enum { Value = (sizeof(IsPoly) == sizeof(MaybePoly)) };
236};
237
238#endif
239
240} // close package namespace
241
242
243namespace bsl {
244
245/// This `struct` template implements the `is_polymorphic` meta-function
246/// defined in the C++11 standard [meta.unary.prop] to determine if the
247/// (template parameter) `t_TYPE` is a (possibly cv-qualified) polymorphic
248/// type. This `struct` derives from `bsl::true_type` if the `t_TYPE` is a
249/// polymorphic type, and `bsl::false_type` otherwise.
250template <class t_TYPE>
252: integral_constant<bool,
253 BloombergLP::bslmf::IsPolymorphic_Imp<
254 typename remove_cv<t_TYPE>::type>::Value> {
255};
256
257#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
258/// This template variable represents the result value of the
259/// `bsl::is_polymorphic` meta-function.
260template <class t_TYPE>
261BSLS_KEYWORD_INLINE_VARIABLE constexpr bool is_polymorphic_v =
263#endif
264
265} // close namespace bsl
266
267
268
269namespace bslmf {
270
271 // ====================
272 // struct IsPolymorphic
273 // ====================
274
275/// This `struct` template implements a meta-function to determine if the
276/// (template parameter) `t_TYPE` is a (possibly cv-qualified) polymorphic
277/// type. This `struct` derives from `bsl::true_type` if the `t_TYPE` is a
278/// polymorphic type, and `bsl::false_type` otherwise.
279///
280/// Note that although this `struct` is functionally equivalent to
281/// `bsl::is_polymorphic`, the use of `bsl::is_polymorphic` should be
282/// preferred.
283template <class t_TYPE>
284struct IsPolymorphic : bsl::is_polymorphic<t_TYPE>::type {
285};
286
287} // close package namespace
288
289#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
290// ============================================================================
291// BACKWARD COMPATIBILITY
292// ============================================================================
293
294#ifdef bslmf_IsPolymorphic
295#undef bslmf_IsPolymorphic
296#endif
297/// This alias is defined for backward compatibility.
298#define bslmf_IsPolymorphic bslmf::IsPolymorphic
299#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
300
301
302
303#endif
304
305// ----------------------------------------------------------------------------
306// Copyright 2013 Bloomberg Finance L.P.
307//
308// Licensed under the Apache License, Version 2.0 (the "License");
309// you may not use this file except in compliance with the License.
310// You may obtain a copy of the License at
311//
312// http://www.apache.org/licenses/LICENSE-2.0
313//
314// Unless required by applicable law or agreed to in writing, software
315// distributed under the License is distributed on an "AS IS" BASIS,
316// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
317// See the License for the specific language governing permissions and
318// limitations under the License.
319// ----------------------------- END-OF-FILE ----------------------------------
320
321/** @} */
322/** @} */
323/** @} */
#define BSLS_NOTHROW_SPEC
Definition bsls_exceptionutil.h:386
#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_integralconstant.h:244
Definition bslmf_ispolymorphic.h:254
Definition bslmf_ispolymorphic.h:204
@ Value
Definition bslmf_ispolymorphic.h:212
Definition bslmf_ispolymorphic.h:284