剖析std::function接口與實作
本文深度剖析了std::function的接口與實作,并簡要介紹了相關的程式設計技巧。
<functional> 系列
目錄
前言
一、std::function的原理與接口
1.1 std::function是函數包裝器
1.2 C++注重運作時效率
1.3 用函數指針實作多态
1.4 std::function的接口
二、std::function的實作
2.1 類型系統
2.1.1 異常類
2.1.2 資料存儲
2.1.3 輔助類
2.1.4 記憶體管理基類
2.1.5 仿函數調用
2.1.6 接口定義
2.1.7 類型關系
2.2 方法的功能與實作
2.2.1 多态性的展現
2.2.2 本地函數對象
2.2.3 heap函數對象
2.2.4 兩種存儲結構如何統一
2.2.5 根據形式區分仿函數類型
2.2.6 實作組裝成接口
後記
附錄
前言
為什麼要剖析 std::function 呢?因為筆者最近在做一個 std::function 向單片機系統的移植與擴充。
後續還會有 std::bind 等标準庫其他部分的移植。
一、std::function的原理與接口
1.1 std::function是函數包裝器
std::function ,能存儲任何符合模闆參數的函數對象。換句話說,這些擁有一緻參數類型、相同傳回值類型(其實不必完全相同)的函數對象,可以由 std::function 統一包裝起來。函數對象的大小是任意的、不能确定的,而C++中的類型都是固定大小的,那麼,如何在一個固定大小的類型中存儲任意大小的對象呢?
實際上問題還不止存儲那麼簡單。存儲了函數對象,必定是要在某一時刻調用;函數對象不是在建立的時候調用,這個特性成為延遲調用;函數對象也是對象,需要處理好構造、拷貝、移動、析構等問題——這些也需要延遲調用,但總不能再用 std::function 來解決吧?
既然 std::function 能存儲不同類型的函數對象,可以說它具有多态性。C++中展現多态性的主要是虛函數,繼承與多态這一套***是可以解決這個問題的。相關資料[1] [2]中的實作利用了繼承與多态,相當簡潔。
1.2 C++注重運作時效率
利用繼承與多态,我們可以讓編譯器幫我們搞定函數對象的析構。就這種實作而言,這是簡潔而有效的方法。然而這種實作需要動态記憶體,在一些情況下不劃算,甚至完全沒有必要。C++11引入了lambda表達式,其本質也是函數對象。這個對象有多大呢?取決于捕獲清單。你寫lambda會捕獲多少東西?很多情況下就隻是一對方括号而已吧。在這種情況下,lambda表達式的對象大小隻有1位元組(因為不能是0位元組),你卻為了這沒有内容的1位元組要調用動态記憶體的函數?C++注重運作時效率,這種浪費是不能接受的。
如何避免這種浪費呢?你也許會說我檢查傳入的對象是不是1位元組的空類型。且不論這個trait怎麼實作,函數指針、捕獲一個int的lambda等類型都聲稱自己是trivial的小對象,也不應該配置設定到heap中去。
之前說過,std::function 的大小是固定的,但是這個大小是可以自己定的。我們可以在 std::function 的類定義中加入一個空白的、大小适中的field,用在存放這些小對象,進而避免這些情況下的動态記憶體操作。同時,既然有了這片空間,也就不需要看傳入的對象是不是1位元組的空類型了。
而對于更大的類型,雖然這個field不足以存放函數對象,但足以存放一個指針,這種分時複用的結構可以用union來實作。這種小對象直接存儲、大對象在heap上開辟空間并存儲指針的方法,稱為small object optimization。
在利用繼承的實作中,函數對象被包裝在一個子類中,std::function 中持有一個其父類的指針。然而為了效率,我們需要把空白field和這個指針union起來。union總給人一種底層的感覺,在不确定這個union到底存儲的是什麼的時候,當然不能通過其中的指針去調用虛函數。在這樣的設計中,多态性不再能用繼承體系實作了,我們需要另一種實作多态的方法。
1.3 用函數指針實作多态
回想一下虛函數是如何實作的?帶有virtual function的類的對象中會安插vptr,這個指針指向一個vtable,這個vtable含有多個slot,裡面含有指向type_info對象的指針與函數指針——對,我們需要函數指針!不知你有沒有在C中實作過多态,在沒有語言特性的幫助下,比較友善的方法是在struct中直接放函數指針。如果要像C++那樣用上vptr和vtable,你得管理好每個類及其對應vtable的内容。你以為這種情況在C++中就有所好轉嗎?隻有你用C++的繼承體系,編譯器才會幫你做這些事。想要自己建立一個從類型到vptr的映射,恐怕你得改編譯器了。(更正:C++14引入了變量模闆,請移步C++值多态:傳統多态與類型擦除之間。)
vptr與vtable的意義是什麼?其一,每個基類隻對應一個vptr,大小固定,多重繼承下便于管理,但這點與這篇文章的主題沒有關聯;其二,當基類有多個虛函數的時候,使用vptr可以節省存儲對象的空間,而如果用函數指針的話,雖然少了一次尋址,但繼承帶來的空間overhead取決于虛函數的數量,由于至少一個,函數指針的占用的空間不會少于vptr,在虛函數數量較多的情況下,函數指針就要占用比較大的空間了。
既然我們已經無法在 std::function 中使用vptr,我們也應該盡可能減少函數指針的數量,而這又取決于這些函數的功能,進一步取決于 std::function 類的接口。
1.4 std::function的接口
雖然C++标準規定了 std::function 的接口就應該是這樣,我還是想說說它為什麼應該是這樣。關于其他的一些問題,比如儲存值還是儲存引用等,可以參考相關資料[4]。
最基本的,std::function 是一個模闆類,模闆參數是一個類型(注意是一個類型,不是好幾個類型)。我們可以這麼寫:
std::function<int(double)> f;
f 是一個可調用對象,參數為 double,傳回值為 int 。你也許會問,這裡既規定了參數類型又規定了傳回值類型,怎麼就成了一個類型呢?确實是一個類型,int(double) 是一個函數類型(注意不是函數指針)。
std::function 要包裝所有合适類型的對象,就必須有對應的構造函數,是以這是個模闆構造函數。參數不是通用引用而是直接傳值:
template <typename F>
function(F);
可能是為了讓編譯器對空對象進行優化。同樣還有一個模闆指派函數,參數是通用引用。
每個構造函數都有一個添加了 std::allocator_arg_t 作為第一個參數、記憶體配置設定器對象作為第二個參數的版本,C++17中已經移除(GCC從未提供,可能是因為 std::function 的記憶體配置設定無法自定義)。同樣删除的還有 assign ,也是與記憶體配置設定器相關的。
另外有一個以 std::reference_wrapper 作為參數的指派函數:
template <typename F>
function& operator=(std::reference_wrapper<F>) noexcept;
可以了解為模闆指派函數的特化。沒有相應的構造函數。
預設構造函數、nullptr_t 構造函數、nullptr_t 拷貝指派函數都将 std::function 對象置空。當 std::function 對象沒有儲存任何函數對象時, operator bool() 傳回 false ,與 nullptr_t 調用 operator== 會傳回 true ,如果調用将抛出 std::bad_function_call 異常。
雖然 std::function 将函數對象包裝了起來,但使用者還是可以獲得原始對象的。target_type() 傳回函數對象的 typeid ,target() 模闆函數當模闆參數與函數對象類型相同時傳回其指針,否則傳回空指針。
作為函數包裝器,std::function 也是函數對象,可以通過 operator() 調用,參數按照模闆參數中聲明的類型傳遞。
還有一些接口與大部分STL設施相似,有Rule of Five規定的5個方法、 swap() ,以及 std::swap() 的特化等。可别小看這個 swap() ,它有大用處。
總之,函數對象的複制、移動、指派、交換等操作都是需要的。對客戶來說,除了兩個 std::function 的相等性判定(筆者最近在嘗試實作這個)以外,其他能想到的方法它都有。
二、std::function的實作
std::function 的實作位于 <functional> ,後續版本遷移至了 <bits/std_function.h> 。下面這段代碼是GCC 4.8.1(第一個支援完整C++11的版本)中的 <functional> 頭檔案,共2579行,預設折疊,慎入。

