剖析std::function接口与实现
2019-08-16 07:54:55来源:博客园 阅读 ()
剖析std::function接口与实现
目录
前言
一、std::function的原理与接口
1.1 std::function是函数包装器
1.2 C++注重运行时效率
1.3 用函数指针实现多态
1.4 std::function的接口
二、std::function的实现
2.1 类型系统
2.1.1 异常类
2.1.2 数据存储
2.1.3 辅助类
2.1.4 内存管理基类
2.1.5 仿函数调用
2.1.6 接口定义
2.1.7 类型关系
2.2 方法的功能与实现
2.2.1 多态性的体现
2.2.2 本地函数对象
2.2.3 heap函数对象
2.2.4 两种存储结构如何统一
2.2.5 根据形式区分仿函数类型
2.2.6 实现组装成接口
后记
附录
前言
为什么要剖析 std::function 呢?因为笔者最近在做一个 std::function 向单片机系统的移植与扩展。
后续还会有 std::bind 等标准库其他部分的移植。
一、std::function的原理与接口
1.1 std::function是函数包装器
std::function ,能存储任何符合模板参数的函数对象。换句话说,这些拥有一致参数类型、相同返回值类型(其实不必完全相同)的函数对象,可以由 std::function 统一包装起来。函数对象的大小是任意的、不能确定的,而C++中的类型都是固定大小的,那么,如何在一个固定大小的类型中存储任意大小的对象呢?
实际上问题还不止存储那么简单。存储了函数对象,必定是要在某一时刻调用;函数对象不是在创建的时候调用,这个特性成为延迟调用;函数对象也是对象,需要处理好构造、拷贝、移动、析构等问题——这些也需要延迟调用,但总不能再用 std::function 来解决吧?
既然 std::function 能存储不同类型的函数对象,可以说它具有多态性。C++中体现多态性的主要是虚函数,继承与多态这一套体制是可以解决这个问题的。相关资料[1] [2]中的实现利用了继承与多态,相当简洁。
1.2 C++注重运行时效率
利用继承与多态,我们可以让编译器帮我们搞定函数对象的析构。就这种实现而言,这是简洁而有效的方法。然而这种实现需要动态内存,在一些情况下不划算,甚至完全没有必要。C++11引入了lambda表达式,其本质也是函数对象。这个对象有多大呢?取决于捕获列表。你写lambda会捕获多少东西?很多情况下就只是一对方括号而已吧。在这种情况下,lambda表达式的对象大小只有1字节(因为不能是0字节),你却为了这没有内容的1字节要调用动态内存的函数?C++注重运行时效率,这种浪费是不能接受的。
如何避免这种浪费呢?你也许会说我检查传入的对象是不是1字节的空类型。且不论这个trait怎么实现,函数指针、捕获一个int的lambda等类型都声称自己是trivial的小对象,也不应该分配到heap中去。
之前说过,std::function 的大小是固定的,但是这个大小是可以自己定的。我们可以在 std::function 的类定义中加入一个空白的、大小适中的field,用在存放这些小对象,从而避免这些情况下的动态内存操作。同时,既然有了这片空间,也就不需要看传入的对象是不是1字节的空类型了。
而对于更大的类型,虽然这个field不足以存放函数对象,但足以存放一个指针,这种分时复用的结构可以用union来实现。这种小对象直接存储、大对象在heap上开辟空间并存储指针的方法,称为small object optimization。
在利用继承的实现中,函数对象被包装在一个子类中,std::function 中持有一个其父类的指针。然而为了效率,我们需要把空白field和这个指针union起来。union总给人一种底层的感觉,在不确定这个union到底存储的是什么的时候,当然不能通过其中的指针去调用虚函数。在这样的设计中,多态性不再能用继承体系实现了,我们需要另一种实现多态的方法。
1.3 用函数指针实现多态
回想一下虚函数是如何实现的?带有virtual function的类的对象中会安插vptr,这个指针指向一个vtable,这个vtable含有多个slot,里面含有指向type_info对象的指针与函数指针——对,我们需要函数指针!不知你有没有在C中实现过多态,在没有语言特性的帮助下,比较方便的方法是在struct中直接放函数指针。如果要像C++那样用上vptr和vtable,你得管理好每个类及其对应vtable的内容。你以为这种情况在C++中就有所好转吗?只有你用C++的继承体系,编译器才会帮你做这些事。想要自己建立一个从类型到vptr的映射,恐怕你得改编译器了。
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 2579functional
这个实现的原理与上面分析的大致相同,使用函数指针实现多态,也使用了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类,判断一个类型是不是“位置不变”的。从字面上来理解,一个类型如果是“位置不变”的,那么对于一个这种类型的对象,无论它复制到哪里,各个对象的底层表示都是相同的。在这个定义中,一个类型是“位置不变”的,当且仅当它是一个指针或成员指针(与一般的理解有所不同)。
1 template<typename _Tp> 2 struct _Simple_type_wrapper 3 { 4 _Simple_type_wrapper(_Tp __value) : __value(__value) { } 5 6 _Tp __value; 7 }; 8 9 template<typename _Tp> 10 struct __is_location_invariant<_Simple_type_wrapper<_Tp> > 11 : __is_location_invariant<_Tp> 12 { };
_Simple_type_wrapper ,一个简单的包装器,用于避免 void* 与指针的指针之间类型转换的 const 问题。以及 __is_location_invariant 对 _Simple_type_wrapper 的偏特化。
2.1.4 内存管理基类
类 _Function_base 定义了一系列用于管理函数对象内存的函数,这是一个非模板类:
1 class _Function_base
2 {
3 public:
4 static const std::size_t _M_max_size = sizeof(_Nocopy_types);
5 static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
6
7 template<typename _Functor>
8 class _Base_manager;
9
10 template<typename _Functor>
11 class _Ref_manager;
12
13 _Function_base() : _M_manager(0) { }
14
15 ~_Function_base()
16 {
17 if (_M_manager)
18 _M_manager(_M_functor, _M_functor, __destroy_functor);
19 }
20
21 bool _M_empty() const { return !_M_manager; }
22
23 typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
24 _Manager_operation);
25
26 _Any_data _M_functor;
27 _Manager_type _M_manager;
28 };
_Function_base 是 std::function 的实现基类,定义了两个静态常量,用于后面的trait类;两个内部类,用于包装静态方法;函数指针类型 _Manager_type 的对象 _M_manager ,用于存取 _Any_data 类型的 _M_functor 中的数据;构造函数,将函数指针置为空;析构函数,调用函数指针,销毁函数对象;_M_empty() 方法,检测内部是否存有函数对象。
我们来看其中的 _Base_manager 类:
1 template<typename _Functor> 2 class _Base_manager 3 { 4 protected: 5 static const bool __stored_locally = 6 (__is_location_invariant<_Functor>::value 7 && sizeof(_Functor) <= _M_max_size 8 && __alignof__(_Functor) <= _M_max_align 9 && (_M_max_align % __alignof__(_Functor) == 0)); 10 11 typedef integral_constant<bool, __stored_locally> _Local_storage; 12 13 static _Functor* 14 _M_get_pointer(const _Any_data& __source); 15 16 static void 17 _M_clone(_Any_data& __dest, const _Any_data& __source, true_type); 18 19 static void 20 _M_clone(_Any_data& __dest, const _Any_data& __source, false_type); 21 22 static void 23 _M_destroy(_Any_data& __victim, true_type); 24 25 static void 26 _M_destroy(_Any_data& __victim, false_type); 27 28 public: 29 static bool 30 _M_manager(_Any_data& __dest, const _Any_data& __source, 31 _Manager_operation __op); 32 33 static void 34 _M_init_functor(_Any_data& __functor, _Functor&& __f); 35 36 template<typename _Signature> 37 static bool 38 _M_not_empty_function(const function<_Signature>& __f); 39 40 template<typename _Tp> 41 static bool 42 _M_not_empty_function(const _Tp*& __fp); 43 44 template<typename _Class, typename _Tp> 45 static bool 46 _M_not_empty_function(_Tp _Class::* const& __mp); 47 48 template<typename _Tp> 49 static bool 50 _M_not_empty_function(const _Tp&); 51 52 private: 53 static void 54 _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type); 55 56 static void 57 _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type); 58 };
定义了一个静态布尔常量 __stored_locally ,它为真当且仅当 __is_location_invariant trait为真、仿函数放得下、仿函数的align符合两个要求。然后再反过来根据这个值定义trait类 _Local_storage (标准库里一般都是根据value trait来生成value)。
其余几个静态方法,顾名思义即可。有个值得思考的问题,就是为什么 _M_init_functor 是public的,没有被放进 _M_manager 呢?
再来看 _Ref_manager 类:
1 template<typename _Functor> 2 class _Ref_manager : public _Base_manager<_Functor*> 3 { 4 typedef _Function_base::_Base_manager<_Functor*> _Base; 5 6 public: 7 static bool 8 _M_manager(_Any_data& __dest, const _Any_data& __source, 9 _Manager_operation __op); 10 11 static void 12 _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f); 13 };
_Ref_manager 继承自 _Base_manager 类,覆写了两个静态方法。
2.1.5 仿函数调用
起辅助作用的模板函数 __callable_functor :
1 template<typename _Functor> 2 inline _Functor& 3 __callable_functor(_Functor& __f) 4 { return __f; } 5 6 template<typename _Member, typename _Class> 7 inline _Mem_fn<_Member _Class::*> 8 __callable_functor(_Member _Class::* &__p) 9 { return std::mem_fn(__p); } 10 11 template<typename _Member, typename _Class> 12 inline _Mem_fn<_Member _Class::*> 13 __callable_functor(_Member _Class::* const &__p) 14 { return std::mem_fn(__p); } 15 16 template<typename _Member, typename _Class> 17 inline _Mem_fn<_Member _Class::*> 18 __callable_functor(_Member _Class::* volatile &__p) 19 { return std::mem_fn(__p); } 20 21 template<typename _Member, typename _Class> 22 inline _Mem_fn<_Member _Class::*> 23 __callable_functor(_Member _Class::* const volatile &__p) 24 { return std::mem_fn(__p); }
对非成员指针类型,直接返回参数本身;对成员指针类型,返回 mem_fn() 的结果(将类对象转换为第一个参数;这个标准库函数的实现不在这篇文章中涉及),并有cv-qualified重载。它改变了调用的形式,把所有的参数都放在了小括号中。
_Function_handler 类,管理仿函数调用:
1 template<typename _Signature, typename _Functor> 2 class _Function_handler; 3 4 template<typename _Res, typename _Functor, typename... _ArgTypes> 5 class _Function_handler<_Res(_ArgTypes...), _Functor> 6 : public _Function_base::_Base_manager<_Functor> 7 { 8 typedef _Function_base::_Base_manager<_Functor> _Base; 9 10 public: 11 static _Res 12 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 13 }; 14 15 template<typename _Functor, typename... _ArgTypes> 16 class _Function_handler<void(_ArgTypes...), _Functor> 17 : public _Function_base::_Base_manager<_Functor> 18 { 19 typedef _Function_base::_Base_manager<_Functor> _Base; 20 21 public: 22 static void 23 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 24 }; 25 26 template<typename _Res, typename _Functor, typename... _ArgTypes> 27 class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> > 28 : public _Function_base::_Ref_manager<_Functor> 29 { 30 typedef _Function_base::_Ref_manager<_Functor> _Base; 31 32 public: 33 static _Res 34 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 35 }; 36 37 template<typename _Functor, typename... _ArgTypes> 38 class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> > 39 : public _Function_base::_Ref_manager<_Functor> 40 { 41 typedef _Function_base::_Ref_manager<_Functor> _Base; 42 43 public: 44 static void 45 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 46 }; 47 48 template<typename _Class, typename _Member, typename _Res, 49 typename... _ArgTypes> 50 class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> 51 : public _Function_handler<void(_ArgTypes...), _Member _Class::*> 52 { 53 typedef _Function_handler<void(_ArgTypes...), _Member _Class::*> 54 _Base; 55 56 public: 57 static _Res 58 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 59 }; 60 61 template<typename _Class, typename _Member, typename... _ArgTypes> 62 class _Function_handler<void(_ArgTypes...), _Member _Class::*> 63 : public _Function_base::_Base_manager< 64 _Simple_type_wrapper< _Member _Class::* > > 65 { 66 typedef _Member _Class::* _Functor; 67 typedef _Simple_type_wrapper<_Functor> _Wrapper; 68 typedef _Function_base::_Base_manager<_Wrapper> _Base; 69 70 public: 71 static bool 72 _M_manager(_Any_data& __dest, const _Any_data& __source, 73 _Manager_operation __op); 74 75 static void 76 _M_invoke(const _Any_data& __functor, _ArgTypes... __args); 77 };
共有6个特化版本:返回值类型为 void 、其他;函数对象类型为 std::reference_wrapper 、成员指针、其他。
继承自 _Function_base::_Base_manager 或 _Function_base::_Ref_manager ,提供了静态方法 _M_invoke() ,用于仿函数调用。有一个覆写的 _M_manager() ,表面上看是一个偏特化有覆写,实际上是两个,因为返回非 void 的成员指针偏特化版本还继承了其对应 void 偏特化版本。
2.1.6 接口定义
终于回到伟大的 std::function 了,但是我们还得再看点别的:
1 template<typename _Arg, typename _Result> 2 struct unary_function 3 { 4 typedef _Arg argument_type; 5 6 typedef _Result result_type; 7 }; 8 9 template<typename _Arg1, typename _Arg2, typename _Result> 10 struct binary_function 11 { 12 typedef _Arg1 first_argument_type; 13 14 typedef _Arg2 second_argument_type; 15 16 typedef _Result result_type; 17 };
std::unary_function 与 std::binary_function ,定义了一元和二元函数的参数类型与返回值类型。
1 template<typename _Res, typename... _ArgTypes> 2 struct _Maybe_unary_or_binary_function { }; 3 4 template<typename _Res, typename _T1> 5 struct _Maybe_unary_or_binary_function<_Res, _T1> 6 : std::unary_function<_T1, _Res> { }; 7 8 template<typename _Res, typename _T1, typename _T2> 9 struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> 10 : std::binary_function<_T1, _T2, _Res> { };
_Maybe_unary_or_binary_function 类,当模板参数表示的函数为一元或二元时,分别继承 std::unary_function 与 std::binary_function 。
现在可以给出 std::function 类定义与方法声明:
1 template<typename _Signature> 2 class function; 3 4 template<typename _Res, typename... _ArgTypes> 5 class function<_Res(_ArgTypes...)> 6 : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, 7 private _Function_base 8 { 9 typedef _Res _Signature_type(_ArgTypes...); 10 11 template<typename _Functor> 12 using _Invoke = decltype(__callable_functor(std::declval<_Functor&>()) 13 (std::declval<_ArgTypes>()...) ); 14 15 template<typename _CallRes, typename _Res1> 16 struct _CheckResult 17 : is_convertible<_CallRes, _Res1> { }; 18 19 template<typename _CallRes> 20 struct _CheckResult<_CallRes, void> 21 : true_type { }; 22 23 template<typename _Functor> 24 using _Callable = _CheckResult<_Invoke<_Functor>, _Res>; 25 26 template<typename _Cond, typename _Tp> 27 using _Requires = typename enable_if<_Cond::value, _Tp>::type; 28 29 public: 30 typedef _Res result_type; 31 32 function() noexcept; 33 34 function(nullptr_t) noexcept; 35 36 function(const function& __x); 37 38 function(function&& __x); 39 40 // TODO: needs allocator_arg_t 41 42 template<typename _Functor, 43 typename = _Requires<_Callable<_Functor>, void>> 44 function(_Functor); 45 46 function& 47 operator=(const function& __x); 48 49 function& 50 operator=(function&& __x); 51 52 function& 53 operator=(nullptr_t); 54 55 template<typename _Functor> 56 _Requires<_Callable<_Functor>, function&> 57 operator=(_Functor&& __f); 58 59 template<typename _Functor> 60 function& 61 operator=(reference_wrapper<_Functor> __f) noexcept; 62 void swap(function& __x); 63 64 // TODO: needs allocator_arg_t 65 /* 66 template<typename _Functor, typename _Alloc> 67 void 68 assign(_Functor&& __f, const _Alloc& __a); 69 */ 70 71 explicit operator bool() const noexcept; 72 73 _Res operator()(_ArgTypes... __args) const; 74 75 #ifdef __GXX_RTTI 76 const type_info& target_type() const noexcept; 77 78 template<typename _Functor> _Functor* target() noexcept; 79 80 template<typename _Functor> const _Functor* target() const noexcept; 81 #endif 82 83 private: 84 typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...); 85 _Invoker_type _M_invoker; 86 }; 87 88 template<typename _Res, typename... _Args> 89 inline bool 90 operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept; 91 92 template<typename _Res, typename... _Args> 93 inline bool 94 operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept; 95 96 template<typename _Res, typename... _Args> 97 inline bool 98 operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept; 99 100 template<typename _Res, typename... _Args> 101 inline bool 102 operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept; 103 104 template<typename _Res, typename... _Args> 105 inline void 106 swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y);
前面说过,std::function 类的模板参数是一个函数类型。一个函数类型也是一个类型;std::function 只在模板参数是函数类型时才有意义;因此,有用的 std::function 是一个特化的模板,需要一个声明。标准库规定没有特化的声明是没有定义的。
std::function 继承自两个类:公有继承模板类 _Maybe_unary_or_binary_function ,私有继承非模板类 _Function_base 。
前者是公有继承,但实际上没有继承虚函数,不属于接口继承,而是实现继承,继承的是基类定义的类型别名。因为这些类型别名是面向客户的,所以必须公有继承。这个继承使 std::function 在不同数量的模板参数的实例化下定义不同的类型别名。继承是实现这种功能的唯一方法,SFINAE不行。(这是本文第一次出现SFINAE这个词,我默认你看得懂。这是泛型编程中的常用技巧,如果不会请参考这篇文章或Google。)
后者是私有继承,也属于实现继承,继承了基类的两个数据域与几个静态方法。
_Signature_type 是一个类型别名,就是模板参数,是一个函数类型。
_Invoke 是一个别名模板,就是仿函数被按参数类型调用的返回类型。如果不能调用,根据SFINAE,S错误不会E,但这个别名只有一个定义,在使用的地方所有S都E了,编译器还是会给E。
_CheckResult 是一个trait类,检测第一个模板参数能否转换为第二个。另有第二个参数为 void 的偏特化,在类型检测上使返回类型为 void 的 std::function 对象能支持任何返回值的函数对象。
_Callable 也是一个trait类,利用上面两个定义检测仿函数类型与 std::function 模板参数是否匹配。
_Requires 是一个有趣的别名模板,如果模板参数中第一个value trait为 true ,则定义为第二个模板参数,否则未定义(是没有,不是 void ),使用时将交给SFINAE处理。它大致上实现了C++20中 require 关键字的功能。实际上concept在2005年就有proposal了,一路从C++0x拖到C++20。我计划在C++20标准正式发布之前写一篇文章完整介绍concept。
result_type 是模板参数函数类型的返回值类型,与基类中定义的相同。
在类定义最后的私有段,还定义了一个函数指针类型以及该类型的一个对象,这是第二个函数指针。
其余的各种函数,在1.4节都介绍过了。
2.1.7 类型关系
讲了这么多类型,你记住它们之间的关系了吗?我们再来自顶向下地梳理一遍。
一个 std::function 对象中包含一个函数指针,它会被初始化为 _Function_handler 类中的静态函数的指针。std::function 与 _Function_handler 类之间,可以认为是组合关系。
std::function 继承自 _Maybe_unary_or_binary_function 与 _Function_base ,两者都是实现继承。
_Function_base 中有 _Base_manager 与 _Ref_manager 两个嵌套类型,其中后者还继承了前者,并覆写了几个方法。两个类定义了一系列静态方法,继承只是为了避免代码重复。
_Function_base 含有两个数据域,一个是函数指针,_Function_base 与两个嵌套类型之间既是嵌套又是组合;另一个是 _Any_data 类型对象,_Function_base 与 _Any_data 之间是组合关系。
而 _Any_data 是一个联合体,是两部分相同大小数据的联合,分别是 char 数组和 _Nocopy_types 类型对象,后者又是4种基本类型的联合。
其余的一些类与函数,都是起辅助作用的。至此,对 std::function 定义的分析就结束了。
2.2 方法的功能与实现
2.2.1 多态性的体现
之前一直讲,std::function 是一个多态的函数对象包装器,其中的难点就在于多态。什么是多态?你能看到这里,水平肯定不低,不知道多态是不可能的。Wikipedia对polymorphism的定义是:In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.
可以说,我们要在 std::function 中处理好多态,就是要处理好类型。类型当然不能一个个枚举,但可以分类。这里可以分类的有两处:接口类型,即组成模板参数的类型,以及实现类型,即绑定的仿函数的类型。下面,我们就从这两个角度入手,分析 std::function 是如何实现的。
2.2.2 本地函数对象
先根据仿函数类型分类,可以在 std::function 对象内部存储的,无需heap空间的,在这一节讨论。相关的方法有以下3个:
1 template<typename _Functor> 2 static void 3 _Function_base::_Base_manager<_Functor>:: 4 _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type) 5 { new (__functor._M_access()) _Functor(std::move(__f)); } 6 7 template<typename _Functor> 8 static void 9 _Function_base::_Base_manager<_Functor>:: 10 _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) 11 { 12 new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); 13 } 14 15 template<typename _Functor> 16 static void 17 _Function_base::_Base_manager<_Functor>:: 18 _M_destroy(_Any_data& __victim, true_type) 19 { 20 __victim._M_access<_Functor>().~_Functor(); 21 }
_M_init_functor 用于初始化对象,在空白区域上用placement new 移动构造了函数对象。
_M_clone 用于复制对象,在目标的空白区域上用placement new 拷贝构造和函数对象。
_M_destroy 用于销毁对象,对函数对象显式调用了析构函数。
2.2.3 heap函数对象
然后来看函数对象存储在heap上的情况:
1 template<typename _Functor> 2 static void 3 _Function_base::_Base_manager<_Functor>:: 4 _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type) 5 { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); } 6 7 template<typename _Functor> 8 static void 9 _Function_base::_Base_manager<_Functor>:: 10 _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) 11 { 12 __dest._M_access<_Functor*>() = 13 new _Functor(*__source._M_access<_Functor*>()); 14 } 15 16 template<typename _Functor> 17 static void 18 _Function_base::_Base_manager<_Functor>:: 19 _M_destroy(_Any_data& __victim, false_type) 20 { 21 delete __victim._M_access<_Functor*>(); 22 }
_M_access<_Functor*>() 将空白区域解释为仿函数的指针,并返回其引用,实现了这片区域的分时复用。前两个方法都比前一种情况多一层间接,而销毁方法则直接调用了 delete 。
2.2.4 两种存储结构如何统一
尽管我们不得不分类讨论,但为了方便使用,还需要一个统一的接口。不知你有没有注意到,上面每一个方法都有一个未命名的参数放在最后,在方法中也没有用到。前一种情况,这个参数都是 true_type 类型,而后一种都是 false_type 类型。这个技巧称为tag dispatching,在调用时根据类型特征确定这个位置的参数类型,从而通过重载决定调用哪一个。
1 template<typename _Functor> 2 static void 3 _Function_base::_Base_manager<_Functor>:: 4 _M_init_functor(_Any_data& __functor, _Functor&& __f) 5 { _M_init_functor(__functor, std::move(__f), _Local_storage()); } 6 7 template<typename _Functor> 8 static bool 9 _Function_base::_Base_manager<_Functor>:: 10 _M_manager(_Any_data& __dest, const _Any_data& __source, 11 _Manager_operation __op) 12 { 13 switch (__op) 14 { 15 #ifdef __GXX_RTTI 16 case __get_type_info: 17 __dest._M_access<const type_info*>() = &typeid(_Functor); 18 break; 19 #endif 20 case __get_functor_ptr: 21 __dest._M_access<_Functor*>() = _M_get_pointer(__source); 22 break; 23 24 case __clone_functor: 25 _M_clone(__dest, __source, _Local_storage()); 26 break; 27 28 case __destroy_functor: 29 _M_destroy(__dest, _Local_storage()); 30 break; 31 } 32 return false; 33 }
这个版本的 _M_init_functor() 只有两个参数,加上第三个参数委托给重载版本处理,这第三个参数是一个 _Local_storage 类的对象,它根据 __stored_locally 而成为 true_type 与 false_type ,从而区分开两个重载。
_M_manager() 方法,同样地,利用tag dispatching把另两组方法统一起来。它通过第三个枚举类型参数来确定需要的操作。
但是,这个方法的返回值是 bool ,怎么传出 type_info 与函数对象指针呢?它们将返回值写入第一个参数所指向的空间中。说起利用参数来传递返回值,我就想起C中的指针、C++中的引用、RVO、Java中的包裹类型、C#中的 out 关键字……这里的处理方法不仅解决了返回值的问题,同时也使各个操作的参数统一起来。
一个值得思考的问题是为什么不把 _M_init_functor() 也放到 _M_manager() 中去?答案是,调用 _M_init_functor() 的地方在 std::function 的模板构造或模板赋值函数中,此时是知道仿函数类型的;而其他操作被调用时,主调函数是不知道仿函数类型的,就必须用函数指针存储起来;为了节省空间,就引入一个枚举类 _Manager_operation ,把几种操作合并到一个函数中。
实际上这一层可以先不统一,就是写两种情况的 _M_manager ,然后到上一层再统一,但是会增加代码量。
除此以外,还有一种简单的方法将两者统一:
1 template<typename _Functor> 2 static _Functor* 3 _Function_base::_Base_manager<_Functor>:: 4 _M_get_pointer(const _Any_data& __source) 5 { 6 const _Functor* __ptr = 7 __stored_locally? std::__addressof(__source._M_access<_Functor>()) 8 : __source._M_access<_Functor*>(); 9 return const_cast<_Functor*>(__ptr); 10 }
三目运算符的条件是一个静态常量,编译器会优化,不浪费程序空间,也不需要在运行时判断,效果与前一种方法相同。至于另外两个方法(指函数)为什么不用这种方法(指将两种情况统一的方法),可能是为了可读性吧。
2.2.5 根据形式区分仿函数类型
在下面一层解决了不同存储结构的问题后,我们还要考虑几种特殊情况。
_M_not_empty_function() 用于判断参数是否非空,而不同类型的判定方法是不同的。这里的解决方案很简单,模板方法重载即可。
1 template<typename _Functor> 2 template<typename _Signature> 3 static bool 4 _Function_base::_Base_manager<_Functor>:: 5 _M_not_empty_function(const function<_Signature>& __f) 6 { return static_cast<bool>(__f); } 7 8 template<typename _Functor> 9 template<typename _Tp> 10 static bool 11 _Function_base::_Base_manager<_Functor>:: 12 _M_not_empty_function(const _Tp*& __fp) 13 { return __fp; } 14 15 template<typename _Functor> 16 template<typename _Class, typename _Tp> 17 static bool 18 _Function_base::_Base_manager<_Functor>:: 19 _M_not_empty_function(_Tp _Class::* const& __mp) 20 { return __mp; } 21 22 template<typename _Functor> 23 template<typename _Tp> 24 static bool 25 _Function_base::_Base_manager<_Functor>:: 26 _M_not_empty_function(const _Tp&) 27 { return true; }
在调用时,普通函数对象、std::reference_wrapper 对象与成员指针的调用方法是不同的,也需要分类讨论。
1 template<typename _Res, typename _Functor, typename... _ArgTypes> 2 static _Res 3 _Function_handler<_Res(_ArgTypes...), _Functor>:: 4 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 5 { 6 return (*_Base::_M_get_pointer(__functor))( 7 std::forward<_ArgTypes>(__args)...); 8 }
对于普通函数对象,函数调用没什么特殊的。注意自定义 operator() 必须是 const 的。
对于 std::reference_wrapper 对象,由于包装的对象存储为指针,因此存储结构与普通函数对象有所不同,相应地调用也不同。
1 template<typename _Functor> 2 static void 3 _Function_base::_Ref_manager<_Functor>:: 4 _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) 5 { 6 _Base::_M_init_functor(__functor, std::__addressof(__f.get())); 7 } 8 9 template<typename _Functor> 10 static bool 11 _Function_base::_Ref_manager<_Functor>:: 12 _M_manager(_Any_data& __dest, const _Any_data& __source, 13 _Manager_operation __op) 14 { 15 switch (__op) 16 { 17 #ifdef __GXX_RTTI 18 case __get_type_info: 19 __dest._M_access<const type_info*>() = &typeid(_Functor); 20 break; 21 #endif 22 case __get_functor_ptr: 23 __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); 24 return is_const<_Functor>::value; 25 break; 26 27 default: 28 _Base::_M_manager(__dest, __source, __op); 29 } 30 return false; 31 } 32 33 template<typename _Res, typename _Functor, typename... _ArgTypes> 34 static _Res 35 _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >:: 36 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 37 { 38 return __callable_functor(**_Base::_M_get_pointer(__functor))( 39 std::forward<_ArgTypes>(__args)...); 40 }
碰到两个星号是不是有点晕?其实只要想,一般情况下存储函数对象的地方现在存储指针,所以要获得原始对象,只需要比一般情况多一次解引用,这样就容易理解了。
对于成员指针,情况又有一点不一样:
1 template<typename _Class, typename _Member, typename... _ArgTypes> 2 static bool 3 _Function_handler<void(_ArgTypes...), _Member _Class::*>:: 4 _M_manager(_Any_data& __dest, const _Any_data& __source, 5 _Manager_operation __op) 6 { 7 switch (__op) 8 { 9 #ifdef __GXX_RTTI 10 case __get_type_info: 11 __dest._M_access<const type_info*>() = &typeid(_Functor); 12 break; 13 #endif 14 case __get_functor_ptr: 15 __dest._M_access<_Functor*>() = 16 &_Base::_M_get_pointer(__source)->__value; 17 break; 18 19 default: 20 _Base::_M_manager(__dest, __source, __op); 21 } 22 return false; 23 } 24 25 template<typename _Class, typename _Member, typename _Res, 26 typename... _ArgTypes> 27 static _Res 28 _Function_handler<_Res(_ArgTypes...), _Member _Class::*>:: 29 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 30 { 31 return std::mem_fn(_Base::_M_get_pointer(__functor)->__value)( 32 std::forward<_ArgTypes>(__args)...); 33 }
我一直说“成员指针”,而不是“成员函数指针”,是因为数据成员指针也是可以绑定的,这种情况在 std::mem_fn() 中已经处理好了。
void 返回类型的偏特化本应接下来讨论,但之前讲过,这个函数被通过继承复用了。实际上,如果把这里的 void 改为模板类型,然后交换两个 _Function_handler 偏特化的继承关系,效果还是一样的,所以就在这里先讨论了。
最后一个需要区分的类型,是返回值类型,属于接口类型。之前都是非 void 版本,下面还有几个 void 的偏特化:
1 template<typename _Functor, typename... _ArgTypes> 2 static void 3 _Function_handler<void(_ArgTypes...), _Functor>:: 4 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 5 { 6 (*_Base::_M_get_pointer(__functor))( 7 std::forward<_ArgTypes>(__args)...); 8 } 9 10 template<typename _Functor, typename... _ArgTypes> 11 static void 12 _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >:: 13 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 14 { 15 __callable_functor(**_Base::_M_get_pointer(__functor))( 16 std::forward<_ArgTypes>(__args)...); 17 } 18 19 template<typename _Class, typename _Member, typename... _ArgTypes> 20 static void 21 _Function_handler<void(_ArgTypes...), _Member _Class::*>:: 22 _M_invoke(const _Any_data& __functor, _ArgTypes... __args) 23 { 24 std::mem_fn(_Base::_M_get_pointer(__functor)->__value)( 25 std::forward<_ArgTypes>(__args)...); 26 }
void 只是删除了 return 关键字的非 void 版本,因此 void 返回类型的 std::function 对象可以绑定任何返回值的函数对象。
2.2.6 实现组装成接口
我们终于讨论完了各种情况,接下来让我们来见证 std::function 的大和谐:如何用这些方法组装成 std::function 。
1 template<typename _Res, typename... _ArgTypes> 2 function<_Res(_ArgTypes...)>:: 3 function() noexcept 4 : _Function_base() { } 5 6 template<typename _Res, typename... _ArgTypes> 7 function<_Res(_ArgTypes...)>:: 8 function(nullptr_t) noexcept 9 : _Function_base() { } 10 11 template<typename _Res, typename... _ArgTypes> 12 function<_Res(_ArgTypes...)>:: 13 function(function&& __x) : _Function_base() 14 { 15 __x.swap(*this); 16 } 17 18 template<typename _Res, typename... _ArgTypes> 19 auto 20 function<_Res(_ArgTypes...)>:: 21 operator=(const function& __x) 22 -> function& 23 { 24 function(__x).swap(*this); 25 return *this; 26 } 27 28 template<typename _Res, typename... _ArgTypes> 29 auto 30 function<_Res(_ArgTypes...)>:: 31 operator=(function&& __x) 32 -> function& 33 { 34 function(std::move(__x)).swap(*this); 35 return *this; 36 } 37 38 template<typename _Res, typename... _ArgTypes> 39 auto 40 function<_Res(_ArgTypes...)>:: 41 operator=(nullptr_t) 42 -> function& 43 { 44 if (_M_manager) 45 { 46 _M_manager(_M_functor, _M_functor, __destroy_functor); 47 _M_manager = 0; 48 _M_invoker = 0; 49 } 50 return *this; 51 } 52 53 template<typename _Functor> 54 auto 55 function<_Res(_ArgTypes...)>:: 56 operator=(_Functor&& __f) 57 -> _Requires<_Callable<_Functor>, function&> 58 { 59 function(std::forward<_Functor>(__f)).swap(*this); 60 return *this; 61 } 62 63 template<typename _Res, typename... _ArgTypes> 64 template<typename _Functor> 65 auto 66 function<_Res(_ArgTypes...)>:: 67 -> function& 68 operator=(reference_wrapper<_Functor> __f) noexcept 69 { 70 function(__f).swap(*this); 71 return *this; 72 } 73 74 template<typename _Res, typename... _ArgTypes> 75 void 76 function<_Res(_ArgTypes...)>:: 77 swap(function& __x) 78 { 79 std::swap(_M_functor, __x._M_functor); 80 std::swap(_M_manager, __x._M_manager); 81 std::swap(_M_invoker, __x._M_invoker); 82 } 83 84 template<typename _Res, typename... _ArgTypes> 85 function<_Res(_ArgTypes...)>:: 86 operator bool() const noexcept 87 { return !_M_empty(); } 88 89 template<typename _Res, typename... _ArgTypes> 90 function<_Res(_ArgTypes...)>:: 91 function(const function& __x) 92 : _Function_base() 93 { 94 if (static_cast<bool>(__x)) 95 { 96 _M_invoker = __x._M_invoker; 97 _M_manager = __x._M_manager; 98 __x._M_manager(_M_functor, __x._M_functor, __clone_functor); 99 } 100 } 101 102 template<typename _Res, typename... _ArgTypes> 103 template<typename _Functor, typename> 104 function<_Res(_ArgTypes...)>:: 105 function(_Functor __f) 106 : _Function_base() 107 { 108 typedef _Function_handler<_Signature_type, _Functor> _My_handler; 109 110 if (_My_handler::_M_not_empty_function(__f)) 111 { 112 _My_handler::_M_init_functor(_M_functor, std::move(__f)); 113 _M_invoker = &_My_handler::_M_invoke; 114 _M_manager = &_My_handler::_M_manager; 115 } 116 } 117 118 template<typename _Res, typename... _ArgTypes> 119 _Res 120 function<_Res(_ArgTypes...)>:: 121 operator()(_ArgTypes... __args) const 122 { 123 if (_M_empty()) 124 __throw_bad_function_call(); 125 return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...); 126 } 127 128 template<typename _Res, typename... _ArgTypes> 129 const type_info& 130 function<_Res(_ArgTypes...)>:: 131 target_type() const noexcept 132 { 133 if (_M_manager) 134 { 135 _Any_data __typeinfo_result; 136 _M_manager(__typeinfo_result, _M_functor, __get_type_info); 137 return *__typeinfo_result._M_access<const type_info*>(); 138 } 139 else 140 return typeid(void); 141 } 142 143 template<typename _Res, typename... _ArgTypes> 144 template<typename _Functor> 145 _Functor* 146 function<_Res(_ArgTypes...)>:: 147 target() noexcept 148 { 149 if (typeid(_Functor) == target_type() && _M_manager) 150 { 151 _Any_data __ptr; 152 if (_M_manager(__ptr, _M_functor, __get_functor_ptr) 153 && !is_const<_Functor>::value) 154 return 0; 155 else 156 return __ptr._M_access<_Functor*>(); 157 } 158 else 159 return 0; 160 } 161 162 template<typename _Res, typename... _ArgTypes> 163 template<typename _Functor> 164 const _Functor* 165 function<_Res(_ArgTypes...)>:: 166 target() const noexcept 167 { 168 if (typeid(_Functor) == target_type() && _M_manager) 169 { 170 _Any_data __ptr; 171 _M_manager(__ptr, _M_functor, __get_functor_ptr); 172 return __ptr._M_access<const _Functor*>(); 173 } 174 else 175 return 0; 176 } 177 178 template<typename _Res, typename... _Args> 179 inline bool 180 operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept 181 { return !static_cast<bool>(__f); } 182 183 template<typename _Res, typename... _Args> 184 inline bool 185 operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept 186 { return !static_cast<bool>(__f); } 187 188 template<typename _Res, typename... _Args> 189 inline bool 190 operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept 191 { return static_cast<bool>(__f); } 192 193 template<typename _Res, typename... _Args> 194 inline bool 195 operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept 196 { return static_cast<bool>(__f); } 197 198 template<typename _Res, typename... _Args> 199 inline void 200 swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) 201 { __x.swap(__y); }
我们从 swap() 开始入手。swap() 方法只是简单地将三个数据成员交换了一下,这是正确的,因为它们存储的都是POD类型。我认为,这个实现对函数对象存储在本地的条件的限制太过严格,大小合适的可trivial复制的函数对象也应该可以存储在本地。
在 swap() 的基础上,拷贝构造、移动构造、拷贝赋值、移动赋值函数很自然地构建起来了,而且只用到了 swap() 方法。这种技巧称为copy-and-swap。这也就解释了为什么 std::function 需要那么多延迟调用的操作而表示操作的枚举类只需要定义4种操作。
swap() 还可以成为异常安全的基础。由于以上方法只涉及到 swap() ,而 swap() 方法是不抛异常的,因此两个移动函数是 noexcept 的,两个拷贝函数也能保证在栈空间足够时不抛异常,在抛异常时不会出现内存泄漏。
其余的方法,有了前面的基础,看代码就能读懂了。
后记
写这篇文章花了好久呀。这是我第一次写这么长的博客,希望你能有所收获。如果有不懂的地方,可以在评论区留言。如果有任何错误,烦请指正。
我是从实现的角度来写的这篇文章,如果你对其中的一些技巧(SFINAE、tag dispatching)不太熟悉的话,理解起来可能有点困难。相关资料[8]介绍了 function 类的设计思路,从无到有的构建过程比较容易理解。相关资料[9]分析了另一个版本的 std::function 实现,可供参考。
文章内容已经很充实了,但是没有图片,不太直观。有空我会加上图片的,这样更容易理解。
另外,在我实现完自己的 function 类以后,还会对这篇文章作一点补充。自己造一遍轮子,总会有更深刻的感受吧。
附录
相关资料:
[1] Naive std::function implementation
[2] How is std::function implemented?
[3] std::function - cppreference.com
[4] The space of design choices for std::function
[5] How true is “Want Speed? Pass by value”
[6] C++奇淫巧技之SFINAE
[7] What is the copy-and-swap idiom?
[8] std::function 基本实现
[9] std::function 源码分析
原文链接:https://www.cnblogs.com/jerry-fuyi/p/std_function_interface_implementation.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- C语言程序结构 2020-05-31
- 透彻理解C++11新特性:右值引用、std::move、std::forward 2020-04-30
- std::bind接口与实现 2020-04-05
- 单链表 2020-03-31
- 顺序算法 2020-03-31
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash