剖析std::function接口与实现
目录
前言
为什么要剖析 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
这个实现的原理与上面分析的大致相同,使用函数指针实现多态,也使用了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?
posted on 2019-07-29 12:02 Jerry_SJTU 阅读(19761) 评论(3) 编辑 收藏 举报