1 // <functional> -*- C++ -*-
2
3 // Copyright (C) 2001-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /*
26 * Copyright (c) 1997
27 * Silicon Graphics Computer Systems, Inc.
28 *
29 * Permission to use, copy, modify, distribute and sell this software
30 * and its documentation for any purpose is hereby granted without fee,
31 * provided that the above copyright notice appear in all copies and
32 * that both that copyright notice and this permission notice appear
33 * in supporting documentation. Silicon Graphics makes no
34 * representations about the suitability of this software for any
35 * purpose. It is provided "as is" without express or implied warranty.
36 *
37 */
38
39 /** @file include/functional
40 * This is a Standard C++ Library header.
41 */
42
43 #ifndef _GLIBCXX_FUNCTIONAL
44 #define _GLIBCXX_FUNCTIONAL 1
45
46 #pragma GCC system_header
47
48 #include <bits/c++config.h>
49 #include <bits/stl_function.h>
50
51 #if __cplusplus >= 201103L
52
53 #include <typeinfo>
54 #include <new>
55 #include <tuple>
56 #include <type_traits>
57 #include <bits/functexcept.h>
58 #include <bits/functional_hash.h>
59
60 namespace std _GLIBCXX_VISIBILITY(default)
61 {
62 _GLIBCXX_BEGIN_NAMESPACE_VERSION
63
64 template<typename _MemberPointer>
65 class _Mem_fn;
66 template<typename _Tp, typename _Class>
67 _Mem_fn<_Tp _Class::*>
68 mem_fn(_Tp _Class::*) noexcept;
69
70 _GLIBCXX_HAS_NESTED_TYPE(result_type)
71
72 /// If we have found a result_type, extract it.
73 template<bool _Has_result_type, typename _Functor>
74 struct _Maybe_get_result_type
75 { };
76
77 template<typename _Functor>
78 struct _Maybe_get_result_type<true, _Functor>
79 { typedef typename _Functor::result_type result_type; };
80
81 /**
82 * Base class for any function object that has a weak result type, as
83 * defined in 3.3/3 of TR1.
84 */
85 template<typename _Functor>
86 struct _Weak_result_type_impl
87 : _Maybe_get_result_type<__has_result_type<_Functor>::value, _Functor>
88 { };
89
90 /// Retrieve the result type for a function type.
91 template<typename _Res, typename... _ArgTypes>
92 struct _Weak_result_type_impl<_Res(_ArgTypes...)>
93 { typedef _Res result_type; };
94
95 template<typename _Res, typename... _ArgTypes>
96 struct _Weak_result_type_impl<_Res(_ArgTypes......)>
97 { typedef _Res result_type; };
98
99 template<typename _Res, typename... _ArgTypes>
100 struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
101 { typedef _Res result_type; };
102
103 template<typename _Res, typename... _ArgTypes>
104 struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
105 { typedef _Res result_type; };
106
107 template<typename _Res, typename... _ArgTypes>
108 struct _Weak_result_type_impl<_Res(_ArgTypes...) volatile>
109 { typedef _Res result_type; };
110
111 template<typename _Res, typename... _ArgTypes>
112 struct _Weak_result_type_impl<_Res(_ArgTypes......) volatile>
113 { typedef _Res result_type; };
114
115 template<typename _Res, typename... _ArgTypes>
116 struct _Weak_result_type_impl<_Res(_ArgTypes...) const volatile>
117 { typedef _Res result_type; };
118
119 template<typename _Res, typename... _ArgTypes>
120 struct _Weak_result_type_impl<_Res(_ArgTypes......) const volatile>
121 { typedef _Res result_type; };
122
123 /// Retrieve the result type for a function reference.
124 template<typename _Res, typename... _ArgTypes>
125 struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
126 { typedef _Res result_type; };
127
128 template<typename _Res, typename... _ArgTypes>
129 struct _Weak_result_type_impl<_Res(&)(_ArgTypes......)>
130 { typedef _Res result_type; };
131
132 /// Retrieve the result type for a function pointer.
133 template<typename _Res, typename... _ArgTypes>
134 struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
135 { typedef _Res result_type; };
136
137 template<typename _Res, typename... _ArgTypes>
138 struct _Weak_result_type_impl<_Res(*)(_ArgTypes......)>
139 { typedef _Res result_type; };
140
141 /// Retrieve result type for a member function pointer.
142 template<typename _Res, typename _Class, typename... _ArgTypes>
143 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
144 { typedef _Res result_type; };
145
146 template<typename _Res, typename _Class, typename... _ArgTypes>
147 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)>
148 { typedef _Res result_type; };
149
150 /// Retrieve result type for a const member function pointer.
151 template<typename _Res, typename _Class, typename... _ArgTypes>
152 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
153 { typedef _Res result_type; };
154
155 template<typename _Res, typename _Class, typename... _ArgTypes>
156 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const>
157 { typedef _Res result_type; };
158
159 /// Retrieve result type for a volatile member function pointer.
160 template<typename _Res, typename _Class, typename... _ArgTypes>
161 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
162 { typedef _Res result_type; };
163
164 template<typename _Res, typename _Class, typename... _ArgTypes>
165 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile>
166 { typedef _Res result_type; };
167
168 /// Retrieve result type for a const volatile member function pointer.
169 template<typename _Res, typename _Class, typename... _ArgTypes>
170 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)
171 const volatile>
172 { typedef _Res result_type; };
173
174 template<typename _Res, typename _Class, typename... _ArgTypes>
175 struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
176 const volatile>
177 { typedef _Res result_type; };
178
179 /**
180 * Strip top-level cv-qualifiers from the function object and let
181 * _Weak_result_type_impl perform the real work.
182 */
183 template<typename _Functor>
184 struct _Weak_result_type
185 : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
186 { };
187
188 /// Determines if the type _Tp derives from unary_function.
189 template<typename _Tp>
190 struct _Derives_from_unary_function : __sfinae_types
191 {
192 private:
193 template<typename _T1, typename _Res>
194 static __one __test(const volatile unary_function<_T1, _Res>*);
195
196 // It\'s tempting to change "..." to const volatile void*, but
197 // that fails when _Tp is a function type.
198 static __two __test(...);
199
200 public:
201 static const bool value = sizeof(__test((_Tp*)0)) == 1;
202 };
203
204 /// Determines if the type _Tp derives from binary_function.
205 template<typename _Tp>
206 struct _Derives_from_binary_function : __sfinae_types
207 {
208 private:
209 template<typename _T1, typename _T2, typename _Res>
210 static __one __test(const volatile binary_function<_T1, _T2, _Res>*);
211
212 // It\'s tempting to change "..." to const volatile void*, but
213 // that fails when _Tp is a function type.
214 static __two __test(...);
215
216 public:
217 static const bool value = sizeof(__test((_Tp*)0)) == 1;
218 };
219
220 /**
221 * Invoke a function object, which may be either a member pointer or a
222 * function object. The first parameter will tell which.
223 */
224 template<typename _Functor, typename... _Args>
225 inline
226 typename enable_if<
227 (!is_member_pointer<_Functor>::value
228 && !is_function<_Functor>::value
229 && !is_function<typename remove_pointer<_Functor>::type>::value),
230 typename result_of<_Functor&(_Args&&...)>::type
231 >::type
232 __invoke(_Functor& __f, _Args&&... __args)
233 {
234 return __f(std::forward<_Args>(__args)...);
235 }
236
237 template<typename _Functor, typename... _Args>
238 inline
239 typename enable_if<
240 (is_member_pointer<_Functor>::value
241 && !is_function<_Functor>::value
242 && !is_function<typename remove_pointer<_Functor>::type>::value),
243 typename result_of<_Functor(_Args&&...)>::type
244 >::type
245 __invoke(_Functor& __f, _Args&&... __args)
246 {
247 return std::mem_fn(__f)(std::forward<_Args>(__args)...);
248 }
249
250 // To pick up function references (that will become function pointers)
251 template<typename _Functor, typename... _Args>
252 inline
253 typename enable_if<
254 (is_pointer<_Functor>::value
255 && is_function<typename remove_pointer<_Functor>::type>::value),
256 typename result_of<_Functor(_Args&&...)>::type
257 >::type
258 __invoke(_Functor __f, _Args&&... __args)
259 {
260 return __f(std::forward<_Args>(__args)...);
261 }
262
263 /**
264 * Knowing which of unary_function and binary_function _Tp derives
265 * from, derives from the same and ensures that reference_wrapper
266 * will have a weak result type. See cases below.
267 */
268 template<bool _Unary, bool _Binary, typename _Tp>
269 struct _Reference_wrapper_base_impl;
270
271 // None of the nested argument types.
272 template<typename _Tp>
273 struct _Reference_wrapper_base_impl<false, false, _Tp>
274 : _Weak_result_type<_Tp>
275 { };
276
277 // Nested argument_type only.
278 template<typename _Tp>
279 struct _Reference_wrapper_base_impl<true, false, _Tp>
280 : _Weak_result_type<_Tp>
281 {
282 typedef typename _Tp::argument_type argument_type;
283 };
284
285 // Nested first_argument_type and second_argument_type only.
286 template<typename _Tp>
287 struct _Reference_wrapper_base_impl<false, true, _Tp>
288 : _Weak_result_type<_Tp>
289 {
290 typedef typename _Tp::first_argument_type first_argument_type;
291 typedef typename _Tp::second_argument_type second_argument_type;
292 };
293
294 // All the nested argument types.
295 template<typename _Tp>
296 struct _Reference_wrapper_base_impl<true, true, _Tp>
297 : _Weak_result_type<_Tp>
298 {
299 typedef typename _Tp::argument_type argument_type;
300 typedef typename _Tp::first_argument_type first_argument_type;
301 typedef typename _Tp::second_argument_type second_argument_type;
302 };
303
304 _GLIBCXX_HAS_NESTED_TYPE(argument_type)
305 _GLIBCXX_HAS_NESTED_TYPE(first_argument_type)
306 _GLIBCXX_HAS_NESTED_TYPE(second_argument_type)
307
308 /**
309 * Derives from unary_function or binary_function when it
310 * can. Specializations handle all of the easy cases. The primary
311 * template determines what to do with a class type, which may
312 * derive from both unary_function and binary_function.
313 */
314 template<typename _Tp>
315 struct _Reference_wrapper_base
316 : _Reference_wrapper_base_impl<
317 __has_argument_type<_Tp>::value,
318 __has_first_argument_type<_Tp>::value
319 && __has_second_argument_type<_Tp>::value,
320 _Tp>
321 { };
322
323 // - a function type (unary)
324 template<typename _Res, typename _T1>
325 struct _Reference_wrapper_base<_Res(_T1)>
326 : unary_function<_T1, _Res>
327 { };
328
329 template<typename _Res, typename _T1>
330 struct _Reference_wrapper_base<_Res(_T1) const>
331 : unary_function<_T1, _Res>
332 { };
333
334 template<typename _Res, typename _T1>
335 struct _Reference_wrapper_base<_Res(_T1) volatile>
336 : unary_function<_T1, _Res>
337 { };
338
339 template<typename _Res, typename _T1>
340 struct _Reference_wrapper_base<_Res(_T1) const volatile>
341 : unary_function<_T1, _Res>
342 { };
343
344 // - a function type (binary)
345 template<typename _Res, typename _T1, typename _T2>
346 struct _Reference_wrapper_base<_Res(_T1, _T2)>
347 : binary_function<_T1, _T2, _Res>
348 { };
349
350 template<typename _Res, typename _T1, typename _T2>
351 struct _Reference_wrapper_base<_Res(_T1, _T2) const>
352 : binary_function<_T1, _T2, _Res>
353 { };
354
355 template<typename _Res, typename _T1, typename _T2>
356 struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
357 : binary_function<_T1, _T2, _Res>
358 { };
359
360 template<typename _Res, typename _T1, typename _T2>
361 struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
362 : binary_function<_T1, _T2, _Res>
363 { };
364
365 // - a function pointer type (unary)
366 template<typename _Res, typename _T1>
367 struct _Reference_wrapper_base<_Res(*)(_T1)>
368 : unary_function<_T1, _Res>
369 { };
370
371 // - a function pointer type (binary)
372 template<typename _Res, typename _T1, typename _T2>
373 struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
374 : binary_function<_T1, _T2, _Res>
375 { };
376
377 // - a pointer to member function type (unary, no qualifiers)
378 template<typename _Res, typename _T1>
379 struct _Reference_wrapper_base<_Res (_T1::*)()>
380 : unary_function<_T1*, _Res>
381 { };
382
383 // - a pointer to member function type (binary, no qualifiers)
384 template<typename _Res, typename _T1, typename _T2>
385 struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
386 : binary_function<_T1*, _T2, _Res>
387 { };
388
389 // - a pointer to member function type (unary, const)
390 template<typename _Res, typename _T1>
391 struct _Reference_wrapper_base<_Res (_T1::*)() const>
392 : unary_function<const _T1*, _Res>
393 { };
394
395 // - a pointer to member function type (binary, const)
396 template<typename _Res, typename _T1, typename _T2>
397 struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
398 : binary_function<const _T1*, _T2, _Res>
399 { };
400
401 // - a pointer to member function type (unary, volatile)
402 template<typename _Res, typename _T1>
403 struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
404 : unary_function<volatile _T1*, _Res>
405 { };
406
407 // - a pointer to member function type (binary, volatile)
408 template<typename _Res, typename _T1, typename _T2>
409 struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
410 : binary_function<volatile _T1*, _T2, _Res>
411 { };
412
413 // - a pointer to member function type (unary, const volatile)
414 template<typename _Res, typename _T1>
415 struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
416 : unary_function<const volatile _T1*, _Res>
417 { };
418
419 // - a pointer to member function type (binary, const volatile)
420 template<typename _Res, typename _T1, typename _T2>
421 struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
422 : binary_function<const volatile _T1*, _T2, _Res>
423 { };
424
425 /**
426 * @brief Primary class template for reference_wrapper.
427 * @ingroup functors
428 * @{
429 */
430 template<typename _Tp>
431 class reference_wrapper
432 : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
433 {
434 _Tp* _M_data;
435
436 public:
437 typedef _Tp type;
438
439 reference_wrapper(_Tp& __indata) noexcept
440 : _M_data(std::__addressof(__indata))
441 { }
442
443 reference_wrapper(_Tp&&) = delete;
444
445 reference_wrapper(const reference_wrapper<_Tp>& __inref) noexcept
446 : _M_data(__inref._M_data)
447 { }
448
449 reference_wrapper&
450 operator=(const reference_wrapper<_Tp>& __inref) noexcept
451 {
452 _M_data = __inref._M_data;
453 return *this;
454 }
455
456 operator _Tp&() const noexcept
457 { return this->get(); }
458
459 _Tp&
460 get() const noexcept
461 { return *_M_data; }
462
463 template<typename... _Args>
464 typename result_of<_Tp&(_Args&&...)>::type
465 operator()(_Args&&... __args) const
466 {
467 return __invoke(get(), std::forward<_Args>(__args)...);
468 }
469 };
470
471
472 /// Denotes a reference should be taken to a variable.
473 template<typename _Tp>
474 inline reference_wrapper<_Tp>
475 ref(_Tp& __t) noexcept
476 { return reference_wrapper<_Tp>(__t); }
477
478 /// Denotes a const reference should be taken to a variable.
479 template<typename _Tp>
480 inline reference_wrapper<const _Tp>
481 cref(const _Tp& __t) noexcept
482 { return reference_wrapper<const _Tp>(__t); }
483
484 template<typename _Tp>
485 void ref(const _Tp&&) = delete;
486
487 template<typename _Tp>
488 void cref(const _Tp&&) = delete;
489
490 /// Partial specialization.
491 template<typename _Tp>
492 inline reference_wrapper<_Tp>
493 ref(reference_wrapper<_Tp> __t) noexcept
494 { return ref(__t.get()); }
495
496 /// Partial specialization.
497 template<typename _Tp>
498 inline reference_wrapper<const _Tp>
499 cref(reference_wrapper<_Tp> __t) noexcept
500 { return cref(__t.get()); }
501
502 // @} group functors
503
504 template<typename... _Types>
505 struct _Pack : integral_constant<size_t, sizeof...(_Types)>
506 { };
507
508 template<typename _From, typename _To, bool = _From::value == _To::value>
509 struct _AllConvertible : false_type
510 { };
511
512 template<typename... _From, typename... _To>
513 struct _AllConvertible<_Pack<_From...>, _Pack<_To...>, true>
514 : __and_<is_convertible<_From, _To>...>
515 { };
516
517 template<typename _Tp1, typename _Tp2>
518 using _NotSame = __not_<is_same<typename std::decay<_Tp1>::type,
519 typename std::decay<_Tp2>::type>>;
520
521 /**
522 * Derives from @c unary_function or @c binary_function, or perhaps
523 * nothing, depending on the number of arguments provided. The
524 * primary template is the basis case, which derives nothing.
525 */
526 template<typename _Res, typename... _ArgTypes>
527 struct _Maybe_unary_or_binary_function { };
528
529 /// Derives from @c unary_function, as appropriate.
530 template<typename _Res, typename _T1>
531 struct _Maybe_unary_or_binary_function<_Res, _T1>
532 : std::unary_function<_T1, _Res> { };
533
534 /// Derives from @c binary_function, as appropriate.
535 template<typename _Res, typename _T1, typename _T2>
536 struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
537 : std::binary_function<_T1, _T2, _Res> { };
538
539 /// Implementation of @c mem_fn for member function pointers.
540 template<typename _Res, typename _Class, typename... _ArgTypes>
541 class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
542 : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
543 {
544 typedef _Res (_Class::*_Functor)(_ArgTypes...);
545
546 template<typename _Tp, typename... _Args>
547 _Res
548 _M_call(_Tp&& __object, const volatile _Class *,
549 _Args&&... __args) const
550 {
551 return (std::forward<_Tp>(__object).*__pmf)
552 (std::forward<_Args>(__args)...);
553 }
554
555 template<typename _Tp, typename... _Args>
556 _Res
557 _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
558 { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
559
560 // Require each _Args to be convertible to corresponding _ArgTypes
561 template<typename... _Args>
562 using _RequireValidArgs
563 = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
564
565 // Require each _Args to be convertible to corresponding _ArgTypes
566 // and require _Tp is not _Class, _Class& or _Class*
567 template<typename _Tp, typename... _Args>
568 using _RequireValidArgs2
569 = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
570 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
571
572 // Require each _Args to be convertible to corresponding _ArgTypes
573 // and require _Tp is _Class or derived from _Class
574 template<typename _Tp, typename... _Args>
575 using _RequireValidArgs3
576 = _Require<is_base_of<_Class, _Tp>,
577 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
578
579 public:
580 typedef _Res result_type;
581
582 explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
583
584 // Handle objects
585 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
586 _Res
587 operator()(_Class& __object, _Args&&... __args) const
588 { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
589
590 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
591 _Res
592 operator()(_Class&& __object, _Args&&... __args) const
593 {
594 return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
595 }
596
597 // Handle pointers
598 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
599 _Res
600 operator()(_Class* __object, _Args&&... __args) const
601 { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
602
603 // Handle smart pointers, references and pointers to derived
604 template<typename _Tp, typename... _Args,
605 typename _Req = _RequireValidArgs2<_Tp, _Args...>>
606 _Res
607 operator()(_Tp&& __object, _Args&&... __args) const
608 {
609 return _M_call(std::forward<_Tp>(__object), &__object,
610 std::forward<_Args>(__args)...);
611 }
612
613 template<typename _Tp, typename... _Args,
614 typename _Req = _RequireValidArgs3<_Tp, _Args...>>
615 _Res
616 operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
617 { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
618
619 private:
620 _Functor __pmf;
621 };
622
623 /// Implementation of @c mem_fn for const member function pointers.
624 template<typename _Res, typename _Class, typename... _ArgTypes>
625 class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
626 : public _Maybe_unary_or_binary_function<_Res, const _Class*,
627 _ArgTypes...>
628 {
629 typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
630
631 template<typename _Tp, typename... _Args>
632 _Res
633 _M_call(_Tp&& __object, const volatile _Class *,
634 _Args&&... __args) const
635 {
636 return (std::forward<_Tp>(__object).*__pmf)
637 (std::forward<_Args>(__args)...);
638 }
639
640 template<typename _Tp, typename... _Args>
641 _Res
642 _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
643 { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
644
645 template<typename... _Args>
646 using _RequireValidArgs
647 = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
648
649 template<typename _Tp, typename... _Args>
650 using _RequireValidArgs2
651 = _Require<_NotSame<_Class, _Tp>, _NotSame<const _Class*, _Tp>,
652 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
653
654 template<typename _Tp, typename... _Args>
655 using _RequireValidArgs3
656 = _Require<is_base_of<_Class, _Tp>,
657 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
658
659 public:
660 typedef _Res result_type;
661
662 explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
663
664 // Handle objects
665 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
666 _Res
667 operator()(const _Class& __object, _Args&&... __args) const
668 { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
669
670 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
671 _Res
672 operator()(const _Class&& __object, _Args&&... __args) const
673 {
674 return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
675 }
676
677 // Handle pointers
678 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
679 _Res
680 operator()(const _Class* __object, _Args&&... __args) const
681 { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
682
683 // Handle smart pointers, references and pointers to derived
684 template<typename _Tp, typename... _Args,
685 typename _Req = _RequireValidArgs2<_Tp, _Args...>>
686 _Res operator()(_Tp&& __object, _Args&&... __args) const
687 {
688 return _M_call(std::forward<_Tp>(__object), &__object,
689 std::forward<_Args>(__args)...);
690 }
691
692 template<typename _Tp, typename... _Args,
693 typename _Req = _RequireValidArgs3<_Tp, _Args...>>
694 _Res
695 operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
696 { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
697
698 private:
699 _Functor __pmf;
700 };
701
702 /// Implementation of @c mem_fn for volatile member function pointers.
703 template<typename _Res, typename _Class, typename... _ArgTypes>
704 class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
705 : public _Maybe_unary_or_binary_function<_Res, volatile _Class*,
706 _ArgTypes...>
707 {
708 typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
709
710 template<typename _Tp, typename... _Args>
711 _Res
712 _M_call(_Tp&& __object, const volatile _Class *,
713 _Args&&... __args) const
714 {
715 return (std::forward<_Tp>(__object).*__pmf)
716 (std::forward<_Args>(__args)...);
717 }
718
719 template<typename _Tp, typename... _Args>
720 _Res
721 _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
722 { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
723
724 template<typename... _Args>
725 using _RequireValidArgs
726 = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
727
728 template<typename _Tp, typename... _Args>
729 using _RequireValidArgs2
730 = _Require<_NotSame<_Class, _Tp>, _NotSame<volatile _Class*, _Tp>,
731 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
732
733 template<typename _Tp, typename... _Args>
734 using _RequireValidArgs3
735 = _Require<is_base_of<_Class, _Tp>,
736 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
737
738 public:
739 typedef _Res result_type;
740
741 explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
742
743 // Handle objects
744 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
745 _Res
746 operator()(volatile _Class& __object, _Args&&... __args) const
747 { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
748
749 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
750 _Res
751 operator()(volatile _Class&& __object, _Args&&... __args) const
752 {
753 return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
754 }
755
756 // Handle pointers
757 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
758 _Res
759 operator()(volatile _Class* __object, _Args&&... __args) const
760 { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
761
762 // Handle smart pointers, references and pointers to derived
763 template<typename _Tp, typename... _Args,
764 typename _Req = _RequireValidArgs2<_Tp, _Args...>>
765 _Res
766 operator()(_Tp&& __object, _Args&&... __args) const
767 {
768 return _M_call(std::forward<_Tp>(__object), &__object,
769 std::forward<_Args>(__args)...);
770 }
771
772 template<typename _Tp, typename... _Args,
773 typename _Req = _RequireValidArgs3<_Tp, _Args...>>
774 _Res
775 operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
776 { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
777
778 private:
779 _Functor __pmf;
780 };
781
782 /// Implementation of @c mem_fn for const volatile member function pointers.
783 template<typename _Res, typename _Class, typename... _ArgTypes>
784 class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
785 : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*,
786 _ArgTypes...>
787 {
788 typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
789
790 template<typename _Tp, typename... _Args>
791 _Res
792 _M_call(_Tp&& __object, const volatile _Class *,
793 _Args&&... __args) const
794 {
795 return (std::forward<_Tp>(__object).*__pmf)
796 (std::forward<_Args>(__args)...);
797 }
798
799 template<typename _Tp, typename... _Args>
800 _Res
801 _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
802 { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
803
804 template<typename... _Args>
805 using _RequireValidArgs
806 = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
807
808 template<typename _Tp, typename... _Args>
809 using _RequireValidArgs2
810 = _Require<_NotSame<_Class, _Tp>,
811 _NotSame<const volatile _Class*, _Tp>,
812 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
813
814 template<typename _Tp, typename... _Args>
815 using _RequireValidArgs3
816 = _Require<is_base_of<_Class, _Tp>,
817 _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
818
819 public:
820 typedef _Res result_type;
821
822 explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
823
824 // Handle objects
825 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
826 _Res
827 operator()(const volatile _Class& __object, _Args&&... __args) const
828 { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
829
830 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
831 _Res
832 operator()(const volatile _Class&& __object, _Args&&... __args) const
833 {
834 return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
835 }
836
837 // Handle pointers
838 template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
839 _Res
840 operator()(const volatile _Class* __object, _Args&&... __args) const
841 { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
842
843 // Handle smart pointers, references and pointers to derived
844 template<typename _Tp, typename... _Args,
845 typename _Req = _RequireValidArgs2<_Tp, _Args...>>
846 _Res operator()(_Tp&& __object, _Args&&... __args) const
847 {
848 return _M_call(std::forward<_Tp>(__object), &__object,
849 std::forward<_Args>(__args)...);
850 }
851
852 template<typename _Tp, typename... _Args,
853 typename _Req = _RequireValidArgs3<_Tp, _Args...>>
854 _Res
855 operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
856 { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
857
858 private:
859 _Functor __pmf;
860 };
861
862
863 template<typename _Tp, bool>
864 struct _Mem_fn_const_or_non
865 {
866 typedef const _Tp& type;
867 };
868
869 template<typename _Tp>
870 struct _Mem_fn_const_or_non<_Tp, false>
871 {
872 typedef _Tp& type;
873 };
874
875 template<typename _Res, typename _Class>
876 class _Mem_fn<_Res _Class::*>
877 {
878 using __pm_type = _Res _Class::*;
879
880 // This bit of genius is due to Peter Dimov, improved slightly by
881 // Douglas Gregor.
882 // Made less elegant to support perfect forwarding and noexcept.
883 template<typename _Tp>
884 auto
885 _M_call(_Tp&& __object, const _Class *) const noexcept
886 -> decltype(std::forward<_Tp>(__object).*std::declval<__pm_type&>())
887 { return std::forward<_Tp>(__object).*__pm; }
888
889 template<typename _Tp, typename _Up>
890 auto
891 _M_call(_Tp&& __object, _Up * const *) const noexcept
892 -> decltype((*std::forward<_Tp>(__object)).*std::declval<__pm_type&>())
893 { return (*std::forward<_Tp>(__object)).*__pm; }
894
895 template<typename _Tp>
896 auto
897 _M_call(_Tp&& __ptr, const volatile void*) const
898 noexcept(noexcept((*__ptr).*std::declval<__pm_type&>()))
899 -> decltype((*__ptr).*std::declval<__pm_type&>())
900 { return (*__ptr).*__pm; }
901
902 public:
903 explicit
904 _Mem_fn(_Res _Class::*__pm) noexcept : __pm(__pm) { }
905
906 // Handle objects
907 _Res&
908 operator()(_Class& __object) const noexcept
909 { return __object.*__pm; }
910
911 const _Res&
912 operator()(const _Class& __object) const noexcept
913 { return __object.*__pm; }
914
915 _Res&&
916 operator()(_Class&& __object) const noexcept
917 { return std::forward<_Class>(__object).*__pm; }
918
919 const _Res&&
920 operator()(const _Class&& __object) const noexcept
921 { return std::forward<const _Class>(__object).*__pm; }
922
923 // Handle pointers
924 _Res&
925 operator()(_Class* __object) const noexcept
926 { return __object->*__pm; }
927
928 const _Res&
929 operator()(const _Class* __object) const noexcept
930 { return __object->*__pm; }
931
932 // Handle smart pointers and derived
933 template<typename _Tp, typename _Req = _Require<_NotSame<_Class*, _Tp>>>
934 auto
935 operator()(_Tp&& __unknown) const
936 noexcept(noexcept(std::declval<_Mem_fn*>()->_M_call
937 (std::forward<_Tp>(__unknown), &__unknown)))
938 -> decltype(this->_M_call(std::forward<_Tp>(__unknown), &__unknown))
939 { return _M_call(std::forward<_Tp>(__unknown), &__unknown); }
940
941 template<typename _Tp, typename _Req = _Require<is_base_of<_Class, _Tp>>>
942 auto
943 operator()(reference_wrapper<_Tp> __ref) const
944 noexcept(noexcept(std::declval<_Mem_fn&>()(__ref.get())))
945 -> decltype((*this)(__ref.get()))
946 { return (*this)(__ref.get()); }
947
948 private:
949 _Res _Class::*__pm;
950 };
951
952 // _GLIBCXX_RESOLVE_LIB_DEFECTS
953 // 2048. Unnecessary mem_fn overloads
954 /**
955 * @brief Returns a function object that forwards to the member
956 * pointer @a pm.
957 * @ingroup functors
958 */
959 template<typename _Tp, typename _Class>
960 inline _Mem_fn<_Tp _Class::*>
961 mem_fn(_Tp _Class::* __pm) noexcept
962 {
963 return _Mem_fn<_Tp _Class::*>(__pm);
964 }
965
966 /**
967 * @brief Determines if the given type _Tp is a function object
968 * should be treated as a subexpression when evaluating calls to
969 * function objects returned by bind(). [TR1 3.6.1]
970 * @ingroup binders
971 */
972 template<typename _Tp>
973 struct is_bind_expression
974 : public false_type { };
975
976 /**
977 * @brief Determines if the given type _Tp is a placeholder in a
978 * bind() expression and, if so, which placeholder it is. [TR1 3.6.2]
979 * @ingroup binders
980 */
981 template<typename _Tp>
982 struct is_placeholder
983 : public integral_constant<int, 0>
984 { };
985
986 /** @brief The type of placeholder objects defined by libstdc++.
987 * @ingroup binders
988 */
989 template<int _Num> struct _Placeholder { };
990
991 _GLIBCXX_END_NAMESPACE_VERSION
992
993 /** @namespace std::placeholders
994 * @brief ISO C++11 entities sub-namespace for functional.
995 * @ingroup binders
996 */
997 namespace placeholders
998 {
999 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1000 /* Define a large number of placeholders. There is no way to
1001 * simplify this with variadic templates, because we\'re introducing
1002 * unique names for each.
1003 */
1004 extern const _Placeholder<1> _1;
1005 extern const _Placeholder<2> _2;
1006 extern const _Placeholder<3> _3;
1007 extern const _Placeholder<4> _4;
1008 extern const _Placeholder<5> _5;
1009 extern const _Placeholder<6> _6;
1010 extern const _Placeholder<7> _7;
1011 extern const _Placeholder<8> _8;
1012 extern const _Placeholder<9> _9;
1013 extern const _Placeholder<10> _10;
1014 extern const _Placeholder<11> _11;
1015 extern const _Placeholder<12> _12;
1016 extern const _Placeholder<13> _13;
1017 extern const _Placeholder<14> _14;
1018 extern const _Placeholder<15> _15;
1019 extern const _Placeholder<16> _16;
1020 extern const _Placeholder<17> _17;
1021 extern const _Placeholder<18> _18;
1022 extern const _Placeholder<19> _19;
1023 extern const _Placeholder<20> _20;
1024 extern const _Placeholder<21> _21;
1025 extern const _Placeholder<22> _22;
1026 extern const _Placeholder<23> _23;
1027 extern const _Placeholder<24> _24;
1028 extern const _Placeholder<25> _25;
1029 extern const _Placeholder<26> _26;
1030 extern const _Placeholder<27> _27;
1031 extern const _Placeholder<28> _28;
1032 extern const _Placeholder<29> _29;
1033 _GLIBCXX_END_NAMESPACE_VERSION
1034 }
1035
1036 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1037
1038 /**
1039 * Partial specialization of is_placeholder that provides the placeholder
1040 * number for the placeholder objects defined by libstdc++.
1041 * @ingroup binders
1042 */
1043 template<int _Num>
1044 struct is_placeholder<_Placeholder<_Num> >
1045 : public integral_constant<int, _Num>
1046 { };
1047
1048 template<int _Num>
1049 struct is_placeholder<const _Placeholder<_Num> >
1050 : public integral_constant<int, _Num>
1051 { };
1052
1053 /**
1054 * Used by _Safe_tuple_element to indicate that there is no tuple
1055 * element at this position.
1056 */
1057 struct _No_tuple_element;
1058
1059 /**
1060 * Implementation helper for _Safe_tuple_element. This primary
1061 * template handles the case where it is safe to use @c
1062 * tuple_element.
1063 */
1064 template<std::size_t __i, typename _Tuple, bool _IsSafe>
1065 struct _Safe_tuple_element_impl
1066 : tuple_element<__i, _Tuple> { };
1067
1068 /**
1069 * Implementation helper for _Safe_tuple_element. This partial
1070 * specialization handles the case where it is not safe to use @c
1071 * tuple_element. We just return @c _No_tuple_element.
1072 */
1073 template<std::size_t __i, typename _Tuple>
1074 struct _Safe_tuple_element_impl<__i, _Tuple, false>
1075 {
1076 typedef _No_tuple_element type;
1077 };
1078
1079 /**
1080 * Like tuple_element, but returns @c _No_tuple_element when
1081 * tuple_element would return an error.
1082 */
1083 template<std::size_t __i, typename _Tuple>
1084 struct _Safe_tuple_element
1085 : _Safe_tuple_element_impl<__i, _Tuple,
1086 (__i < tuple_size<_Tuple>::value)>
1087 { };
1088
1089 /**
1090 * Maps an argument to bind() into an actual argument to the bound
1091 * function object [TR1 3.6.3/5]. Only the first parameter should
1092 * be specified: the rest are used to determine among the various
1093 * implementations. Note that, although this class is a function
1094 * object, it isn\'t entirely normal because it takes only two
1095 * parameters regardless of the number of parameters passed to the
1096 * bind expression. The first parameter is the bound argument and
1097 * the second parameter is a tuple containing references to the
1098 * rest of the arguments.
1099 */
1100 template<typename _Arg,
1101 bool _IsBindExp = is_bind_expression<_Arg>::value,
1102 bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
1103 class _Mu;
1104
1105 /**
1106 * If the argument is reference_wrapper<_Tp>, returns the
1107 * underlying reference. [TR1 3.6.3/5 bullet 1]
1108 */
1109 template<typename _Tp>
1110 class _Mu<reference_wrapper<_Tp>, false, false>
1111 {
1112 public:
1113 typedef _Tp& result_type;
1114
1115 /* Note: This won\'t actually work for const volatile
1116 * reference_wrappers, because reference_wrapper::get() is const
1117 * but not volatile-qualified. This might be a defect in the TR.
1118 */
1119 template<typename _CVRef, typename _Tuple>
1120 result_type
1121 operator()(_CVRef& __arg, _Tuple&) const volatile
1122 { return __arg.get(); }
1123 };
1124
1125 /**
1126 * If the argument is a bind expression, we invoke the underlying
1127 * function object with the same cv-qualifiers as we are given and
1128 * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2]
1129 */
1130 template<typename _Arg>
1131 class _Mu<_Arg, true, false>
1132 {
1133 public:
1134 template<typename _CVArg, typename... _Args>
1135 auto
1136 operator()(_CVArg& __arg,
1137 tuple<_Args...>& __tuple) const volatile
1138 -> decltype(__arg(declval<_Args>()...))
1139 {
1140 // Construct an index tuple and forward to __call
1141 typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
1142 _Indexes;
1143 return this->__call(__arg, __tuple, _Indexes());
1144 }
1145
1146 private:
1147 // Invokes the underlying function object __arg by unpacking all
1148 // of the arguments in the tuple.
1149 template<typename _CVArg, typename... _Args, std::size_t... _Indexes>
1150 auto
1151 __call(_CVArg& __arg, tuple<_Args...>& __tuple,
1152 const _Index_tuple<_Indexes...>&) const volatile
1153 -> decltype(__arg(declval<_Args>()...))
1154 {
1155 return __arg(std::forward<_Args>(get<_Indexes>(__tuple))...);
1156 }
1157 };
1158
1159 /**
1160 * If the argument is a placeholder for the Nth argument, returns
1161 * a reference to the Nth argument to the bind function object.
1162 * [TR1 3.6.3/5 bullet 3]
1163 */
1164 template<typename _Arg>
1165 class _Mu<_Arg, false, true>
1166 {
1167 public:
1168 template<typename _Signature> class result;
1169
1170 template<typename _CVMu, typename _CVArg, typename _Tuple>
1171 class result<_CVMu(_CVArg, _Tuple)>
1172 {
1173 // Add a reference, if it hasn\'t already been done for us.
1174 // This allows us to be a little bit sloppy in constructing
1175 // the tuple that we pass to result_of<...>.
1176 typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value
1177 - 1), _Tuple>::type
1178 __base_type;
1179
1180 public:
1181 typedef typename add_rvalue_reference<__base_type>::type type;
1182 };
1183
1184 template<typename _Tuple>
1185 typename result<_Mu(_Arg, _Tuple)>::type
1186 operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
1187 {
1188 return std::forward<typename result<_Mu(_Arg, _Tuple)>::type>(
1189 ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple));
1190 }
1191 };
1192
1193 /**
1194 * If the argument is just a value, returns a reference to that
1195 * value. The cv-qualifiers on the reference are the same as the
1196 * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4]
1197 */
1198 template<typename _Arg>
1199 class _Mu<_Arg, false, false>
1200 {
1201 public:
1202 template<typename _Signature> struct result;
1203
1204 template<typename _CVMu, typename _CVArg, typename _Tuple>
1205 struct result<_CVMu(_CVArg, _Tuple)>
1206 {
1207 typedef typename add_lvalue_reference<_CVArg>::type type;
1208 };
1209
1210 // Pick up the cv-qualifiers of the argument
1211 template<typename _CVArg, typename _Tuple>
1212 _CVArg&&
1213 operator()(_CVArg&& __arg, _Tuple&) const volatile
1214 { return std::forward<_CVArg>(__arg); }
1215 };
1216
1217 /**
1218 * Maps member pointers into instances of _Mem_fn but leaves all
1219 * other function objects untouched. Used by tr1::bind(). The
1220 * primary template handles the non--member-pointer case.
1221 */
1222 template<typename _Tp>
1223 struct _Maybe_wrap_member_pointer
1224 {
1225 typedef _Tp type;
1226
1227 static const _Tp&
1228 __do_wrap(const _Tp& __x)
1229 { return __x; }
1230
1231 static _Tp&&
1232 __do_wrap(_Tp&& __x)
1233 { return static_cast<_Tp&&>(__x); }
1234 };
1235
1236 /**
1237 * Maps member pointers into instances of _Mem_fn but leaves all
1238 * other function objects untouched. Used by tr1::bind(). This
1239 * partial specialization handles the member pointer case.
1240 */
1241 template<typename _Tp, typename _Class>
1242 struct _Maybe_wrap_member_pointer<_Tp _Class::*>
1243 {
1244 typedef _Mem_fn<_Tp _Class::*> type;
1245
1246 static type
1247 __do_wrap(_Tp _Class::* __pm)
1248 { return type(__pm); }
1249 };
1250
1251 // Specialization needed to prevent "forming reference to void" errors when
1252 // bind<void>() is called, because argument deduction instantiates
1253 // _Maybe_wrap_member_pointer<void> outside the immediate context where
1254 // SFINAE applies.
1255 template<>
1256 struct _Maybe_wrap_member_pointer<void>
1257 {
1258 typedef void type;
1259 };
1260
1261 // std::get<I> for volatile-qualified tuples
1262 template<std::size_t _Ind, typename... _Tp>
1263 inline auto
1264 __volget(volatile tuple<_Tp...>& __tuple)
1265 -> typename tuple_element<_Ind, tuple<_Tp...>>::type volatile&
1266 { return std::get<_Ind>(const_cast<tuple<_Tp...>&>(__tuple)); }
1267
1268 // std::get<I> for const-volatile-qualified tuples
1269 template<std::size_t _Ind, typename... _Tp>
1270 inline auto
1271 __volget(const volatile tuple<_Tp...>& __tuple)
1272 -> typename tuple_element<_Ind, tuple<_Tp...>>::type const volatile&
1273 { return std::get<_Ind>(const_cast<const tuple<_Tp...>&>(__tuple)); }
1274
1275 /// Type of the function object returned from bind().
1276 template<typename _Signature>
1277 struct _Bind;
1278
1279 template<typename _Functor, typename... _Bound_args>
1280 class _Bind<_Functor(_Bound_args...)>
1281 : public _Weak_result_type<_Functor>
1282 {
1283 typedef _Bind __self_type;
1284 typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
1285 _Bound_indexes;
1286
1287 _Functor _M_f;
1288 tuple<_Bound_args...> _M_bound_args;
1289
1290 // Call unqualified
1291 template<typename _Result, typename... _Args, std::size_t... _Indexes>
1292 _Result
1293 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
1294 {
1295 return _M_f(_Mu<_Bound_args>()
1296 (get<_Indexes>(_M_bound_args), __args)...);
1297 }
1298
1299 // Call as const
1300 template<typename _Result, typename... _Args, std::size_t... _Indexes>
1301 _Result
1302 __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
1303 {
1304 return _M_f(_Mu<_Bound_args>()
1305 (get<_Indexes>(_M_bound_args), __args)...);
1306 }
1307
1308 // Call as volatile
1309 template<typename _Result, typename... _Args, std::size_t... _Indexes>
1310 _Result
1311 __call_v(tuple<_Args...>&& __args,
1312 _Index_tuple<_Indexes...>) volatile
1313 {
1314 return _M_f(_Mu<_Bound_args>()
1315 (__volget<_Indexes>(_M_bound_args), __args)...);
1316 }
1317
1318 // Call as const volatile
1319 template<typename _Result, typename... _Args, std::size_t... _Indexes>
1320 _Result
1321 __call_c_v(tuple<_Args...>&& __args,
1322 _Index_tuple<_Indexes...>) const volatile
1323 {
1324 return _M_f(_Mu<_Bound_args>()
1325 (__volget<_Indexes>(_M_bound_args), __args)...);
1326 }
1327
1328 public:
1329 template<typename... _Args>
1330 explicit _Bind(const _Functor& __f, _Args&&... __args)
1331 : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
1332 { }
1333
1334 template<typename... _Args>
1335 explicit _Bind(_Functor&& __f, _Args&&... __args)
1336 : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
1337 { }
1338
1339 _Bind(const _Bind&) = default;
1340
1341 _Bind(_Bind&& __b)
1342 : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
1343 { }
1344
1345 // Call unqualified
1346 template<typename... _Args, typename _Result
1347 = decltype( std::declval<_Functor>()(
1348 _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
1349 std::declval<tuple<_Args...>&>() )... ) )>
1350 _Result
1351 operator()(_Args&&... __args)
1352 {
1353 return this->__call<_Result>(
1354 std::forward_as_tuple(std::forward<_Args>(__args)...),
1355 _Bound_indexes());
1356 }
1357
1358 // Call as const
1359 template<typename... _Args, typename _Result
1360 = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
1361 typename add_const<_Functor>::type>::type>()(
1362 _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
1363 std::declval<tuple<_Args...>&>() )... ) )>
1364 _Result
1365 operator()(_Args&&... __args) const
1366 {
1367 return this->__call_c<_Result>(
1368 std::forward_as_tuple(std::forward<_Args>(__args)...),
1369 _Bound_indexes());
1370 }
1371
1372 // Call as volatile
1373 template<typename... _Args, typename _Result
1374 = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
1375 typename add_volatile<_Functor>::type>::type>()(
1376 _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
1377 std::declval<tuple<_Args...>&>() )... ) )>
1378 _Result
1379 operator()(_Args&&... __args) volatile
1380 {
1381 return this->__call_v<_Result>(
1382 std::forward_as_tuple(std::forward<_Args>(__args)...),
1383 _Bound_indexes());
1384 }
1385
1386 // Call as const volatile
1387 template<typename... _Args, typename _Result
1388 = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
1389 typename add_cv<_Functor>::type>::type>()(
1390 _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
1391 std::declval<tuple<_Args...>&>() )... ) )>
1392 _Result
1393 operator()(_Args&&... __args) const volatile
1394 {
1395 return this->__call_c_v<_Result>(
1396 std::forward_as_tuple(std::forward<_Args>(__args)...),
1397 _Bound_indexes());
1398 }
1399 };
1400
1401 /// Type of the function object returned from bind<R>().
1402 template<typename _Result, typename _Signature>
1403 struct _Bind_result;
1404
1405 template<typename _Result, typename _Functor, typename... _Bound_args>
1406 class _Bind_result<_Result, _Functor(_Bound_args...)>
1407 {
1408 typedef _Bind_result __self_type;
1409 typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
1410 _Bound_indexes;
1411
1412 _Functor _M_f;
1413 tuple<_Bound_args...> _M_bound_args;
1414
1415 // sfinae types
1416 template<typename _Res>
1417 struct __enable_if_void : enable_if<is_void<_Res>::value, int> { };
1418 template<typename _Res>
1419 struct __disable_if_void : enable_if<!is_void<_Res>::value, int> { };
1420
1421 // Call unqualified
1422 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1423 _Result
1424 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1425 typename __disable_if_void<_Res>::type = 0)
1426 {
1427 return _M_f(_Mu<_Bound_args>()
1428 (get<_Indexes>(_M_bound_args), __args)...);
1429 }
1430
1431 // Call unqualified, return void
1432 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1433 void
1434 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1435 typename __enable_if_void<_Res>::type = 0)
1436 {
1437 _M_f(_Mu<_Bound_args>()
1438 (get<_Indexes>(_M_bound_args), __args)...);
1439 }
1440
1441 // Call as const
1442 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1443 _Result
1444 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1445 typename __disable_if_void<_Res>::type = 0) const
1446 {
1447 return _M_f(_Mu<_Bound_args>()
1448 (get<_Indexes>(_M_bound_args), __args)...);
1449 }
1450
1451 // Call as const, return void
1452 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1453 void
1454 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1455 typename __enable_if_void<_Res>::type = 0) const
1456 {
1457 _M_f(_Mu<_Bound_args>()
1458 (get<_Indexes>(_M_bound_args), __args)...);
1459 }
1460
1461 // Call as volatile
1462 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1463 _Result
1464 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1465 typename __disable_if_void<_Res>::type = 0) volatile
1466 {
1467 return _M_f(_Mu<_Bound_args>()
1468 (__volget<_Indexes>(_M_bound_args), __args)...);
1469 }
1470
1471 // Call as volatile, return void
1472 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1473 void
1474 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1475 typename __enable_if_void<_Res>::type = 0) volatile
1476 {
1477 _M_f(_Mu<_Bound_args>()
1478 (__volget<_Indexes>(_M_bound_args), __args)...);
1479 }
1480
1481 // Call as const volatile
1482 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1483 _Result
1484 __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>,
1485 typename __disable_if_void<_Res>::type = 0) const volatile
1486 {
1487 return _M_f(_Mu<_Bound_args>()
1488 (__volget<_Indexes>(_M_bound_args), __args)...);
1489 }
1490
1491 // Call as const volatile, return void
1492 template<typename _Res, typename... _Args, std::size_t... _Indexes>
1493 void
1494 __call(tuple<_Args...>&& __args,
1495 _Index_tuple<_Indexes...>,
1496 typename __enable_if_void<_Res>::type = 0) const volatile
1497 {
1498 _M_f(_Mu<_Bound_args>()
1499 (__volget<_Indexes>(_M_bound_args), __args)...);
1500 }
1501
1502 public:
1503 typedef _Result result_type;
1504
1505 template<typename... _Args>
1506 explicit _Bind_result(const _Functor& __f, _Args&&... __args)
1507 : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
1508 { }
1509
1510 template<typename... _Args>
1511 explicit _Bind_result(_Functor&& __f, _Args&&... __args)
1512 : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
1513 { }
1514
1515 _Bind_result(const _Bind_result&) = default;
1516
1517 _Bind_result(_Bind_result&& __b)
1518 : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
1519 { }
1520
1521 // Call unqualified
1522 template<typename... _Args>
1523 result_type
1524 operator()(_Args&&... __args)
1525 {
1526 return this->__call<_Result>(
1527 std::forward_as_tuple(std::forward<_Args>(__args)...),
1528 _Bound_indexes());
1529 }
1530
1531 // Call as const
1532 template<typename... _Args>
1533 result_type
1534 operator()(_Args&&... __args) const
1535 {
1536 return this->__call<_Result>(
1537 std::forward_as_tuple(std::forward<_Args>(__args)...),
1538 _Bound_indexes());
1539 }
1540
1541 // Call as volatile
1542 template<typename... _Args>
1543 result_type
1544 operator()(_Args&&... __args) volatile
1545 {
1546 return this->__call<_Result>(
1547 std::forward_as_tuple(std::forward<_Args>(__args)...),
1548 _Bound_indexes());
1549 }
1550
1551 // Call as const volatile
1552 template<typename... _Args>
1553 result_type
1554 operator()(_Args&&... __args) const volatile
1555 {
1556 return this->__call<_Result>(
1557 std::forward_as_tuple(std::forward<_Args>(__args)...),
1558 _Bound_indexes());
1559 }
1560 };
1561
1562 /**
1563 * @brief Class template _Bind is always a bind expression.
1564 * @ingroup binders
1565 */
1566 template<typename _Signature>
1567 struct is_bind_expression<_Bind<_Signature> >
1568 : public true_type { };
1569
1570 /**
1571 * @brief Class template _Bind is always a bind expression.
1572 * @ingroup binders
1573 */
1574 template<typename _Signature>
1575 struct is_bind_expression<const _Bind<_Signature> >
1576 : public true_type { };
1577
1578 /**
1579 * @brief Class template _Bind is always a bind expression.
1580 * @ingroup binders
1581 */
1582 template<typename _Signature>
1583 struct is_bind_expression<volatile _Bind<_Signature> >
1584 : public true_type { };
1585
1586 /**
1587 * @brief Class template _Bind is always a bind expression.
1588 * @ingroup binders
1589 */
1590 template<typename _Signature>
1591 struct is_bind_expression<const volatile _Bind<_Signature>>
1592 : public true_type { };
1593
1594 /**
1595 * @brief Class template _Bind_result is always a bind expression.
1596 * @ingroup binders
1597 */
1598 template<typename _Result, typename _Signature>
1599 struct is_bind_expression<_Bind_result<_Result, _Signature>>
1600 : public true_type { };
1601
1602 /**
1603 * @brief Class template _Bind_result is always a bind expression.
1604 * @ingroup binders
1605 */
1606 template<typename _Result, typename _Signature>
1607 struct is_bind_expression<const _Bind_result<_Result, _Signature>>
1608 : public true_type { };
1609
1610 /**
1611 * @brief Class template _Bind_result is always a bind expression.
1612 * @ingroup binders
1613 */
1614 template<typename _Result, typename _Signature>
1615 struct is_bind_expression<volatile _Bind_result<_Result, _Signature>>
1616 : public true_type { };
1617
1618 /**
1619 * @brief Class template _Bind_result is always a bind expression.
1620 * @ingroup binders
1621 */
1622 template<typename _Result, typename _Signature>
1623 struct is_bind_expression<const volatile _Bind_result<_Result, _Signature>>
1624 : public true_type { };
1625
1626 // Trait type used to remove std::bind() from overload set via SFINAE
1627 // when first argument has integer type, so that std::bind() will
1628 // not be a better match than ::bind() from the BSD Sockets API.
1629 template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type>
1630 using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>;
1631
1632 template<bool _SocketLike, typename _Func, typename... _BoundArgs>
1633 struct _Bind_helper
1634 {
1635 typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
1636 __maybe_type;
1637 typedef typename __maybe_type::type __func_type;
1638 typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type;
1639 };
1640
1641 // Partial specialization for is_socketlike == true, does not define
1642 // nested type so std::bind() will not participate in overload resolution
1643 // when the first argument might be a socket file descriptor.
1644 template<typename _Func, typename... _BoundArgs>
1645 struct _Bind_helper<true, _Func, _BoundArgs...>
1646 { };
1647
1648 /**
1649 * @brief Function template for std::bind.
1650 * @ingroup binders
1651 */
1652 template<typename _Func, typename... _BoundArgs>
1653 inline typename
1654 _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
1655 bind(_Func&& __f, _BoundArgs&&... __args)
1656 {
1657 typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
1658 typedef typename __helper_type::__maybe_type __maybe_type;
1659 typedef typename __helper_type::type __result_type;
1660 return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
1661 std::forward<_BoundArgs>(__args)...);
1662 }
1663
1664 template<typename _Result, typename _Func, typename... _BoundArgs>
1665 struct _Bindres_helper
1666 {
1667 typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
1668 __maybe_type;
1669 typedef typename __maybe_type::type __functor_type;
1670 typedef _Bind_result<_Result,
1671 __functor_type(typename decay<_BoundArgs>::type...)>
1672 type;
1673 };
1674
1675 /**
1676 * @brief Function template for std::bind<R>.
1677 * @ingroup binders
1678 */
1679 template<typename _Result, typename _Func, typename... _BoundArgs>
1680 inline
1681 typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
1682 bind(_Func&& __f, _BoundArgs&&... __args)
1683 {
1684 typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type;
1685 typedef typename __helper_type::__maybe_type __maybe_type;
1686 typedef typename __helper_type::type __result_type;
1687 return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
1688 std::forward<_BoundArgs>(__args)...);
1689 }
1690
1691 template<typename _Signature>
1692 struct _Bind_simple;
1693
1694 template<typename _Callable, typename... _Args>
1695 struct _Bind_simple<_Callable(_Args...)>
1696 {
1697 typedef typename result_of<_Callable(_Args...)>::type result_type;
1698
1699 template<typename... _Args2, typename = typename
1700 enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type>
1701 explicit
1702 _Bind_simple(const _Callable& __callable, _Args2&&... __args)
1703 : _M_bound(__callable, std::forward<_Args2>(__args)...)
1704 { }
1705
1706 template<typename... _Args2, typename = typename
1707 enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type>
1708 explicit
1709 _Bind_simple(_Callable&& __callable, _Args2&&... __args)
1710 : _M_bound(std::move(__callable), std::forward<_Args2>(__args)...)
1711 { }
1712
1713 _Bind_simple(const _Bind_simple&) = default;
1714 _Bind_simple(_Bind_simple&&) = default;
1715
1716 result_type
1717 operator()()
1718 {
1719 typedef typename _Build_index_tuple<sizeof...(_Args)>::__type _Indices;
1720 return _M_invoke(_Indices());
1721 }
1722
1723 private:
1724
1725 template<std::size_t... _Indices>
1726 typename result_of<_Callable(_Args...)>::type
1727 _M_invoke(_Index_tuple<_Indices...>)
1728 {
1729 // std::bind always forwards bound arguments as lvalues,
1730 // but this type can call functions which only accept rvalues.
1731 return std::forward<_Callable>(std::get<0>(_M_bound))(
1732 std::forward<_Args>(std::get<_Indices+1>(_M_bound))...);
1733 }
1734
1735 std::tuple<_Callable, _Args...> _M_bound;
1736 };
1737
1738 template<typename _Func, typename... _BoundArgs>
1739 struct _Bind_simple_helper
1740 {
1741 typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
1742 __maybe_type;
1743 typedef typename __maybe_type::type __func_type;
1744 typedef _Bind_simple<__func_type(typename decay<_BoundArgs>::type...)>
1745 __type;
1746 };
1747
1748 // Simplified version of std::bind for internal use, without support for
1749 // unbound arguments, placeholders or nested bind expressions.
1750 template<typename _Callable, typename... _Args>
1751 typename _Bind_simple_helper<_Callable, _Args...>::__type
1752 __bind_simple(_Callable&& __callable, _Args&&... __args)
1753 {
1754 typedef _Bind_simple_helper<_Callable, _Args...> __helper_type;
1755 typedef typename __helper_type::__maybe_type __maybe_type;
1756 typedef typename __helper_type::__type __result_type;
1757 return __result_type(
1758 __maybe_type::__do_wrap( std::forward<_Callable>(__callable)),
1759 std::forward<_Args>(__args)...);
1760 }
1761
1762 /**
1763 * @brief Exception class thrown when class template function\'s
1764 * operator() is called with an empty target.
1765 * @ingroup exceptions
1766 */
1767 class bad_function_call : public std::exception
1768 {
1769 public:
1770 virtual ~bad_function_call() noexcept;
1771
1772 const char* what() const noexcept;
1773 };
1774
1775 /**
1776 * Trait identifying "location-invariant" types, meaning that the
1777 * address of the object (or any of its members) will not escape.
1778 * Also implies a trivial copy constructor and assignment operator.
1779 */
1780 template<typename _Tp>
1781 struct __is_location_invariant
1782 : integral_constant<bool, (is_pointer<_Tp>::value
1783 || is_member_pointer<_Tp>::value)>
1784 { };
1785
1786 class _Undefined_class;
1787
1788 union _Nocopy_types
1789 {
1790 void* _M_object;
1791 const void* _M_const_object;
1792 void (*_M_function_pointer)();
1793 void (_Undefined_class::*_M_member_pointer)();
1794 };
1795
1796 union _Any_data
1797 {
1798 void* _M_access() { return &_M_pod_data[0]; }
1799 const void* _M_access() const { return &_M_pod_data[0]; }
1800
1801 template<typename _Tp>
1802 _Tp&
1803 _M_access()
1804 { return *static_cast<_Tp*>(_M_access()); }
1805
1806 template<typename _Tp>
1807 const _Tp&
1808 _M_access() const
1809 { return *static_cast<const _Tp*>(_M_access()); }
1810
1811 _Nocopy_types _M_unused;
1812 char _M_pod_data[sizeof(_Nocopy_types)];
1813 };
1814
1815 enum _Manager_operation
1816 {
1817 __get_type_info,
1818 __get_functor_ptr,
1819 __clone_functor,
1820 __destroy_functor
1821 };
1822
1823 // Simple type wrapper that helps avoid annoying const problems
1824 // when casting between void pointers and pointers-to-pointers.
1825 template<typename _Tp>
1826 struct _Simple_type_wrapper
1827 {
1828 _Simple_type_wrapper(_Tp __value) : __value(__value) { }
1829
1830 _Tp __value;
1831 };
1832
1833 template<typename _Tp>
1834 struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
1835 : __is_location_invariant<_Tp>
1836 { };
1837
1838 // Converts a reference to a function object into a callable
1839 // function object.
1840 template<typename _Functor>
1841 inline _Functor&
1842 __callable_functor(_Functor& __f)
1843 { return __f; }
1844
1845 template<typename _Member, typename _Class>
1846 inline _Mem_fn<_Member _Class::*>
1847 __callable_functor(_Member _Class::* &__p)
1848 { return std::mem_fn(__p); }
1849
1850 template<typename _Member, typename _Class>
1851 inline _Mem_fn<_Member _Class::*>
1852 __callable_functor(_Member _Class::* const &__p)
1853 { return std::mem_fn(__p); }
1854
1855 template<typename _Member, typename _Class>
1856 inline _Mem_fn<_Member _Class::*>
1857 __callable_functor(_Member _Class::* volatile &__p)
1858 { return std::mem_fn(__p); }
1859
1860 template<typename _Member, typename _Class>
1861 inline _Mem_fn<_Member _Class::*>
1862 __callable_functor(_Member _Class::* const volatile &__p)
1863 { return std::mem_fn(__p); }
1864
1865 template<typename _Signature>
1866 class function;
1867
1868 /// Base class of all polymorphic function object wrappers.
1869 class _Function_base
1870 {
1871 public:
1872 static const std::size_t _M_max_size = sizeof(_Nocopy_types);
1873 static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
1874
1875 template<typename _Functor>
1876 class _Base_manager
1877 {
1878 protected:
1879 static const bool __stored_locally =
1880 (__is_location_invariant<_Functor>::value
1881 && sizeof(_Functor) <= _M_max_size
1882 && __alignof__(_Functor) <= _M_max_align
1883 && (_M_max_align % __alignof__(_Functor) == 0));
1884
1885 typedef integral_constant<bool, __stored_locally> _Local_storage;
1886
1887 // Retrieve a pointer to the function object
1888 static _Functor*
1889 _M_get_pointer(const _Any_data& __source)
1890 {
1891 const _Functor* __ptr =
1892 __stored_locally? std::__addressof(__source._M_access<_Functor>())
1893 /* have stored a pointer */ : __source._M_access<_Functor*>();
1894 return const_cast<_Functor*>(__ptr);
1895 }
1896
1897 // Clone a location-invariant function object that fits within
1898 // an _Any_data structure.
1899 static void
1900 _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
1901 {
1902 new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
1903 }
1904
1905 // Clone a function object that is not location-invariant or
1906 // that cannot fit into an _Any_data structure.
1907 static void
1908 _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
1909 {
1910 __dest._M_access<_Functor*>() =
1911 new _Functor(*__source._M_access<_Functor*>());
1912 }
1913
1914 // Destroying a location-invariant object may still require
1915 // destruction.
1916 static void
1917 _M_destroy(_Any_data& __victim, true_type)
1918 {
1919 __victim._M_access<_Functor>().~_Functor();
1920 }
1921
1922 // Destroying an object located on the heap.
1923 static void
1924 _M_destroy(_Any_data& __victim, false_type)
1925 {
1926 delete __victim._M_access<_Functor*>();
1927 }
1928
1929 public:
1930 static bool
1931 _M_manager(_Any_data& __dest, const _Any_data& __source,
1932 _Manager_operation __op)
1933 {
1934 switch (__op)
1935 {
1936 #ifdef __GXX_RTTI
1937 case __get_type_info:
1938 __dest._M_access<const type_info*>() = &typeid(_Functor);
1939 break;
1940 #endif
1941 case __get_functor_ptr:
1942 __dest._M_access<_Functor*>() = _M_get_pointer(__source);
1943 break;
1944
1945 case __clone_functor:
1946 _M_clone(__dest, __source, _Local_storage());
1947 break;
1948
1949 case __destroy_functor:
1950 _M_destroy(__dest, _Local_storage());
1951 break;
1952 }
1953 return false;
1954 }
1955
1956 static void
1957 _M_init_functor(_Any_data& __functor, _Functor&& __f)
1958 { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
1959
1960 template<typename _Signature>
1961 static bool
1962 _M_not_empty_function(const function<_Signature>& __f)
1963 { return static_cast<bool>(__f); }
1964
1965 template<typename _Tp>
1966 static bool
1967 _M_not_empty_function(const _Tp*& __fp)
1968 { return __fp; }
1969
1970 template<typename _Class, typename _Tp>
1971 static bool
1972 _M_not_empty_function(_Tp _Class::* const& __mp)
1973 { return __mp; }
1974
1975 template<typename _Tp>
1976 static bool
1977 _M_not_empty_function(const _Tp&)
1978 { return true; }
1979
1980 private:
1981 static void
1982 _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
1983 { new (__functor._M_access()) _Functor(std::move(__f)); }
1984
1985 static void
1986 _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
1987 { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
1988 };
1989
1990 template<typename _Functor>
1991 class _Ref_manager : public _Base_manager<_Functor*>
1992 {
1993 typedef _Function_base::_Base_manager<_Functor*> _Base;
1994
1995 public:
1996 static bool
1997 _M_manager(_Any_data& __dest, const _Any_data& __source,
1998 _Manager_operation __op)
1999 {
2000 switch (__op)
2001 {
2002 #ifdef __GXX_RTTI
2003 case __get_type_info:
2004 __dest._M_access<const type_info*>() = &typeid(_Functor);
2005 break;
2006 #endif
2007 case __get_functor_ptr:
2008 __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
2009 return is_const<_Functor>::value;
2010 break;
2011
2012 default:
2013 _Base::_M_manager(__dest, __source, __op);
2014 }
2015 return false;
2016 }
2017
2018 static void
2019 _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
2020 {
2021 _Base::_M_init_functor(__functor, std::__addressof(__f.get()));
2022 }
2023 };
2024
2025 _Function_base() : _M_manager(0) { }
2026
2027 ~_Function_base()
2028 {
2029 if (_M_manager)
2030 _M_manager(_M_functor, _M_functor, __destroy_functor);
2031 }
2032
2033
2034 bool _M_empty() const { return !_M_manager; }
2035
2036 typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
2037 _Manager_operation);
2038
2039 _Any_data _M_functor;
2040 _Manager_type _M_manager;
2041 };
2042
2043 template<typename _Signature, typename _Functor>
2044 class _Function_handler;
2045
2046 template<typename _Res, typename _Functor, typename... _ArgTypes>
2047 class _Function_handler<_Res(_ArgTypes...), _Functor>
2048 : public _Function_base::_Base_manager<_Functor>
2049 {
2050 typedef _Function_base::_Base_manager<_Functor> _Base;
2051
2052 public:
2053 static _Res
2054 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2055 {
2056 return (*_Base::_M_get_pointer(__functor))(
2057 std::forward<_ArgTypes>(__args)...);
2058 }
2059 };
2060
2061 template<typename _Functor, typename... _ArgTypes>
2062 class _Function_handler<void(_ArgTypes...), _Functor>
2063 : public _Function_base::_Base_manager<_Functor>
2064 {
2065 typedef _Function_base::_Base_manager<_Functor> _Base;
2066
2067 public:
2068 static void
2069 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2070 {
2071 (*_Base::_M_get_pointer(__functor))(
2072 std::forward<_ArgTypes>(__args)...);
2073 }
2074 };
2075
2076 template<typename _Res, typename _Functor, typename... _ArgTypes>
2077 class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
2078 : public _Function_base::_Ref_manager<_Functor>
2079 {
2080 typedef _Function_base::_Ref_manager<_Functor> _Base;
2081
2082 public:
2083 static _Res
2084 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2085 {
2086 return __callable_functor(**_Base::_M_get_pointer(__functor))(
2087 std::forward<_ArgTypes>(__args)...);
2088 }
2089 };
2090
2091 template<typename _Functor, typename... _ArgTypes>
2092 class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
2093 : public _Function_base::_Ref_manager<_Functor>
2094 {
2095 typedef _Function_base::_Ref_manager<_Functor> _Base;
2096
2097 public:
2098 static void
2099 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2100 {
2101 __callable_functor(**_Base::_M_get_pointer(__functor))(
2102 std::forward<_ArgTypes>(__args)...);
2103 }
2104 };
2105
2106 template<typename _Class, typename _Member, typename _Res,
2107 typename... _ArgTypes>
2108 class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
2109 : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
2110 {
2111 typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
2112 _Base;
2113
2114 public:
2115 static _Res
2116 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2117 {
2118 return std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
2119 std::forward<_ArgTypes>(__args)...);
2120 }
2121 };
2122
2123 template<typename _Class, typename _Member, typename... _ArgTypes>
2124 class _Function_handler<void(_ArgTypes...), _Member _Class::*>
2125 : public _Function_base::_Base_manager<
2126 _Simple_type_wrapper< _Member _Class::* > >
2127 {
2128 typedef _Member _Class::* _Functor;
2129 typedef _Simple_type_wrapper<_Functor> _Wrapper;
2130 typedef _Function_base::_Base_manager<_Wrapper> _Base;
2131
2132 public:
2133 static bool
2134 _M_manager(_Any_data& __dest, const _Any_data& __source,
2135 _Manager_operation __op)
2136 {
2137 switch (__op)
2138 {
2139 #ifdef __GXX_RTTI
2140 case __get_type_info:
2141 __dest._M_access<const type_info*>() = &typeid(_Functor);
2142 break;
2143 #endif
2144 case __get_functor_ptr:
2145 __dest._M_access<_Functor*>() =
2146 &_Base::_M_get_pointer(__source)->__value;
2147 break;
2148
2149 default:
2150 _Base::_M_manager(__dest, __source, __op);
2151 }
2152 return false;
2153 }
2154
2155 static void
2156 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
2157 {
2158 std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
2159 std::forward<_ArgTypes>(__args)...);
2160 }
2161 };
2162
2163 /**
2164 * @brief Primary class template for std::function.
2165 * @ingroup functors
2166 *
2167 * Polymorphic function wrapper.
2168 */
2169 template<typename _Res, typename... _ArgTypes>
2170 class function<_Res(_ArgTypes...)>
2171 : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
2172 private _Function_base
2173 {
2174 typedef _Res _Signature_type(_ArgTypes...);
2175
2176 template<typename _Functor>
2177 using _Invoke = decltype(__callable_functor(std::declval<_Functor&>())
2178 (std::declval<_ArgTypes>()...) );
2179
2180 template<typename _CallRes, typename _Res1>
2181 struct _CheckResult
2182 : is_convertible<_CallRes, _Res1> { };
2183
2184 template<typename _CallRes>
2185 struct _CheckResult<_CallRes, void>
2186 : true_type { };
2187
2188 template<typename _Functor>
2189 using _Callable = _CheckResult<_Invoke<_Functor>, _Res>;
2190
2191 template<typename _Cond, typename _Tp>
2192 using _Requires = typename enable_if<_Cond::value, _Tp>::type;
2193
2194 public:
2195 typedef _Res result_type;
2196
2197 // [3.7.2.1] construct/copy/destroy
2198
2199 /**
2200 * @brief Default construct creates an empty function call wrapper.
2201 * @post @c !(bool)*this
2202 */
2203 function() noexcept
2204 : _Function_base() { }
2205
2206 /**
2207 * @brief Creates an empty function call wrapper.
2208 * @post @c !(bool)*this
2209 */
2210 function(nullptr_t) noexcept
2211 : _Function_base() { }
2212
2213 /**
2214 * @brief %Function copy constructor.
2215 * @param __x A %function object with identical call signature.
2216 * @post @c bool(*this) == bool(__x)
2217 *
2218 * The newly-created %function contains a copy of the target of @a
2219 * __x (if it has one).
2220 */
2221 function(const function& __x);
2222
2223 /**
2224 * @brief %Function move constructor.
2225 * @param __x A %function object rvalue with identical call signature.
2226 *
2227 * The newly-created %function contains the target of @a __x
2228 * (if it has one).
2229 */
2230 function(function&& __x) : _Function_base()
2231 {
2232 __x.swap(*this);
2233 }
2234
2235 // TODO: needs allocator_arg_t
2236
2237 /**
2238 * @brief Builds a %function that targets a copy of the incoming
2239 * function object.
2240 * @param __f A %function object that is callable with parameters of
2241 * type @c T1, @c T2, ..., @c TN and returns a value convertible
2242 * to @c Res.
2243 *
2244 * The newly-created %function object will target a copy of
2245 * @a __f. If @a __f is @c reference_wrapper<F>, then this function
2246 * object will contain a reference to the function object @c
2247 * __f.get(). If @a __f is a NULL function pointer or NULL
2248 * pointer-to-member, the newly-created object will be empty.
2249 *
2250 * If @a __f is a non-NULL function pointer or an object of type @c
2251 * reference_wrapper<F>, this function will not throw.
2252 */
2253 template<typename _Functor,
2254 typename = _Requires<_Callable<_Functor>, void>>
2255 function(_Functor);
2256
2257 /**
2258 * @brief %Function assignment operator.
2259 * @param __x A %function with identical call signature.
2260 * @post @c (bool)*this == (bool)x
2261 * @returns @c *this
2262 *
2263 * The target of @a __x is copied to @c *this. If @a __x has no
2264 * target, then @c *this will be empty.
2265 *
2266 * If @a __x targets a function pointer or a reference to a function
2267 * object, then this operation will not throw an %exception.
2268 */
2269 function&
2270 operator=(const function& __x)
2271 {
2272 function(__x).swap(*this);
2273 return *this;
2274 }
2275
2276 /**
2277 * @brief %Function move-assignment operator.
2278 * @param __x A %function rvalue with identical call signature.
2279 * @returns @c *this
2280 *
2281 * The target of @a __x is moved to @c *this. If @a __x has no
2282 * target, then @c *this will be empty.
2283 *
2284 * If @a __x targets a function pointer or a reference to a function
2285 * object, then this operation will not throw an %exception.
2286 */
2287 function&
2288 operator=(function&& __x)
2289 {
2290 function(std::move(__x)).swap(*this);
2291 return *this;
2292 }
2293
2294 /**
2295 * @brief %Function assignment to zero.
2296 * @post @c !(bool)*this
2297 * @returns @c *this
2298 *
2299 * The target of @c *this is deallocated, leaving it empty.
2300 */
2301 function&
2302 operator=(nullptr_t)
2303 {
2304 if (_M_manager)
2305 {
2306 _M_manager(_M_functor, _M_functor, __destroy_functor);
2307 _M_manager = 0;
2308 _M_invoker = 0;
2309 }
2310 return *this;
2311 }
2312
2313 /**
2314 * @brief %Function assignment to a new target.
2315 * @param __f A %function object that is callable with parameters of
2316 * type @c T1, @c T2, ..., @c TN and returns a value convertible
2317 * to @c Res.
2318 * @return @c *this
2319 *
2320 * This %function object wrapper will target a copy of @a
2321 * __f. If @a __f is @c reference_wrapper<F>, then this function
2322 * object will contain a reference to the function object @c
2323 * __f.get(). If @a __f is a NULL function pointer or NULL
2324 * pointer-to-member, @c this object will be empty.
2325 *
2326 * If @a __f is a non-NULL function pointer or an object of type @c
2327 * reference_wrapper<F>, this function will not throw.
2328 */
2329 template<typename _Functor>
2330 _Requires<_Callable<_Functor>, function&>
2331 operator=(_Functor&& __f)
2332 {
2333 function(std::forward<_Functor>(__f)).swap(*this);
2334 return *this;
2335 }
2336
2337 /// @overload
2338 template<typename _Functor>
2339 function&
2340 operator=(reference_wrapper<_Functor> __f) noexcept
2341 {
2342 function(__f).swap(*this);
2343 return *this;
2344 }
2345
2346 // [3.7.2.2] function modifiers
2347
2348 /**
2349 * @brief Swap the targets of two %function objects.
2350 * @param __x A %function with identical call signature.
2351 *
2352 * Swap the targets of @c this function object and @a __f. This
2353 * function will not throw an %exception.
2354 */
2355 void swap(function& __x)
2356 {
2357 std::swap(_M_functor, __x._M_functor);
2358 std::swap(_M_manager, __x._M_manager);
2359 std::swap(_M_invoker, __x._M_invoker);
2360 }
2361
2362 // TODO: needs allocator_arg_t
2363 /*
2364 template<typename _Functor, typename _Alloc>
2365 void
2366 assign(_Functor&& __f, const _Alloc& __a)
2367 {
2368 function(allocator_arg, __a,
2369 std::forward<_Functor>(__f)).swap(*this);
2370 }
2371 */
2372
2373 // [3.7.2.3] function capacity
2374
2375 /**
2376 * @brief Determine if the %function wrapper has a target.
2377 *
2378 * @return @c true when this %function object contains a target,
2379 * or @c false when it is empty.
2380 *
2381 * This function will not throw an %exception.
2382 */
2383 explicit operator bool() const noexcept
2384 { return !_M_empty(); }
2385
2386 // [3.7.2.4] function invocation
2387
2388 /**
2389 * @brief Invokes the function targeted by @c *this.
2390 * @returns the result of the target.
2391 * @throws bad_function_call when @c !(bool)*this
2392 *
2393 * The function call operator invokes the target function object
2394 * stored by @c this.
2395 */
2396 _Res operator()(_ArgTypes... __args) const;
2397
2398 #ifdef __GXX_RTTI
2399 // [3.7.2.5] function target access
2400 /**
2401 * @brief Determine the type of the target of this function object
2402 * wrapper.
2403 *
2404 * @returns the type identifier of the target function object, or
2405 * @c typeid(void) if @c !(bool)*this.
2406 *
2407 * This function will not throw an %exception.
2408 */
2409 const type_info& target_type() const noexcept;
2410
2411 /**
2412 * @brief Access the stored target function object.
2413 *
2414 * @return Returns a pointer to the stored target function object,
2415 * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
2416 * pointer.
2417 *
2418 * This function will not throw an %exception.
2419 */
2420 template<typename _Functor> _Functor* target() noexcept;
2421
2422 /// @overload
2423 template<typename _Functor> const _Functor* target() const noexcept;
2424 #endif
2425
2426 private:
2427 typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
2428 _Invoker_type _M_invoker;
2429 };
2430
2431 // Out-of-line member definitions.
2432 template<typename _Res, typename... _ArgTypes>
2433 function<_Res(_ArgTypes...)>::
2434 function(const function& __x)
2435 : _Function_base()
2436 {
2437 if (static_cast<bool>(__x))
2438 {
2439 _M_invoker = __x._M_invoker;
2440 _M_manager = __x._M_manager;
2441 __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
2442 }
2443 }
2444
2445 template<typename _Res, typename... _ArgTypes>
2446 template<typename _Functor, typename>
2447 function<_Res(_ArgTypes...)>::
2448 function(_Functor __f)
2449 : _Function_base()
2450 {
2451 typedef _Function_handler<_Signature_type, _Functor> _My_handler;
2452
2453 if (_My_handler::_M_not_empty_function(__f))
2454 {
2455 _My_handler::_M_init_functor(_M_functor, std::move(__f));
2456 _M_invoker = &_My_handler::_M_invoke;
2457 _M_manager = &_My_handler::_M_manager;
2458 }
2459 }
2460
2461 template<typename _Res, typename... _ArgTypes>
2462 _Res
2463 function<_Res(_ArgTypes...)>::
2464 operator()(_ArgTypes... __args) const
2465 {
2466 if (_M_empty())
2467 __throw_bad_function_call();
2468 return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
2469 }
2470
2471 #ifdef __GXX_RTTI
2472 template<typename _Res, typename... _ArgTypes>
2473 const type_info&
2474 function<_Res(_ArgTypes...)>::
2475 target_type() const noexcept
2476 {
2477 if (_M_manager)
2478 {
2479 _Any_data __typeinfo_result;
2480 _M_manager(__typeinfo_result, _M_functor, __get_type_info);
2481 return *__typeinfo_result._M_access<const type_info*>();
2482 }
2483 else
2484 return typeid(void);
2485 }
2486
2487 template<typename _Res, typename... _ArgTypes>
2488 template<typename _Functor>
2489 _Functor*
2490 function<_Res(_ArgTypes...)>::
2491 target() noexcept
2492 {
2493 if (typeid(_Functor) == target_type() && _M_manager)
2494 {
2495 _Any_data __ptr;
2496 if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
2497 && !is_const<_Functor>::value)
2498 return 0;
2499 else
2500 return __ptr._M_access<_Functor*>();
2501 }
2502 else
2503 return 0;
2504 }
2505
2506 template<typename _Res, typename... _ArgTypes>
2507 template<typename _Functor>
2508 const _Functor*
2509 function<_Res(_ArgTypes...)>::
2510 target() const noexcept
2511 {
2512 if (typeid(_Functor) == target_type() && _M_manager)
2513 {
2514 _Any_data __ptr;
2515 _M_manager(__ptr, _M_functor, __get_functor_ptr);
2516 return __ptr._M_access<const _Functor*>();
2517 }
2518 else
2519 return 0;
2520 }
2521 #endif
2522
2523 // [20.7.15.2.6] null pointer comparisons
2524
2525 /**
2526 * @brief Compares a polymorphic function object wrapper against 0
2527 * (the NULL pointer).
2528 * @returns @c true if the wrapper has no target, @c false otherwise
2529 *
2530 * This function will not throw an %exception.
2531 */
2532 template<typename _Res, typename... _Args>
2533 inline bool
2534 operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
2535 { return !static_cast<bool>(__f); }
2536
2537 /// @overload
2538 template<typename _Res, typename... _Args>
2539 inline bool
2540 operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
2541 { return !static_cast<bool>(__f); }
2542
2543 /**
2544 * @brief Compares a polymorphic function object wrapper against 0
2545 * (the NULL pointer).
2546 * @returns @c false if the wrapper has no target, @c true otherwise
2547 *
2548 * This function will not throw an %exception.
2549 */
2550 template<typename _Res, typename... _Args>
2551 inline bool
2552 operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
2553 { return static_cast<bool>(__f); }
2554
2555 /// @overload
2556 template<typename _Res, typename... _Args>
2557 inline bool
2558 operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
2559 { return static_cast<bool>(__f); }
2560
2561 // [20.7.15.2.7] specialized algorithms
2562
2563 /**
2564 * @brief Swap the targets of two polymorphic function object wrappers.
2565 *
2566 * This function will not throw an %exception.
2567 */
2568 template<typename _Res, typename... _Args>
2569 inline void
2570 swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y)
2571 { __x.swap(__y); }
2572
2573 _GLIBCXX_END_NAMESPACE_VERSION
2574 } // namespace std
2575
2576 #endif // C++11
2577
2578 #endif // _GLIBCXX_FUNCTIONAL
2579
functional
這個實作的原理與上面分析的大緻相同,使用函數指針實作多态,也使用了small object optimization。
注:标準庫的檔案的縮進是2格,有時8個空格會用一個tab代替,在将tab顯示為4位元組的編輯器中縮進會比較亂,我已經把tab全部替換為8個空格;很多人縮進習慣是4格,但如果把2格全部替換成4格也會亂了格式,是以以下摘錄自标準庫檔案的代碼全部都是2格縮進。
2.1 類型系統
類型之間的關系,無非是繼承、嵌套、組合。這個實作中三者都有。
關于繼承,你也許會問,我們剛才不是說了這種實作沒法用繼承嗎?實際上沒有沖突。剛才說的繼承,是接口上的繼承,講得更具體點就是要繼承虛函數,是一種is-a的關系;而這裡的繼承,是實作上的繼承,是一種is-implemented-in-terms-of的關系,在語言層面大多是private繼承。
在泛型程式設計中,還有一個關于繼承的問題,就是在繼承體系的哪一層引入模闆參數。
嵌套,即類中定義嵌套類型,使類之間的結構更加清晰,在泛型程式設計中還可以簡化設計。
組合,在于一個類的對象中包含其他類的對象,本應屬于對象關系的範疇,但是在這個實作中,一個類一般不會在同一個scope内出現多個對象,是以我這裡就直接把對象組合的概念拿來用了。
2.1.1 異常類
首先出現的是 bad_function_call 類型,這是一個異常類,當調用空 std::function 對象時抛出:
1 class bad_function_call : public std::exception
2 {
3 public:
4 virtual ~bad_function_call() noexcept;
5 const char* what() const noexcept;
6 };
由于不是模闆類(難得能在STL中發現非模闆類),實作被編譯好放在了目标檔案中。雖然GCC開源,但既然這個類不太重要,而且稍微想想就能知道它是怎麼實作的了,是以這裡就不深究了。
相關的還有一個用于抛出異常的函數:
1 void __throw_bad_function_call() __attribute__((__noreturn__));
在 <bits/functexcept.h> 中。同樣隻有聲明沒有定義。
2.1.2 資料存儲
有關資料存儲的類共有3個:
1 class _Undefined_class;
2
3 union _Nocopy_types
4 {
5 void* _M_object;
6 const void* _M_const_object;
7 void (*_M_function_pointer)();
8 void (_Undefined_class::*_M_member_pointer)();
9 };
10
11 union _Any_data
12 {
13 void* _M_access() { return &_M_pod_data[0]; }
14 const void* _M_access() const { return &_M_pod_data[0]; }
15
16 template<typename _Tp>
17 _Tp&
18 _M_access()
19 { return *static_cast<_Tp*>(_M_access()); }
20
21 template<typename _Tp>
22 const _Tp&
23 _M_access() const
24 { return *static_cast<const _Tp*>(_M_access()); }
25
26 _Nocopy_types _M_unused;
27 char _M_pod_data[sizeof(_Nocopy_types)];
28 };
_Undefined_class ,顧名思義,連定義都沒有,隻是用于聲明 _Nocopy_types 中的成員指針資料域,因為同一個平台上成員指針的大小是相同的。
_Nocopy_types ,是4種類型的聯合體類型,分别為指針、常量指針、函數指針與成員指針。“nocopy”指的是這幾種類型指向的對象類型,而不是本身。
_Any_data ,是兩種類型的聯合體類型,一個是 _Nocopy_types ,另一個是 char 數組,兩者大小相等。後者是POD的,POD的好處多啊,memcpy可以用,最重要的是複制不會抛異常。非模闆 _M_access() 傳回指針,模闆 _M_access() 傳回解引用的結果,兩者都有 const 重載。
2.1.3 輔助類
1 enum _Manager_operation
2 {
3 __get_type_info,
4 __get_functor_ptr,
5 __clone_functor,
6 __destroy_functor
7 };
_Manager_operation ,枚舉類,是前面所說控制 std::function 的函數指針需要的參數類型。定義了4種操作:獲得 type_info 、獲得仿函數(就是函數對象)指針、複制仿函數、銷毀(析構)仿函數。從這個定義中可以看出,1.4節所說的各種功能中,需要延遲調用的,除了函數對象調用以外,都可以通過這4個功能來組合起來。我們後面還會進一步探讨這個問題。
1 template<typename _Tp>
2 struct __is_location_invariant
3 : integral_constant<bool, (is_pointer<_Tp>::value
4 || is_member_pointer<_Tp>::value)>
5 { };
__is_location_invariant ,一個trait類,判斷一個類型是不是“位置不變”的。從字面上來了解,一個類型如果是“位置不變”的,那麼對于一個這種類型的對象,無論它複制到哪裡,各個對象的底層表示都是相同的。在這個定義中,一個類型是“位置不變”的,當且僅當它是一個指針或成員指針,與一般的了解有所不同(更新:後來改為 template<typename _Tp> struct __is_location_invariant : is_trivially_copyable<_Tp>::type { }; ,這就比較容易了解了)。
1 template<typename _Tp>
2 struct _Simple_type_wrapper
3 {
4 _Simple_type_wrapper(_Tp __value) : __value(__value) { }
5
6 _Tp __value;
7 };
8
9 template<typename _Tp>
10 struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
11 : __is_location_invariant<_Tp>
12 { };
_Simple_type_wrapper ,一個簡單的包裝器,用于避免 void* 與指針的指針之間類型轉換的 const 問題。以及 __is_location_invariant 對 _Simple_type_wrapper 的偏特化。
2.1.4 記憶體管理基類
類 _Function_base 定義了一系列用于管理函數對象記憶體的函數,這是一個非模闆類:
1 class _Function_base
2 {
3 public:
4 static const std::size_t _M_max_size = sizeof(_Nocopy_types);
5 static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
6
7 template<typename _Functor>
8 class _Base_manager;
9
10 template<typename _Functor>
11 class _Ref_manager;
12
13 _Function_base() : _M_manager(0) { }
14
15 ~_Function_base()
16 {
17 if (_M_manager)
18 _M_manager(_M_functor, _M_functor, __destroy_functor);
19 }
20
21 bool _M_empty() const { return !_M_manager; }
22
23 typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
24 _Manager_operation);
25
26 _Any_data _M_functor;
27 _Manager_type _M_manager;
28 };
_Function_base 是 std::function 的實作基類,定義了兩個靜态常量,用于後面的trait類;兩個内部類,用于包裝靜态方法;函數指針類型 _Manager_type 的對象 _M_manager ,用于存取 _Any_data 類型的 _M_functor 中的資料;構造函數,将函數指針置為空;析構函數,調用函數指針,銷毀函數對象;_M_empty() 方法,檢測内部是否存有函數對象。
我們來看其中的 _Base_manager 類:
1 template<typename _Functor>
2 class _Base_manager
3 {
4 protected:
5 static const bool __stored_locally =
6 (__is_location_invariant<_Functor>::value
7 && sizeof(_Functor) <= _M_max_size
8 && __alignof__(_Functor) <= _M_max_align
9 && (_M_max_align % __alignof__(_Functor) == 0));
10
11 typedef integral_constant<bool, __stored_locally> _Local_storage;
12
13 static _Functor*
14 _M_get_pointer(const _Any_data& __source);
15
16 static void
17 _M_clone(_Any_data& __dest, const _Any_data& __source, true_type);
18
19 static void
20 _M_clone(_Any_data& __dest, const _Any_data& __source, false_type);
21
22 static void
23 _M_destroy(_Any_data& __victim, true_type);
24
25 static void
26 _M_destroy(_Any_data& __victim, false_type);
27
28 public:
29 static bool
30 _M_manager(_Any_data& __dest, const _Any_data& __source,
31 _Manager_operation __op);
32
33 static void
34 _M_init_functor(_Any_data& __functor, _Functor&& __f);
35
36 template<typename _Signature>
37 static bool
38 _M_not_empty_function(const function<_Signature>& __f);
39
40 template<typename _Tp>
41 static bool
42 _M_not_empty_function(const _Tp*& __fp);
43
44 template<typename _Class, typename _Tp>
45 static bool
46 _M_not_empty_function(_Tp _Class::* const& __mp);
47
48 template<typename _Tp>
49 static bool
50 _M_not_empty_function(const _Tp&);
51
52 private:
53 static void
54 _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type);
55
56 static void
57 _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type);
58 };
定義了一個靜态布爾常量 __stored_locally ,它為真當且僅當 __is_location_invariant trait為真、仿函數放得下、仿函數的align符合兩個要求。然後再反過來根據這個值定義trait類 _Local_storage (标準庫裡一般都是根據value trait來生成value)。
其餘幾個靜态方法,顧名思義即可。有個值得思考的問題,就是為什麼 _M_init_functor 是public的,沒有被放進 _M_manager 呢?
再來看 _Ref_manager 類:
1 template<typename _Functor>
2 class _Ref_manager : public _Base_manager<_Functor*>
3 {
4 typedef _Function_base::_Base_manager<_Functor*> _Base;
5
6 public:
7 static bool
8 _M_manager(_Any_data& __dest, const _Any_data& __source,
9 _Manager_operation __op);
10
11 static void
12 _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f);
13 };
_Ref_manager 繼承自 _Base_manager 類,覆寫了兩個靜态方法。
2.1.5 仿函數調用
起輔助作用的模闆函數 __callable_functor :
1 template<typename _Functor>
2 inline _Functor&
3 __callable_functor(_Functor& __f)
4 { return __f; }
5
6 template<typename _Member, typename _Class>
7 inline _Mem_fn<_Member _Class::*>
8 __callable_functor(_Member _Class::* &__p)
9 { return std::mem_fn(__p); }
10
11 template<typename _Member, typename _Class>
12 inline _Mem_fn<_Member _Class::*>
13 __callable_functor(_Member _Class::* const &__p)
14 { return std::mem_fn(__p); }
15
16 template<typename _Member, typename _Class>
17 inline _Mem_fn<_Member _Class::*>
18 __callable_functor(_Member _Class::* volatile &__p)
19 { return std::mem_fn(__p); }
20
21 template<typename _Member, typename _Class>
22 inline _Mem_fn<_Member _Class::*>
23 __callable_functor(_Member _Class::* const volatile &__p)
24 { return std::mem_fn(__p); }
對非成員指針類型,直接傳回參數本身;對成員指針類型,傳回 mem_fn() 的結果(将類對象轉換為第一個參數;這個标準庫函數的實作不在這篇文章中涉及),并有cv-qualified重載。它改變了調用的形式,把所有的參數都放在了小括号中。
_Function_handler 類,管理仿函數調用:
1 template<typename _Signature, typename _Functor>
2 class _Function_handler;
3
4 template<typename _Res, typename _Functor, typename... _ArgTypes>
5 class _Function_handler<_Res(_ArgTypes...), _Functor>
6 : public _Function_base::_Base_manager<_Functor>
7 {
8 typedef _Function_base::_Base_manager<_Functor> _Base;
9
10 public:
11 static _Res
12 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
13 };
14
15 template<typename _Functor, typename... _ArgTypes>
16 class _Function_handler<void(_ArgTypes...), _Functor>
17 : public _Function_base::_Base_manager<_Functor>
18 {
19 typedef _Function_base::_Base_manager<_Functor> _Base;
20
21 public:
22 static void
23 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
24 };
25
26 template<typename _Res, typename _Functor, typename... _ArgTypes>
27 class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
28 : public _Function_base::_Ref_manager<_Functor>
29 {
30 typedef _Function_base::_Ref_manager<_Functor> _Base;
31
32 public:
33 static _Res
34 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
35 };
36
37 template<typename _Functor, typename... _ArgTypes>
38 class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
39 : public _Function_base::_Ref_manager<_Functor>
40 {
41 typedef _Function_base::_Ref_manager<_Functor> _Base;
42
43 public:
44 static void
45 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
46 };
47
48 template<typename _Class, typename _Member, typename _Res,
49 typename... _ArgTypes>
50 class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
51 : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
52 {
53 typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
54 _Base;
55
56 public:
57 static _Res
58 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
59 };
60
61 template<typename _Class, typename _Member, typename... _ArgTypes>
62 class _Function_handler<void(_ArgTypes...), _Member _Class::*>
63 : public _Function_base::_Base_manager<
64 _Simple_type_wrapper< _Member _Class::* > >
65 {
66 typedef _Member _Class::* _Functor;
67 typedef _Simple_type_wrapper<_Functor> _Wrapper;
68 typedef _Function_base::_Base_manager<_Wrapper> _Base;
69
70 public:
71 static bool
72 _M_manager(_Any_data& __dest, const _Any_data& __source,
73 _Manager_operation __op);
74
75 static void
76 _M_invoke(const _Any_data& __functor, _ArgTypes... __args);
77 };
共有6個特化版本:傳回值類型為 void 、其他;函數對象類型為 std::reference_wrapper 、成員指針、其他。
繼承自 _Function_base::_Base_manager 或 _Function_base::_Ref_manager ,提供了靜态方法 _M_invoke() ,用于仿函數調用。有一個覆寫的 _M_manager() ,表面上看是一個偏特化有覆寫,實際上是兩個,因為傳回非 void 的成員指針偏特化版本還繼承了其對應 void 偏特化版本。
2.1.6 接口定義
終于回到偉大的 std::function 了,但是我們還得再看點别的:
1 template<typename _Arg, typename _Result>
2 struct unary_function
3 {
4 typedef _Arg argument_type;
5
6 typedef _Result result_type;
7 };
8
9 template<typename _Arg1, typename _Arg2, typename _Result>
10 struct binary_function
11 {
12 typedef _Arg1 first_argument_type;
13
14 typedef _Arg2 second_argument_type;
15
16 typedef _Result result_type;
17 };
std::unary_function 與 std::binary_function ,定義了一進制和二進制函數的參數類型與傳回值類型。
1 template<typename _Res, typename... _ArgTypes>
2 struct _Maybe_unary_or_binary_function { };
3
4 template<typename _Res, typename _T1>
5 struct _Maybe_unary_or_binary_function<_Res, _T1>
6 : std::unary_function<_T1, _Res> { };
7
8 template<typename _Res, typename _T1, typename _T2>
9 struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
10 : std::binary_function<_T1, _T2, _Res> { };
_Maybe_unary_or_binary_function 類,當模闆參數表示的函數為一進制或二進制時,分别繼承 std::unary_function 與 std::binary_function 。
現在可以給出 std::function 類定義與方法聲明:
1 template<typename _Signature>
2 class function;
3
4 template<typename _Res, typename... _ArgTypes>
5 class function<_Res(_ArgTypes...)>
6 : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
7 private _Function_base
8 {
9 typedef _Res _Signature_type(_ArgTypes...);
10
11 template<typename _Functor>
12 using _Invoke = decltype(__callable_functor(std::declval<_Functor&>())
13 (std::declval<_ArgTypes>()...) );
14
15 template<typename _CallRes, typename _Res1>
16 struct _CheckResult
17 : is_convertible<_CallRes, _Res1> { };
18
19 template<typename _CallRes>
20 struct _CheckResult<_CallRes, void>
21 : true_type { };
22
23 template<typename _Functor>
24 using _Callable = _CheckResult<_Invoke<_Functor>, _Res>;
25
26 template<typename _Cond, typename _Tp>
27 using _Requires = typename enable_if<_Cond::value, _Tp>::type;
28
29 public:
30 typedef _Res result_type;
31
32 function() noexcept;
33
34 function(nullptr_t) noexcept;
35
36 function(const function& __x);
37
38 function(function&& __x);
39
40 // TODO: needs allocator_arg_t
41
42 template<typename _Functor,
43 typename = _Requires<_Callable<_Functor>, void>>
44 function(_Functor);
45
46 function&
47 operator=(const function& __x);
48
49 function&
50 operator=(function&& __x);
51
52 function&
53 operator=(nullptr_t);
54
55 template<typename _Functor>
56 _Requires<_Callable<_Functor>, function&>
57 operator=(_Functor&& __f);
58
59 template<typename _Functor>
60 function&
61 operator=(reference_wrapper<_Functor> __f) noexcept;
62 void swap(function& __x);
63
64 // TODO: needs allocator_arg_t
65 /*
66 template<typename _Functor, typename _Alloc>
67 void
68 assign(_Functor&& __f, const _Alloc& __a);
69 */
70
71 explicit operator bool() const noexcept;
72
73 _Res operator()(_ArgTypes... __args) const;
74
75 #ifdef __GXX_RTTI
76 const type_info& target_type() const noexcept;
77
78 template<typename _Functor> _Functor* target() noexcept;
79
80 template<typename _Functor> const _Functor* target() const noexcept;
81 #endif
82
83 private:
84 typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
85 _Invoker_type _M_invoker;
86 };
87
88 template<typename _Res, typename... _Args>
89 inline bool
90 operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept;
91
92 template<typename _Res, typename... _Args>
93 inline bool
94 operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept;
95
96 template<typename _Res, typename... _Args>
97 inline bool
98 operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept;
99
100 template<typename _Res, typename... _Args>
101 inline bool
102 operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept;
103
104 template<typename _Res, typename... _Args>
105 inline void
106 swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y);
前面說過,std::function 類的模闆參數是一個函數類型。一個函數類型也是一個類型;std::function 隻在模闆參數是函數類型時才有意義;是以,有用的 std::function 是一個特化的模闆,需要一個聲明。标準庫規定沒有特化的聲明是沒有定義的。
std::function 繼承自兩個類:公有繼承模闆類 _Maybe_unary_or_binary_function ,私有繼承非模闆類 _Function_base 。
前者是公有繼承,但實際上沒有繼承虛函數,不屬于接口繼承,而是實作繼承,繼承的是基類定義的類型别名。因為這些類型别名是面向客戶的,是以必須公有繼承。這個繼承使 std::function 在不同數量的模闆參數的執行個體化下定義不同的類型别名。繼承是實作這種功能的唯一方法,SFINAE不行。(這是本文第一次出現SFINAE這個詞,我預設你看得懂。這是泛型程式設計中的常用技巧,如果不會請參考這篇文章或Google。)
後者是私有繼承,也屬于實作繼承,繼承了基類的兩個資料域與幾個靜态方法。
_Signature_type 是一個類型别名,就是模闆參數,是一個函數類型。
_Invoke 是一個别名模闆,就是仿函數被按參數類型調用的傳回類型。如果不能調用,根據SFINAE,S錯誤不會E,但這個别名隻有一個定義,在使用的地方所有S都E了,編譯器還是會給E。
_CheckResult 是一個trait類,檢測第一個模闆參數能否轉換為第二個。另有第二個參數為 void 的偏特化,在類型檢測上使傳回類型為 void 的 std::function 對象能支援任何傳回值的函數對象。
_Callable 也是一個trait類,利用上面兩個定義檢測仿函數類型與 std::function 模闆參數是否比對。
_Requires 是一個有趣的别名模闆,如果模闆參數中第一個value trait為 true ,則定義為第二個模闆參數,否則未定義(是沒有,不是 void ),使用時将交給SFINAE處理。它大緻上實作了C++20中 require 關鍵字的功能。實際上concept在2005年就有proposal了,一路從C++0x拖到C++20。我計劃在C++20标準正式釋出之前寫一篇文章完整介紹concept。
result_type 是模闆參數函數類型的傳回值類型,與基類中定義的相同。
在類定義最後的私有段,還定義了一個函數指針類型以及該類型的一個對象,這是第二個函數指針。
其餘的各種函數,在1.4節都介紹過了。
2.1.7 類型關系
講了這麼多類型,你記住它們之間的關系了嗎?我們再來自頂向下地梳理一遍。
一個 std::function 對象中包含一個函數指針,它會被初始化為 _Function_handler 類中的靜态函數的指針。std::function 與 _Function_handler 類之間,可以認為是組合關系。
std::function 繼承自 _Maybe_unary_or_binary_function 與 _Function_base ,兩者都是實作繼承。
_Function_base 中有 _Base_manager 與 _Ref_manager 兩個嵌套類型,其中後者還繼承了前者,并覆寫了幾個方法。兩個類定義了一系列靜态方法,繼承隻是為了避免代碼重複。
_Function_base 含有兩個資料域,一個是函數指針,_Function_base 與兩個嵌套類型之間既是嵌套又是組合;另一個是 _Any_data 類型對象,_Function_base 與 _Any_data 之間是組合關系。
而 _Any_data 是一個聯合體,是兩部分相同大小資料的聯合,分别是 char 數組和 _Nocopy_types 類型對象,後者又是4種基本類型的聯合。
其餘的一些類與函數,都是起輔助作用的。至此,對 std::function 定義的分析就結束了。
2.2 方法的功能與實作
2.2.1 多态性的展現
之前一直講,std::function 是一個多态的函數對象包裝器,其中的難點就在于多态。什麼是多态?你能看到這裡,想必不是初學者,不知道多态是不可能的。Wikipedia對polymorphism的定義是:In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.
可以說,我們要在 std::function 中處理好多态,就是要處理好類型。類型當然不能一個個枚舉,但可以分類。這裡可以分類的有兩處:接口類型,即組成模闆參數的類型,以及實作類型,即綁定的仿函數的類型。下面,我們就從這兩個角度入手,分析 std::function 是如何實作的。
2.2.2 本地函數對象
先根據仿函數類型分類,可以在 std::function 對象内部存儲的,無需heap空間的,在這一節讨論。相關的方法有以下3個:
1 template<typename _Functor>
2 static void
3 _Function_base::_Base_manager<_Functor>::
4 _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
5 { new (__functor._M_access()) _Functor(std::move(__f)); }
6
7 template<typename _Functor>
8 static void
9 _Function_base::_Base_manager<_Functor>::
10 _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
11 {
12 new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
13 }
14
15 template<typename _Functor>
16 static void
17 _Function_base::_Base_manager<_Functor>::
18 _M_destroy(_Any_data& __victim, true_type)
19 {
20 __victim._M_access<_Functor>().~_Functor();
21 }
_M_init_functor 用于初始化對象,在空白區域上用placement new 移動構造了函數對象。
_M_clone 用于複制對象,在目标的空白區域上用placement new 拷貝構造和函數對象。
_M_destroy 用于銷毀對象,對函數對象顯式調用了析構函數。
2.2.3 heap函數對象
然後來看函數對象存儲在heap上的情況:
1 template<typename _Functor>
2 static void
3 _Function_base::_Base_manager<_Functor>::
4 _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
5 { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
6
7 template<typename _Functor>
8 static void
9 _Function_base::_Base_manager<_Functor>::
10 _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
11 {
12 __dest._M_access<_Functor*>() =
13 new _Functor(*__source._M_access<_Functor*>());
14 }
15
16 template<typename _Functor>
17 static void
18 _Function_base::_Base_manager<_Functor>::
19 _M_destroy(_Any_data& __victim, false_type)
20 {
21 delete __victim._M_access<_Functor*>();
22 }
_M_access<_Functor*>() 将空白區域解釋為仿函數的指針,并傳回其引用,實作了這片區域的分時複用。前兩個方法都比前一種情況多一層間接,而銷毀方法則直接調用了 delete 。
2.2.4 兩種存儲結構如何統一
盡管我們不得不分類讨論,但為了友善使用,還需要一個統一的接口。不知你有沒有注意到,上面每一個方法都有一個未命名的參數放在最後,在方法中也沒有用到。前一種情況,這個參數都是 true_type 類型,而後一種都是 false_type 類型。這個技巧稱為tag dispatching,在調用時根據類型特征确定這個位置的參數類型,進而通過重載決定調用哪一個。
1 template<typename _Functor>
2 static void
3 _Function_base::_Base_manager<_Functor>::
4 _M_init_functor(_Any_data& __functor, _Functor&& __f)
5 { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
6
7 template<typename _Functor>
8 static bool
9 _Function_base::_Base_manager<_Functor>::
10 _M_manager(_Any_data& __dest, const _Any_data& __source,
11 _Manager_operation __op)
12 {
13 switch (__op)
14 {
15 #ifdef __GXX_RTTI
16 case __get_type_info:
17 __dest._M_access<const type_info*>() = &typeid(_Functor);
18 break;
19 #endif
20 case __get_functor_ptr:
21 __dest._M_access<_Functor*>() = _M_get_pointer(__source);
22 break;
23
24 case __clone_functor:
25 _M_clone(__dest, __source, _Local_storage());
26 break;
27
28 case __destroy_functor:
29 _M_destroy(__dest, _Local_storage());
30 break;
31 }
32 return false;
33 }
這個版本的 _M_init_functor() 隻有兩個參數,加上第三個參數委托給重載版本處理,這第三個參數是一個 _Local_storage 類的對象,它根據 __stored_locally 而成為 true_type 與 false_type ,進而區分開兩個重載。
_M_manager() 方法,同樣地,利用tag dispatching把另兩組方法統一起來。它通過第三個枚舉類型參數來确定需要的操作。
但是,這個方法的傳回值是 bool ,怎麼傳出 type_info 與函數對象指針呢?它們将傳回值寫入第一個參數所指向的空間中。說起利用參數來傳遞傳回值,我就想起C中的指針、C++中的引用、RVO、Java中的包裹類型、C#中的 out 關鍵字……這裡的處理方法不僅解決了傳回值的問題,同時也使各個操作的參數統一起來。
一個值得思考的問題是為什麼不把 _M_init_functor() 也放到 _M_manager() 中去?答案是,調用 _M_init_functor() 的地方在 std::function 的模闆構造或模闆指派函數中,此時是知道仿函數類型的;而其他操作被調用時,主調函數是不知道仿函數類型的,就必須用函數指針存儲起來;為了節省空間,就引入一個枚舉類 _Manager_operation ,把幾種操作合并到一個函數中。
實際上這一層可以先不統一,就是寫兩種情況的 _M_manager ,然後到上一層再統一,但是會增加代碼量。
除此以外,還有一種簡單的方法将兩者統一:
1 template<typename _Functor>
2 static _Functor*
3 _Function_base::_Base_manager<_Functor>::
4 _M_get_pointer(const _Any_data& __source)
5 {
6 const _Functor* __ptr =
7 __stored_locally? std::__addressof(__source._M_access<_Functor>())
8 : __source._M_access<_Functor*>();
9 return const_cast<_Functor*>(__ptr);
10 }
三目運算符的條件是一個靜态常量,編譯器會優化,不浪費程式空間,也不需要在運作時判斷,效果與前一種方法相同。至于另外兩個方法(指函數)為什麼不用這種方法(指将兩種情況統一的方法),可能是為了可讀性吧。
2.2.5 根據形式區分仿函數類型
在下面一層解決了不同存儲結構的問題後,我們還要考慮幾種特殊情況。
_M_not_empty_function() 用于判斷參數是否非空,而不同類型的判定方法是不同的。這裡的解決方案很簡單,模闆方法重載即可。
1 template<typename _Functor>
2 template<typename _Signature>
3 static bool
4 _Function_base::_Base_manager<_Functor>::
5 _M_not_empty_function(const function<_Signature>& __f)
6 { return static_cast<bool>(__f); }
7
8 template<typename _Functor>
9 template<typename _Tp>
10 static bool
11 _Function_base::_Base_manager<_Functor>::
12 _M_not_empty_function(const _Tp*& __fp)
13 { return __fp; }
14
15 template<typename _Functor>
16 template<typename _Class, typename _Tp>
17 static bool
18 _Function_base::_Base_manager<_Functor>::
19 _M_not_empty_function(_Tp _Class::* const& __mp)
20 { return __mp; }
21
22 template<typename _Functor>
23 template<typename _Tp>
24 static bool
25 _Function_base::_Base_manager<_Functor>::
26 _M_not_empty_function(const _Tp&)
27 { return true; }
在調用時,普通函數對象、std::reference_wrapper 對象與成員指針的調用方法是不同的,也需要分類讨論。
1 template<typename _Res, typename _Functor, typename... _ArgTypes>
2 static _Res
3 _Function_handler<_Res(_ArgTypes...), _Functor>::
4 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
5 {
6 return (*_Base::_M_get_pointer(__functor))(
7 std::forward<_ArgTypes>(__args)...);
8 }
對于普通函數對象,函數調用沒什麼特殊的。注意自定義 operator() 必須是 const 的。
對于 std::reference_wrapper 對象,由于包裝的對象存儲為指針,是以存儲結構與普通函數對象有所不同,相應地調用也不同。
1 template<typename _Functor>
2 static void
3 _Function_base::_Ref_manager<_Functor>::
4 _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
5 {
6 _Base::_M_init_functor(__functor, std::__addressof(__f.get()));
7 }
8
9 template<typename _Functor>
10 static bool
11 _Function_base::_Ref_manager<_Functor>::
12 _M_manager(_Any_data& __dest, const _Any_data& __source,
13 _Manager_operation __op)
14 {
15 switch (__op)
16 {
17 #ifdef __GXX_RTTI
18 case __get_type_info:
19 __dest._M_access<const type_info*>() = &typeid(_Functor);
20 break;
21 #endif
22 case __get_functor_ptr:
23 __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
24 return is_const<_Functor>::value;
25 break;
26
27 default:
28 _Base::_M_manager(__dest, __source, __op);
29 }
30 return false;
31 }
32
33 template<typename _Res, typename _Functor, typename... _ArgTypes>
34 static _Res
35 _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >::
36 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
37 {
38 return __callable_functor(**_Base::_M_get_pointer(__functor))(
39 std::forward<_ArgTypes>(__args)...);
40 }
碰到兩個星号是不是有點暈?其實隻要想,一般情況下存儲函數對象的地方現在存儲指針,是以要獲得原始對象,隻需要比一般情況多一次解引用,這樣就容易了解了。
對于成員指針,情況又有一點不一樣:
1 template<typename _Class, typename _Member, typename... _ArgTypes>
2 static bool
3 _Function_handler<void(_ArgTypes...), _Member _Class::*>::
4 _M_manager(_Any_data& __dest, const _Any_data& __source,
5 _Manager_operation __op)
6 {
7 switch (__op)
8 {
9 #ifdef __GXX_RTTI
10 case __get_type_info:
11 __dest._M_access<const type_info*>() = &typeid(_Functor);
12 break;
13 #endif
14 case __get_functor_ptr:
15 __dest._M_access<_Functor*>() =
16 &_Base::_M_get_pointer(__source)->__value;
17 break;
18
19 default:
20 _Base::_M_manager(__dest, __source, __op);
21 }
22 return false;
23 }
24
25 template<typename _Class, typename _Member, typename _Res,
26 typename... _ArgTypes>
27 static _Res
28 _Function_handler<_Res(_ArgTypes...), _Member _Class::*>::
29 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
30 {
31 return std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
32 std::forward<_ArgTypes>(__args)...);
33 }
我一直說“成員指針”,而不是“成員函數指針”,是因為資料成員指針也是可以綁定的,這種情況在 std::mem_fn() 中已經處理好了。
void 傳回類型的偏特化本應接下來讨論,但之前講過,這個函數被通過繼承複用了。實際上,如果把這裡的 void 改為模闆類型,然後交換兩個 _Function_handler 偏特化的繼承關系,效果還是一樣的,是以就在這裡先讨論了。
最後一個需要區分的類型,是傳回值類型,屬于接口類型。之前都是非 void 版本,下面還有幾個 void 的偏特化:
1 template<typename _Functor, typename... _ArgTypes>
2 static void
3 _Function_handler<void(_ArgTypes...), _Functor>::
4 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
5 {
6 (*_Base::_M_get_pointer(__functor))(
7 std::forward<_ArgTypes>(__args)...);
8 }
9
10 template<typename _Functor, typename... _ArgTypes>
11 static void
12 _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >::
13 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
14 {
15 __callable_functor(**_Base::_M_get_pointer(__functor))(
16 std::forward<_ArgTypes>(__args)...);
17 }
18
19 template<typename _Class, typename _Member, typename... _ArgTypes>
20 static void
21 _Function_handler<void(_ArgTypes...), _Member _Class::*>::
22 _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
23 {
24 std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
25 std::forward<_ArgTypes>(__args)...);
26 }
void 隻是删除了 return 關鍵字的非 void 版本,是以 void 傳回類型的 std::function 對象可以綁定任何傳回值的函數對象。
2.2.6 實作組裝成接口
我們終于讨論完了各種情況,接下來讓我們來見證 std::function 的大和諧:如何用這些方法組裝成 std::function 。
1 template<typename _Res, typename... _ArgTypes>
2 function<_Res(_ArgTypes...)>::
3 function() noexcept
4 : _Function_base() { }
5
6 template<typename _Res, typename... _ArgTypes>
7 function<_Res(_ArgTypes...)>::
8 function(nullptr_t) noexcept
9 : _Function_base() { }
10
11 template<typename _Res, typename... _ArgTypes>
12 function<_Res(_ArgTypes...)>::
13 function(function&& __x) : _Function_base()
14 {
15 __x.swap(*this);
16 }
17
18 template<typename _Res, typename... _ArgTypes>
19 auto
20 function<_Res(_ArgTypes...)>::
21 operator=(const function& __x)
22 -> function&
23 {
24 function(__x).swap(*this);
25 return *this;
26 }
27
28 template<typename _Res, typename... _ArgTypes>
29 auto
30 function<_Res(_ArgTypes...)>::
31 operator=(function&& __x)
32 -> function&
33 {
34 function(std::move(__x)).swap(*this);
35 return *this;
36 }
37
38 template<typename _Res, typename... _ArgTypes>
39 auto
40 function<_Res(_ArgTypes...)>::
41 operator=(nullptr_t)
42 -> function&
43 {
44 if (_M_manager)
45 {
46 _M_manager(_M_functor, _M_functor, __destroy_functor);
47 _M_manager = 0;
48 _M_invoker = 0;
49 }
50 return *this;
51 }
52
53 template<typename _Functor>
54 auto
55 function<_Res(_ArgTypes...)>::
56 operator=(_Functor&& __f)
57 -> _Requires<_Callable<_Functor>, function&>
58 {
59 function(std::forward<_Functor>(__f)).swap(*this);
60 return *this;
61 }
62
63 template<typename _Res, typename... _ArgTypes>
64 template<typename _Functor>
65 auto
66 function<_Res(_ArgTypes...)>::
67 -> function&
68 operator=(reference_wrapper<_Functor> __f) noexcept
69 {
70 function(__f).swap(*this);
71 return *this;
72 }
73
74 template<typename _Res, typename... _ArgTypes>
75 void
76 function<_Res(_ArgTypes...)>::
77 swap(function& __x)
78 {
79 std::swap(_M_functor, __x._M_functor);
80 std::swap(_M_manager, __x._M_manager);
81 std::swap(_M_invoker, __x._M_invoker);
82 }
83
84 template<typename _Res, typename... _ArgTypes>
85 function<_Res(_ArgTypes...)>::
86 operator bool() const noexcept
87 { return !_M_empty(); }
88
89 template<typename _Res, typename... _ArgTypes>
90 function<_Res(_ArgTypes...)>::
91 function(const function& __x)
92 : _Function_base()
93 {
94 if (static_cast<bool>(__x))
95 {
96 _M_invoker = __x._M_invoker;
97 _M_manager = __x._M_manager;
98 __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
99 }
100 }
101
102 template<typename _Res, typename... _ArgTypes>
103 template<typename _Functor, typename>
104 function<_Res(_ArgTypes...)>::
105 function(_Functor __f)
106 : _Function_base()
107 {
108 typedef _Function_handler<_Signature_type, _Functor> _My_handler;
109
110 if (_My_handler::_M_not_empty_function(__f))
111 {
112 _My_handler::_M_init_functor(_M_functor, std::move(__f));
113 _M_invoker = &_My_handler::_M_invoke;
114 _M_manager = &_My_handler::_M_manager;
115 }
116 }
117
118 template<typename _Res, typename... _ArgTypes>
119 _Res
120 function<_Res(_ArgTypes...)>::
121 operator()(_ArgTypes... __args) const
122 {
123 if (_M_empty())
124 __throw_bad_function_call();
125 return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
126 }
127
128 template<typename _Res, typename... _ArgTypes>
129 const type_info&
130 function<_Res(_ArgTypes...)>::
131 target_type() const noexcept
132 {
133 if (_M_manager)
134 {
135 _Any_data __typeinfo_result;
136 _M_manager(__typeinfo_result, _M_functor, __get_type_info);
137 return *__typeinfo_result._M_access<const type_info*>();
138 }
139 else
140 return typeid(void);
141 }
142
143 template<typename _Res, typename... _ArgTypes>
144 template<typename _Functor>
145 _Functor*
146 function<_Res(_ArgTypes...)>::
147 target() noexcept
148 {
149 if (typeid(_Functor) == target_type() && _M_manager)
150 {
151 _Any_data __ptr;
152 if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
153 && !is_const<_Functor>::value)
154 return 0;
155 else
156 return __ptr._M_access<_Functor*>();
157 }
158 else
159 return 0;
160 }
161
162 template<typename _Res, typename... _ArgTypes>
163 template<typename _Functor>
164 const _Functor*
165 function<_Res(_ArgTypes...)>::
166 target() const noexcept
167 {
168 if (typeid(_Functor) == target_type() && _M_manager)
169 {
170 _Any_data __ptr;
171 _M_manager(__ptr, _M_functor, __get_functor_ptr);
172 return __ptr._M_access<const _Functor*>();
173 }
174 else
175 return 0;
176 }
177
178 template<typename _Res, typename... _Args>
179 inline bool
180 operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
181 { return !static_cast<bool>(__f); }
182
183 template<typename _Res, typename... _Args>
184 inline bool
185 operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
186 { return !static_cast<bool>(__f); }
187
188 template<typename _Res, typename... _Args>
189 inline bool
190 operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
191 { return static_cast<bool>(__f); }
192
193 template<typename _Res, typename... _Args>
194 inline bool
195 operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
196 { return static_cast<bool>(__f); }
197
198 template<typename _Res, typename... _Args>
199 inline void
200 swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y)
201 { __x.swap(__y); }
我們從 swap() 開始入手。swap() 方法隻是簡單地将三個資料成員交換了一下,這是正确的,因為它們存儲的都是POD類型。我認為,這個實作對函數對象存儲在本地的條件的限制太過嚴格,大小合适的可trivial複制的函數對象也應該可以存儲在本地。
在 swap() 的基礎上,拷貝構造、移動構造、拷貝指派、移動指派函數很自然地建構起來了,而且隻用到了 swap() 方法。這種技巧稱為copy-and-swap。這也就解釋了為什麼 std::function 需要那麼多延遲調用的操作而表示操作的枚舉類隻需要定義4種操作。
swap() 還可以成為異常安全的基礎。由于以上方法隻涉及到 swap() ,而 swap() 方法是不抛異常的,是以兩個移動函數是 noexcept 的,兩個拷貝函數也能保證在棧空間足夠時不抛異常,在抛異常時不會出現記憶體洩漏。
其餘的方法,有了前面的基礎,看代碼就能讀懂了。
後記
寫這篇文章花了好久呀。這是我第一次寫這麼長的部落格,希望你能有所收獲。如果有不懂的地方,可以在評論區留言。如果有任何錯誤,煩請指正。
我是從實作的角度來寫的這篇文章,如果你對其中的一些技巧(SFINAE、tag dispatching)不太熟悉的話,了解起來可能有點困難。相關資料[8]介紹了 function 類的設計思路,從無到有的建構過程比較容易了解。相關資料[9]分析了另一個版本的 std::function 實作,可供參考。
文章内容已經很充實了,但是沒有圖檔,不太直覺。有空我會加上圖檔的,這樣更容易了解。
另外,在我實作完自己的 function 類以後,還會對這篇文章作一點補充。自己造一遍***,總會有更深刻的感受吧。
附錄
相關資料:
[1] Naive std::function implementation
[2] How is std::function implemented?
[3] std::function - cppreference.com
[4] The space of design choices for std::function
[5] How true is “Want Speed? Pass by value”
[6] C++奇淫巧技之SFINAE
[7] What is the copy-and-swap idiom?
[8] std::function 基本實作
[9] std::function 源碼分析