• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[article CallableTraits
2    [quickbook 1.6]
3    [id callable_traits]
4        [copyright 2016-2018 Barrett Adair]
5    [authors [Adair, Barrett]]
6        [license
7        Distributed under the Boost Software License, Version 1.0.
8        (See accompanying file LICENSE.md or copy at
9        [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt])
10    ]
11    [source-mode c++]
12        [last-revision $Date$]
13        [lang en]
14]
15
16[/ developer: you should enable word wrap before you read further]
17
18[template libname[][^Boost.CallableTraits]]
19[template lib_namespace[][^callable_traits]]
20[template namespace_scoped[][^boost::callable_traits::]]
21[template header_include_prefix[]callable_traits/]
22[template invoke[][@http://en.cppreference.com/w/cpp/utility/functional/invoke [^['INVOKE]]]]
23[template hana[][@https://boostorg.github.io/hana/ [^Boost.Hana]]]
24[template feedback[][link callable_traits.contact feedback]]
25[template unsure[][link callable_traits.contact ?]]
26[template link_contact_the_author[][link callable_traits.contact contact me]]
27[template repo[][@https://github.com/boostorg/callable_traits GitHub]]
28[template abominable_paper[][@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html "abominable" function types]]
29[template link_compatibility[][link callable_traits.compatibility Compatibility]]
30[template link_compatibility_issues[][link callable_traits.compatibility.compatibility_issues Compatibility Issues]]
31[template function_types_link[][@http://www.boost.org/doc/libs/1_61_0/libs/function_types/doc/html/index.html [^Boost.FunctionTypes]]]
32[template function_types[][^Boost.FunctionTypes]]
33
34[section:introduction Overview]
35
36[libname] is a C++11 header-only library for the inspection, synthesis, and decomposition of callable types. [libname] aims to be the "complete type manipulation facility for function types" mentioned in the final paragraph of C++17 proposal [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0172r0.html p0172], and removes the need for template specializations for different function signatures. C++17 `noexcept` and the Transactional Memory TS are also supported if available.
37[import ../example/intro.cpp]
38[intro]
39
40[section:motivation Motivation]
41
42[:[*['["Don't try to write helper code to detect PMFs/PMDs and dispatch on them -- it is an [_absolute nightmare]. PMF types are the worst types by far in the core language.]]]
43
44-- Stephan T. Lavavej, CppCon 2015, [@https://www.youtube.com/watch?v=zt7ThwVfap0&t=11m40s "functional: What's New, And Proper Usage"]
45]
46
47Consider for a moment the code below, which defines all 48 template specializations necessary to specialize for every valid function type in pure C++17:
48
49[import ./hideous_template.snippet.cpp]
50[hideous_template]
51
52Things get even more complicated with member function pointers, function pointers, function references, function objects, and `transaction_safe`.
53
54Granted, use cases for such obscure specializations are vitually nonexistent in run-of-the-mill application codebases. Even in library code, these are exceedingly rare. However, there are a handful of metaprogramming scenarios that can only be solved with this kind of template "spam". Writing, testing, and maintaining such code is tedious and costly.
55
56[libname] offers a final and decisive library-level solution to this problem, and removes the need for these specializations entirely (platform-specific calling conventions notwithstanding).
57
58[endsect][/section:motivation]
59
60[section:boost_function_types Regarding [^Boost.FunctionTypes]]
61
62The features in [libname] largely overlap with [function_types_link]. Here are some reasons why you might prefer [libname]:
63
64# [function_types] is tightly coupled to [@http://www.boost.org/doc/libs/1_64_0/libs/mpl/doc/index.html [^Boost.MPL]] sequences, while [libname] has no dependencies other than the standard library.
65# [libname] targets C++11 and later:
66  # [libname] treats function objects/lambdas as first-class citizens.
67  # [libname] supports lvalue/rvalue reference member qualifiers.
68  # [libname] supports `noexcept` and `transaction_safe`.
69# [function_types] does not attempt to factor all callable types into a unified, [invoke]-aware interface.
70# [function_types] relies heavily on "tag" types, while [libname] follows the style of <type_traits> instead. Supporting C++11 and later in [function_types] would have required significant proliferation of these tags.
71
72For example, here is how to remove member `const` from a member function pointer type in the [function_types] library:
73
74    #include <type_traits>
75    #include <boost/function_types/components.hpp>
76    #include <boost/function_types/member_function_pointer.hpp>
77
78    struct foo {
79        void bar() const {}
80    };
81
82    using const_removed = typename boost::function_types::member_function_pointer<
83        typename boost::function_types::components<decltype(&foo::bar)>::types,
84        boost::function_types::non_const>::type;
85
86    static_assert(std::is_same<const_removed, void(foo::*)()>::value, "");
87
88    int main(){}
89
90[libname] makes this easier:
91
92[import ../example/function_types_remove_const_comparison.cpp]
93[function_types_remove_const_comparison]
94
95The [function_types] library includes an excellent [@http://www.boost.org/doc/libs/1_64_0/libs/function_types/example/interface_example.cpp example] for generating type-erased interfaces (implementation [@http://www.boost.org/doc/libs/1_64_0/libs/function_types/example/interface.hpp here]). This example was [@https://github.com/badair/eraserface/blob/master/include/eraserface/eraserface.hpp re-implemented] using [libname] to yield a [@https://github.com/badair/eraserface/blob/master/example/basic_example.cpp slightly more intuitive interface].
96
97[function_types] is a fine library, but its interface left room for improvement.
98
99[endsect][/section:boost_function_types]
100
101[section:compatibility Compatibility]
102
103[template link_travis_ci[][@https://travis-ci.org/boostorg/callable_traits/builds Travis]]
104[template link_appveyor_ci[][@https://ci.appveyor.com/project/boostorg/callable-traits Appveyor]]
105
106[libname] supports on GCC 4.7.4+, Clang 3.5.2+, XCode 6.4+, and Visual Studio 2015+. Continuous integration is managed on [link_appveyor_ci] for Visual Studio, and on [link_travis_ci] for everything else. The Intel C++ Compiler is not officially supported yet, although the 2017 version for Linux does pass a handful of test cases.
107
108[template yes[][role green \u2713]]
109[template c11[][role green c++11]]
110[template c14[][role green c++14]]
111[template c17[][role green c++17]]
112[template gnutm[][role gold c++17] (requires -fgnu-tm)]
113[template noabom[][role gold c++11] (no abominables)]
114[template no[][role red static_assert fails on instantiation]]
115[template falsy[][role gold c++11] (always false)]
116[template noop[][role gold c++11] (no effect)]
117[template unk[]unknown]
118
119[table GCC Support
120    [[feature]                                                                                         [GCC 8.2.0] [GCC 7.3.0] [GCC 6.3.0] [GCC 5.4.0] [GCC 4.9.2] [GCC 4.8.2] [GCC 4.7.4]]
121    [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]]                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
122    [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]]                             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
123    [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[no]] [[no]] ]
124    [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[no]] [[no]] ]
125    [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
126    [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]]                               [[c17]] [[c17]] [[c17]] [[no]] [[no]] [[no]] [[no]] ]
127    [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]]               [[gnutm]] [[gnutm]] [[gnutm]] [[no]] [[no]] [[no]] [[no]] ]
128    [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
129    [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]]               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
130    [[[link callable_traits.reference.ref_apply_return [^apply_return]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
131    [[[link callable_traits.reference.ref_args [^args]]]                                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
132    [[[link callable_traits.reference.ref_class_of [^class_of]]]                                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
133    [[[link callable_traits.reference.ref_function_type [^function_type]]]                             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
134    [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]]             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
135    [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
136    [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]]                         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
137    [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]]                         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
138    [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
139    [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[unk]] [[unk]] ]
140    [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]]   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ]
141    [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]]                                 [[c17]] [[c17]] [[c17]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
142    [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ]
143    [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]]   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ]
144    [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]]                 [[gnutm]] [[gnutm]] [[gnutm]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
145    [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]]                   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
146    [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]]                   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
147    [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
148    [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]]                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
149    [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]]         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noop]] [[noop]] ]
150    [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]]           [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ]
151    [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]]                         [[c17]] [[c17]] [[c17]] [[noop]] [[noop]] [[noop]] [[noop]] ]
152    [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]]         [[gnutm]] [[gnutm]] [[gnutm]] [[noop]] [[noop]] [[noop]] [[noop]] ]
153    [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]]                           [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
154    [[[link callable_traits.reference.ref_return_type [^return_type]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
155]
156
157[table LLVM/Clang Support
158    [[feature] [Clang 7.0.1] [Clang 6.0.0] [Clang 5.0.1] [Clang 4.0.0] [Clang 3.8.0] [Clang 3.7.1] [Clang 3.6.2] [Clang 3.5.2]]
159    [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]]                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
160    [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]]                             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
161    [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
162    [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
163    [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
164    [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]]                               [[c11]] [[c17]] [[c17]] [[c17]] [[no]] [[no]] [[no]] [[no]] ]
165    [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]]               [[unk]] [[unk]] [[unk]] [[unk]] [[no]] [[no]] [[no]] [[no]] ]
166    [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
167    [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]]               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
168    [[[link callable_traits.reference.ref_apply_return [^apply_return]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
169    [[[link callable_traits.reference.ref_args [^args]]]                                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
170    [[[link callable_traits.reference.ref_class_of [^class_of]]]                                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
171    [[[link callable_traits.reference.ref_function_type [^function_type]]]                             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
172    [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]]             [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
173    [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
174    [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]]                         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
175    [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]]                         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
176    [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
177    [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]]                               [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
178    [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]]   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
179    [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]]                                 [[c17]] [[c17]] [[c17]] [[c17]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
180    [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
181    [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]]   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
182    [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]]                 [[unk]] [[unk]] [[unk]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
183    [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]]                   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
184    [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]]                   [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
185    [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]]                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
186    [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]]                       [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
187    [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]]         [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
188    [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]]           [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
189    [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]]                         [[c17]] [[c17]] [[c17]] [[c17]] [[noop]] [[noop]] [[noop]] [[noop]] ]
190    [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]]         [[unk]] [[unk]] [[unk]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ]
191    [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]]                           [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
192    [[[link callable_traits.reference.ref_return_type [^return_type]]]                                 [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
193]
194
195[table XCode/AppleClang Support
196    [[feature] [XCode 8] [XCode 7.3] [XCode 7.2] [XCode 7.1] [XCode 6.4]]
197    [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
198    [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
199    [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
200    [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
201    [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
202    [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[unk]] [[no]] [[no]] [[no]] [[no]] ]
203    [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[unk]] [[no]] [[no]] [[no]] [[no]] ]
204    [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
205    [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
206    [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
207    [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
208    [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
209    [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
210    [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
211    [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
212    [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
213    [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
214    [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
215    [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
216    [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
217    [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
218    [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
219    [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
220    [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ]
221    [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
222    [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
223    [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
224    [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
225    [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
226    [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
227    [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ]
228    [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ]
229    [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
230    [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ]
231]
232
233[table Visual Studio Support
234    [[feature] [MSVC with Visual Studio 2017] [MSVC with Visual Studio 2015 (latest update)]]
235    [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] ]
236    [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] ]
237    [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] ]
238    [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] ]
239    [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] ]
240    [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[no]] [[no]] ]
241    [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[no]] [[no]] ]
242    [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ]
243    [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] ]
244    [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] ]
245    [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] ]
246    [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] ]
247    [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] ]
248    [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] ]
249    [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ]
250    [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] ]
251    [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] ]
252    [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] ]
253    [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[role gold c++11] (always false for functions that are simultaneously ref and cv-qualified due to compiler bug)] ]
254    [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] ]
255    [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[falsy]] [[falsy]] ]
256    [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] ]
257    [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] ]
258    [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[falsy]] [[falsy]] ]
259    [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] ]
260    [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]]  [[c11]][[c11]] ]
261    [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]]  [[c11]] [[c11]] ]
262    [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]]  [[c11]] [[c11]] ]
263    [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]]  [[c11]] [[c11]] ]
264    [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] ]
265    [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[noop]] [[noop]] ]
266    [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[noop]] [[noop]] ]
267    [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ]
268    [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] ]
269]
270
271[endsect][/section:compatibility]
272
273[endsect][/section:introduction]
274
275
276[section:reference Reference Documentation]
277
278This reference will be most beneficial to readers familiar with the following C++ topics:
279
280* [@http://en.cppreference.com/w/cpp/language/partial_specialization template specializations]
281* [@http://en.cppreference.com/w/cpp/language/sfinae SFINAE]
282* [invoke] rules
283* function types
284* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions function pointers]
285* [@http://stackoverflow.com/questions/480248/function-references function references]
286* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_member_functions pointers to member functions] (a.k.a. PMFs)
287* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_data_members pointers to data members] (a.k.a. PMDs)
288* [@http://en.cppreference.com/w/cpp/language/operators#Function_call_operator the function call operator, [^operator()]]
289* [@https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers universal references] and [@http://stackoverflow.com/questions/13725747/concise-explanation-of-reference-collapsing-rules-requested-1-a-a-2 reference collapsing rules]
290* [@http://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions cv-qualified and ref-qualified member functions]
291* [abominable_paper]
292* [@http://en.cppreference.com/w/c/language/variadic C-style variadics], a.k.a. varargs
293
294[import ../../../boost/callable_traits/add_member_const.hpp]
295[add_member_const_hpp]
296
297[import ../../../boost/callable_traits/add_member_cv.hpp]
298[add_member_cv_hpp]
299
300[import ../../../boost/callable_traits/add_member_lvalue_reference.hpp]
301[add_member_lvalue_reference_hpp]
302
303[import ../../../boost/callable_traits/add_member_rvalue_reference.hpp]
304[add_member_rvalue_reference_hpp]
305
306[import ../../../boost/callable_traits/add_member_volatile.hpp]
307[add_member_volatile_hpp]
308
309[import ../../../boost/callable_traits/add_noexcept.hpp]
310[add_noexcept_hpp]
311
312[import ../../../boost/callable_traits/add_transaction_safe.hpp]
313[add_transaction_safe_hpp]
314
315[import ../../../boost/callable_traits/add_varargs.hpp]
316[add_varargs_hpp]
317
318[import ../../../boost/callable_traits/apply_member_pointer.hpp]
319[apply_member_pointer_hpp]
320
321[import ../../../boost/callable_traits/apply_return.hpp]
322[apply_return_hpp]
323
324[import ../../../boost/callable_traits/args.hpp]
325[args_hpp]
326
327[import ../../../boost/callable_traits/class_of.hpp]
328[class_of_hpp]
329
330[import ../../../boost/callable_traits/function_type.hpp]
331[function_type_hpp]
332
333[import ../../../boost/callable_traits/has_member_qualifiers.hpp]
334[has_member_qualifiers_hpp]
335
336[import ../../../boost/callable_traits/has_varargs.hpp]
337[has_varargs_hpp]
338
339[import ../../../boost/callable_traits/has_void_return.hpp]
340[has_void_return_hpp]
341
342[import ../../../boost/callable_traits/is_const_member.hpp]
343[is_const_member_hpp]
344
345[import ../../../boost/callable_traits/is_cv_member.hpp]
346[is_cv_member_hpp]
347
348[import ../../../boost/callable_traits/is_invocable.hpp]
349[is_invocable_hpp]
350
351[import ../../../boost/callable_traits/is_lvalue_reference_member.hpp]
352[is_lvalue_reference_member_hpp]
353
354[import ../../../boost/callable_traits/is_reference_member.hpp]
355[is_reference_member_hpp]
356
357[import ../../../boost/callable_traits/is_rvalue_reference_member.hpp]
358[is_rvalue_reference_member_hpp]
359
360[import ../../../boost/callable_traits/is_noexcept.hpp]
361[is_noexcept_hpp]
362
363[import ../../../boost/callable_traits/is_transaction_safe.hpp]
364[is_transaction_safe_hpp]
365
366[import ../../../boost/callable_traits/is_volatile_member.hpp]
367[is_volatile_member_hpp]
368
369[import ../../../boost/callable_traits/qualified_class_of.hpp]
370[qualified_class_of_hpp]
371
372[import ../../../boost/callable_traits/remove_member_const.hpp]
373[remove_member_const_hpp]
374
375[import ../../../boost/callable_traits/remove_member_cv.hpp]
376[remove_member_cv_hpp]
377
378[import ../../../boost/callable_traits/remove_member_reference.hpp]
379[remove_member_reference_hpp]
380
381[import ../../../boost/callable_traits/remove_member_volatile.hpp]
382[remove_member_volatile_hpp]
383
384[import ../../../boost/callable_traits/remove_noexcept.hpp]
385[remove_noexcept_hpp]
386
387[import ../../../boost/callable_traits/remove_transaction_safe.hpp]
388[remove_transaction_safe_hpp]
389
390[import ../../../boost/callable_traits/remove_varargs.hpp]
391[remove_varargs_hpp]
392
393[import ../../../boost/callable_traits/return_type.hpp]
394[return_type_hpp]
395
396[endsect][/section:reference]
397
398[/*********************************************************************]
399[/***************************** F A Q *********************************]
400[/*********************************************************************]
401
402[section:faq FAQ]
403
404[heading:reasons Why should I use [libname]?]
405
406If you are not writing generic code, you should not use [libname].
407
408If you ['are] writing generic code, take a moment to skim your header files, and see if you can find code that looks like this:
409
410    template<class Return, class First, class Second>
411    class foo<Return(First, Second)> {
412        //    ^^^^^^^^^^^^^^^^^^^^^
413    };
414
415Or maybe something like this:
416
417    template<class Return, class ...Args>
418    class foo<Return(*)(Args...)> {
419        //    ^^^^^^^^^^^^^^^^^^
420    };
421
422Or, if you are *really* unlucky, something like this:
423
424    template<class Return, class T, class ...Args>
425    class foo<Return(T::*)(Args..., ...) const volatile & noexcept> {
426        //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
427    };
428
429With [libname], you can get rid of all of these template specializations (unless you deal with platform-specific calling conventions, for now). Even if you are only specializing a simple function type like `Return(Args...)`, [libname] might be useful to you. You may find that [libname] can help make your code more readable, more maintainable, more generic, and less error-prone.
430
431[libname] is well-tested on many platforms. [libname] correctly handles many corner cases that are often overlooked. The need for a proper library solution grows as more features are added to C++.
432
433[heading Boost is a massive dependency. Do I really need it?]
434
435Nope! [libname] doesn't have any dependencies, so all you need are the [libname] headers.
436
437[heading Why use reference collapsing rules when adding member function ref-qualifiers?]
438
439Although arbitrary, the reference collapsing rules are well-defined and already known to many template metaprogrammers. Anything else would be a burden to memorize. This also parallels the metafunctions provided in `<type_traits>`.
440
441[heading Many features in this library cause a "substitution failure" when the template constraints are violated. Does this mean that I can violate the constraints in a SFINAE context, as long as there is another legal substitute?]
442
443Yes. The SFINAE-ability of violated constraints has been tested extensively on supported compilers. Achieving this required some messy code in the public header files.
444
445[heading What about calling conventions?]
446
447I originally implemented features for these. However, these features necessitated many, many more platform-specific test cases. The code is still designed to accommodate such features, so I would consider adding them in the future if there is sufficient interest.
448
449[endsect]
450
451[section:building Building the test suite]
452
453This section contains the instructions for building and running the test cases and documentatation examples that are packaged with [libname].
454
455[note Some test cases that use language features that do not work on some supported compilers. These conflicts are "resolved" by replacing `int main(){}` with the actual test via conditional compilation.]
456
457[heading Dependencies]
458
459Even though the [libname] headers do not rely on external dependencies, you'll need to install [@https://cmake.org/ CMake] version 3.5 or higher to run the full test suite. The build instructions assume that both CMake and Git are available from your environment PATH. Boost.Build is also supported.
460
461[heading Linux/OSX - clone and run test suite]
462
463Open a shell and enter the following commands:
464
465```
466git clone http://github.com/boostorg/callable_traits
467cd callable_traits
468mkdir build
469cd build
470cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler
471make check
472```
473
474[heading Windows - clone and run test suite]
475
476[note Cygwin and MSYS users should refer to the Linux section (you know who you are).]
477
478Fire up `cmd.exe` and enter the following commands:
479
480```
481git clone http://github.com/boostorg/callable_traits
482cd callable_traits
483mkdir build
484cd build
485cmake ..
486path\to\msbuild.exe check.vcxproj /t:build /p:Configuration=Debug /p:Platform=Win32 /v:n /nologo
487```
488
489To build with Clang/C2 instead of MSVC, append `-TLLVM-vs2014` (or similar supported flag) to the CMake arguments. This will only work if you have Clang/C2 installed.
490
491[endsect][/section:building]
492
493
494[/*********************************************************************]
495[/************************* C O N T A C T *****************************]
496[/*********************************************************************]
497
498[section:contact Contact]
499
500[libname] is authored and maintained by Barrett Adair.
501
502Comments, feedback, bug reports, and questions are appreciated, which can be submitted in the following ways:
503
504* Open a new issue [@https://github.com/boostorg/callable_traits/issues/new] on GitHub
505* Send an email to barrettellisadair
506* ...at gmail.com
507
508[endsect][/section:contact]
509
510[section:acknowledgements Acknowledgements]
511
512Credit to Tobias Schwinger for authoring the influential [function_types_link].
513
514Thanks to the following people for their reviews and feedback:
515
516* Bruno Dutra
517* Edward Diener
518* Emil Dotchevski
519* Gavin Lambert
520* Jason Rice
521* John Fletcher
522* Klemens Morgenstern
523* Niall Douglas
524* Paul Fultz II
525* Peter Dimov
526* Tim Song
527* Zach Laine
528
529Special thanks to...
530
531* Louis Dionne, for the significant time and effort spent as the Boost review manager, and for introducing me to the exciting world of Boost development.
532* The Harding University Computer Science Department, for the all of the challenging instruction, inspiration, and mentorship (especially to Dr. Dana Steil, for teaching me the joy of C++)
533* My family, for the support and encouragement during the development of this library, and for so much more.
534
535[endsect][/section:acknowledgements]