BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_isfunction.h
Go to the documentation of this file.
1/// @file bslmf_isfunction.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_isfunction.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISFUNCTION
9#define INCLUDED_BSLMF_ISFUNCTION
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_isfunction bslmf_isfunction
15/// @brief Provide a compile-time check for determining function types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_isfunction
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_isfunction-purpose"> Purpose</a>
25/// * <a href="#bslmf_isfunction-classes"> Classes </a>
26/// * <a href="#bslmf_isfunction-description"> Description </a>
27/// * <a href="#bslmf_isfunction-usage"> Usage </a>
28/// * <a href="#bslmf_isfunction-example-1-verify-function-types"> Example 1: Verify Function Types </a>
29///
30/// # Purpose {#bslmf_isfunction-purpose}
31/// Provide a compile-time check for determining function types.
32///
33/// # Classes {#bslmf_isfunction-classes}
34///
35/// - bsl::is_function: standard meta-function for determining function types
36/// - bsl::is_function_v: the result value of `bsl::is_function`
37///
38/// @see bslmf_integralconstant
39///
40/// # Description {#bslmf_isfunction-description}
41/// This component defines a meta-function, `bsl::is_function` and
42/// a template variable `bsl::is_function_v`, that represents the result value
43/// of the `bsl::is_function` meta-function, that may be used to query whether a
44/// template parameter type is a function type.
45///
46/// `bsl::is_function` meets the requirements of the `is_function` template
47/// defined in the C++11 standard [meta.unary.cat].
48///
49/// Note that the template variable `is_function_v` is defined in the C++17
50/// standard as an inline variable. If the current compiler supports the inline
51/// variable C++17 compiler feature, `bsl::is_function_v` is defined as an
52/// `inline constexpr bool` variable. Otherwise, if the compiler supports the
53/// variable templates C++14 compiler feature, `bsl::is_function_v` is defined
54/// as a non-`const` `constexpr bool` variable. See
55/// `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
56/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in
57/// bsls_compilerfeatures component for details.
58///
59/// ## Usage {#bslmf_isfunction-usage}
60///
61///
62/// In this section we show intended use of this component.
63///
64/// ### Example 1: Verify Function Types {#bslmf_isfunction-example-1-verify-function-types}
65///
66///
67/// Suppose that we want to assert whether a set of types are function types.
68///
69/// Now, we instantiate the `bsl::is_function` template for both a non-function
70/// type and a function type, and assert the `value` static data member of each
71/// instantiation:
72/// @code
73/// assert(false == bsl::is_function<int>::value);
74/// assert(true == bsl::is_function<int (int)>::value);
75/// @endcode
76/// Note that if the current compiler supports the variable templates C++14
77/// feature, then we can re-write the snippet of code above using the
78/// `bsl::is_function_v` variable as follows:
79/// @code
80/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
81/// assert(false == bsl::is_function_v<int>);
82/// assert(true == bsl::is_function_v<int (int)>);
83/// #endif
84/// @endcode
85/// @}
86/** @} */
87/** @} */
88
89/** @addtogroup bsl
90 * @{
91 */
92/** @addtogroup bslmf
93 * @{
94 */
95/** @addtogroup bslmf_isfunction
96 * @{
97 */
98
99#include <bslscm_version.h>
100
102#include <bslmf_isconst.h>
103
105#include <bsls_keyword.h>
106#include <bsls_platform.h>
107
108#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
109#include <bslmf_addpointer.h>
111#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
112
113#if defined(BSLS_PLATFORM_CMP_IBM)
114// The IBM xlC compiler produces a "hard" error (not eligible for SFINAE) when
115// trying to apply cv-qualifiers to a template parameter (or typedef) that is a
116// function type. Hence, a more oblique approach is needed to detect all
117// function types on this platform. This implementation relies on the fact
118// that you cannot form an array of function types.
119
120
121namespace bslmf {
122
123struct IsFunction_Imp {
124 struct FalseType {
125 // This 'struct' provides a type larger than 'char' to be used in
126 // unevaluated contexts, allowing 'sizeof(selected overload)' to
127 // distinguish which overload was called when all other overloads
128 // return a 'char'.
129
130 char d_dummy[17]; // Member to guarantee 'sizeof(FalseType) > 1'
131 };
132
133 template <class t_TYPE>
134 static FalseType test(int t_TYPE::*, void *);
135 // This function will match any class type, including abstract types.
136
137 template <class t_TYPE>
138 static FalseType test(t_TYPE (*)[2], ...);
139 // This function will match all types other than those that cannot be
140 // used to form an array. This includes function types, reference
141 // types, void types, and abstract types. Further overloads and
142 // specializations will filter the reference, array, and abstract
143 // types.
144
145 template <class t_TYPE>
146 static char test(...);
147 // This function, when called with '0' in a non-evaluated context, will
148 // match anything that the previous overloads fail to match, which will
149 // include all function types, reference types, void types, and arrays
150 // of unknown bound.
151};
152
153} // close package namespace
154
155
156namespace bsl {
157
158template <class t_TYPE>
159struct is_function
160: integral_constant<
161 bool,
162 sizeof(BloombergLP::bslmf::IsFunction_Imp::test<t_TYPE>(0, 0)) == 1> {
163 // This 'struct' template implements the 'is_function' meta-function
164 // defined in the C++11 standard [meta.unary.cat] to determine if the
165 // (template parameter) 't_TYPE' is a function type. This 'struct' derives
166 // from 'bsl::true_type' if the 't_TYPE' is a function type, and from
167 // 'bsl::false_type' otherwise.
168};
169
170template <class t_TYPE>
171struct is_function<t_TYPE[]> : false_type {
172 // Array types are, self-evidently, never function types. Arrays of
173 // unknown bound will be misdiagnosed by the 'IsFunction_Imp' detector, so
174 // this template is partially specialized to resolve such cases.
175};
176
177template <class t_TYPE>
178struct is_function<t_TYPE&> : false_type {
179 // Reference types are, self-evidently, never function types. This
180 // template is partially specialized to resolve such cases, as the
181 // detection idiom embodied in 'IsFunction_Imp' would yield the wrong
182 // result otherwise.
183};
184
185template <>
186struct is_function<void> : false_type {
187 // 'void' types are not functions. It is easier to provide 4 cv-qualified
188 // explicit specializations than introduce a further dependency and chain
189 // template instantiations through 'remove_cv'.
190};
191
192template <>
193struct is_function<const void> : false_type {
194 // 'void' types are not functions. It is easier to provide 4 cv-qualified
195 // explicit specializations than introduce a further dependency and chain
196 // template instantiations through 'remove_cv'.
197};
198
199template <>
200struct is_function<volatile void> : false_type {
201 // 'void' types are not functions. It is easier to provide 4 cv-qualified
202 // explicit specializations than introduce a further dependency and chain
203 // template instantiations through 'remove_cv'.
204};
205
206template <>
207struct is_function<const volatile void> : false_type {
208 // 'void' types are not functions. It is easier to provide 4 cv-qualified
209 // explicit specializations than introduce a further dependency and chain
210 // template instantiations through 'remove_cv'.
211};
212
213} // close namespace bsl
214
215#else // This is the simplest implementation, for conforming compilers.
216namespace bsl {
217
218#ifdef BSLS_PLATFORM_CMP_MSVC
219# pragma warning(push)
220# pragma warning(disable: 4180) // cv-qualifier has no effect on function type
221#endif
222
223/// This `struct` template implements the `is_function` meta-function
224/// defined in the C++11 standard [meta.unary.cat] to determine if the
225/// (template parameter) `t_TYPE` is a function type. This `struct` derives
226/// from `bsl::true_type` if the `t_TYPE` is a function type, and from
227/// `bsl::false_type` otherwise. This implementation relies on the fact
228/// that neither function types nor reference types can be cv-qualified so
229/// that `is_const<const t_TYPE>` will actually yield `false`.
230template <class t_TYPE>
232: bsl::integral_constant<bool, !is_const<const t_TYPE>::value> {
233};
234
235#ifdef BSLS_PLATFORM_CMP_MSVC
236# pragma warning(pop)
237#endif
238
239/// Reference types are, self-evidently, never function types. The idiom
240/// for detecting function types in this component is that a function is a
241/// type that is the same as the const-qualified version of that same type.
242/// As references also have this property, we must filter out references
243/// with this partial specialization.
244template <class t_TYPE>
245struct is_function<t_TYPE&> : false_type {
246};
247
248#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
249/// Reference types are, self-evidently, never function types. The idiom
250/// for detecting function types in this component is that a function is a
251/// type that is the same as the const-qualified version of that same type.
252/// As references also have this property, we must filter out references
253/// with this partial specialization.
254template <class t_TYPE>
255struct is_function<t_TYPE&&> : false_type {
256};
257# endif
258
259#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
260/// This template variable represents the result value of the
261/// `bsl::is_function` meta-function.
262template <class t_TYPE>
263BSLS_KEYWORD_INLINE_VARIABLE constexpr bool is_function_v =
265#endif
266
267} // close namespace bsl
268#endif
269
270#endif
271
272// ----------------------------------------------------------------------------
273// Copyright 2017 Bloomberg Finance L.P.
274//
275// Licensed under the Apache License, Version 2.0 (the "License");
276// you may not use this file except in compliance with the License.
277// You may obtain a copy of the License at
278//
279// http://www.apache.org/licenses/LICENSE-2.0
280//
281// Unless required by applicable law or agreed to in writing, software
282// distributed under the License is distributed on an "AS IS" BASIS,
283// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
284// See the License for the specific language governing permissions and
285// limitations under the License.
286// ----------------------------- END-OF-FILE ----------------------------------
287
288/** @} */
289/** @} */
290/** @} */
static const bool 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
integral_constant< bool, false > false_type
Definition bslmf_integralconstant.h:297
Definition bdlbb_blob.h:576
Definition bslmf_integralconstant.h:244
Definition bslmf_isfunction.h:232