1*f8a1b7d9SAlexander Kabaev// TR1 functional header -*- C++ -*- 2*f8a1b7d9SAlexander Kabaev 3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4*f8a1b7d9SAlexander Kabaev// 5*f8a1b7d9SAlexander Kabaev// This file is part of the GNU ISO C++ Library. This library is free 6*f8a1b7d9SAlexander Kabaev// software; you can redistribute it and/or modify it under the 7*f8a1b7d9SAlexander Kabaev// terms of the GNU General Public License as published by the 8*f8a1b7d9SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option) 9*f8a1b7d9SAlexander Kabaev// any later version. 10*f8a1b7d9SAlexander Kabaev 11*f8a1b7d9SAlexander Kabaev// This library is distributed in the hope that it will be useful, 12*f8a1b7d9SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*f8a1b7d9SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*f8a1b7d9SAlexander Kabaev// GNU General Public License for more details. 15*f8a1b7d9SAlexander Kabaev 16*f8a1b7d9SAlexander Kabaev// You should have received a copy of the GNU General Public License along 17*f8a1b7d9SAlexander Kabaev// with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19*f8a1b7d9SAlexander Kabaev// USA. 20*f8a1b7d9SAlexander Kabaev 21*f8a1b7d9SAlexander Kabaev// As a special exception, you may use this file as part of a free software 22*f8a1b7d9SAlexander Kabaev// library without restriction. Specifically, if other files instantiate 23*f8a1b7d9SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile 24*f8a1b7d9SAlexander Kabaev// this file and link it with other files to produce an executable, this 25*f8a1b7d9SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by 26*f8a1b7d9SAlexander Kabaev// the GNU General Public License. This exception does not however 27*f8a1b7d9SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by 28*f8a1b7d9SAlexander Kabaev// the GNU General Public License. 29*f8a1b7d9SAlexander Kabaev 30*f8a1b7d9SAlexander Kabaev/** @file tr1/functional 31*f8a1b7d9SAlexander Kabaev * This is a TR1 C++ Library header. 32*f8a1b7d9SAlexander Kabaev */ 33*f8a1b7d9SAlexander Kabaev 34*f8a1b7d9SAlexander Kabaev#ifndef _TR1_FUNCTIONAL 35*f8a1b7d9SAlexander Kabaev#define _TR1_FUNCTIONAL 1 36*f8a1b7d9SAlexander Kabaev 37*f8a1b7d9SAlexander Kabaev#pragma GCC system_header 38*f8a1b7d9SAlexander Kabaev 39*f8a1b7d9SAlexander Kabaev#include "../functional" 40*f8a1b7d9SAlexander Kabaev#include <typeinfo> 41*f8a1b7d9SAlexander Kabaev#include <tr1/type_traits> 42*f8a1b7d9SAlexander Kabaev#include <ext/type_traits.h> 43*f8a1b7d9SAlexander Kabaev#include <cstdlib> // for std::abort 44*f8a1b7d9SAlexander Kabaev#include <tr1/tuple> 45*f8a1b7d9SAlexander Kabaev 46*f8a1b7d9SAlexander Kabaevnamespace std 47*f8a1b7d9SAlexander Kabaev{ 48*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(tr1) 49*f8a1b7d9SAlexander Kabaev 50*f8a1b7d9SAlexander Kabaev template<typename _MemberPointer> 51*f8a1b7d9SAlexander Kabaev class _Mem_fn; 52*f8a1b7d9SAlexander Kabaev 53*f8a1b7d9SAlexander Kabaev /** 54*f8a1b7d9SAlexander Kabaev * @if maint 55*f8a1b7d9SAlexander Kabaev * Actual implementation of _Has_result_type, which uses SFINAE to 56*f8a1b7d9SAlexander Kabaev * determine if the type _Tp has a publicly-accessible member type 57*f8a1b7d9SAlexander Kabaev * result_type. 58*f8a1b7d9SAlexander Kabaev * @endif 59*f8a1b7d9SAlexander Kabaev */ 60*f8a1b7d9SAlexander Kabaev template<typename _Tp> 61*f8a1b7d9SAlexander Kabaev class _Has_result_type_helper : __sfinae_types 62*f8a1b7d9SAlexander Kabaev { 63*f8a1b7d9SAlexander Kabaev template<typename _Up> 64*f8a1b7d9SAlexander Kabaev struct _Wrap_type 65*f8a1b7d9SAlexander Kabaev { }; 66*f8a1b7d9SAlexander Kabaev 67*f8a1b7d9SAlexander Kabaev template<typename _Up> 68*f8a1b7d9SAlexander Kabaev static __one __test(_Wrap_type<typename _Up::result_type>*); 69*f8a1b7d9SAlexander Kabaev 70*f8a1b7d9SAlexander Kabaev template<typename _Up> 71*f8a1b7d9SAlexander Kabaev static __two __test(...); 72*f8a1b7d9SAlexander Kabaev 73*f8a1b7d9SAlexander Kabaev public: 74*f8a1b7d9SAlexander Kabaev static const bool value = sizeof(__test<_Tp>(0)) == 1; 75*f8a1b7d9SAlexander Kabaev }; 76*f8a1b7d9SAlexander Kabaev 77*f8a1b7d9SAlexander Kabaev template<typename _Tp> 78*f8a1b7d9SAlexander Kabaev struct _Has_result_type 79*f8a1b7d9SAlexander Kabaev : integral_constant< 80*f8a1b7d9SAlexander Kabaev bool, 81*f8a1b7d9SAlexander Kabaev _Has_result_type_helper<typename remove_cv<_Tp>::type>::value> 82*f8a1b7d9SAlexander Kabaev { }; 83*f8a1b7d9SAlexander Kabaev 84*f8a1b7d9SAlexander Kabaev /** 85*f8a1b7d9SAlexander Kabaev * @if maint 86*f8a1b7d9SAlexander Kabaev * If we have found a result_type, extract it. 87*f8a1b7d9SAlexander Kabaev * @endif 88*f8a1b7d9SAlexander Kabaev */ 89*f8a1b7d9SAlexander Kabaev template<bool _Has_result_type, typename _Functor> 90*f8a1b7d9SAlexander Kabaev struct _Maybe_get_result_type 91*f8a1b7d9SAlexander Kabaev { }; 92*f8a1b7d9SAlexander Kabaev 93*f8a1b7d9SAlexander Kabaev template<typename _Functor> 94*f8a1b7d9SAlexander Kabaev struct _Maybe_get_result_type<true, _Functor> 95*f8a1b7d9SAlexander Kabaev { 96*f8a1b7d9SAlexander Kabaev typedef typename _Functor::result_type result_type; 97*f8a1b7d9SAlexander Kabaev }; 98*f8a1b7d9SAlexander Kabaev 99*f8a1b7d9SAlexander Kabaev /** 100*f8a1b7d9SAlexander Kabaev * @if maint 101*f8a1b7d9SAlexander Kabaev * Base class for any function object that has a weak result type, as 102*f8a1b7d9SAlexander Kabaev * defined in 3.3/3 of TR1. 103*f8a1b7d9SAlexander Kabaev * @endif 104*f8a1b7d9SAlexander Kabaev */ 105*f8a1b7d9SAlexander Kabaev template<typename _Functor> 106*f8a1b7d9SAlexander Kabaev struct _Weak_result_type_impl 107*f8a1b7d9SAlexander Kabaev : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> 108*f8a1b7d9SAlexander Kabaev { 109*f8a1b7d9SAlexander Kabaev }; 110*f8a1b7d9SAlexander Kabaev 111*f8a1b7d9SAlexander Kabaev /** 112*f8a1b7d9SAlexander Kabaev * @if maint 113*f8a1b7d9SAlexander Kabaev * Strip top-level cv-qualifiers from the function object and let 114*f8a1b7d9SAlexander Kabaev * _Weak_result_type_impl perform the real work. 115*f8a1b7d9SAlexander Kabaev * @endif 116*f8a1b7d9SAlexander Kabaev */ 117*f8a1b7d9SAlexander Kabaev template<typename _Functor> 118*f8a1b7d9SAlexander Kabaev struct _Weak_result_type 119*f8a1b7d9SAlexander Kabaev : _Weak_result_type_impl<typename remove_cv<_Functor>::type> 120*f8a1b7d9SAlexander Kabaev { 121*f8a1b7d9SAlexander Kabaev }; 122*f8a1b7d9SAlexander Kabaev 123*f8a1b7d9SAlexander Kabaev template<typename _Signature> 124*f8a1b7d9SAlexander Kabaev class result_of; 125*f8a1b7d9SAlexander Kabaev 126*f8a1b7d9SAlexander Kabaev /** 127*f8a1b7d9SAlexander Kabaev * @if maint 128*f8a1b7d9SAlexander Kabaev * Actual implementation of result_of. When _Has_result_type is 129*f8a1b7d9SAlexander Kabaev * true, gets its result from _Weak_result_type. Otherwise, uses 130*f8a1b7d9SAlexander Kabaev * the function object's member template result to extract the 131*f8a1b7d9SAlexander Kabaev * result type. 132*f8a1b7d9SAlexander Kabaev * @endif 133*f8a1b7d9SAlexander Kabaev */ 134*f8a1b7d9SAlexander Kabaev template<bool _Has_result_type, typename _Signature> 135*f8a1b7d9SAlexander Kabaev struct _Result_of_impl; 136*f8a1b7d9SAlexander Kabaev 137*f8a1b7d9SAlexander Kabaev // Handle member data pointers using _Mem_fn's logic 138*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class, typename _T1> 139*f8a1b7d9SAlexander Kabaev struct _Result_of_impl<false, _Res _Class::*(_T1)> 140*f8a1b7d9SAlexander Kabaev { 141*f8a1b7d9SAlexander Kabaev typedef typename _Mem_fn<_Res _Class::*> 142*f8a1b7d9SAlexander Kabaev ::template _Result_type<_T1>::type type; 143*f8a1b7d9SAlexander Kabaev }; 144*f8a1b7d9SAlexander Kabaev 145*f8a1b7d9SAlexander Kabaev /** 146*f8a1b7d9SAlexander Kabaev * @if maint 147*f8a1b7d9SAlexander Kabaev * Determines if the type _Tp derives from unary_function. 148*f8a1b7d9SAlexander Kabaev * @endif 149*f8a1b7d9SAlexander Kabaev */ 150*f8a1b7d9SAlexander Kabaev template<typename _Tp> 151*f8a1b7d9SAlexander Kabaev struct _Derives_from_unary_function : __sfinae_types 152*f8a1b7d9SAlexander Kabaev { 153*f8a1b7d9SAlexander Kabaev private: 154*f8a1b7d9SAlexander Kabaev template<typename _T1, typename _Res> 155*f8a1b7d9SAlexander Kabaev static __one __test(const volatile unary_function<_T1, _Res>*); 156*f8a1b7d9SAlexander Kabaev 157*f8a1b7d9SAlexander Kabaev // It's tempting to change "..." to const volatile void*, but 158*f8a1b7d9SAlexander Kabaev // that fails when _Tp is a function type. 159*f8a1b7d9SAlexander Kabaev static __two __test(...); 160*f8a1b7d9SAlexander Kabaev 161*f8a1b7d9SAlexander Kabaev public: 162*f8a1b7d9SAlexander Kabaev static const bool value = sizeof(__test((_Tp*)0)) == 1; 163*f8a1b7d9SAlexander Kabaev }; 164*f8a1b7d9SAlexander Kabaev 165*f8a1b7d9SAlexander Kabaev /** 166*f8a1b7d9SAlexander Kabaev * @if maint 167*f8a1b7d9SAlexander Kabaev * Determines if the type _Tp derives from binary_function. 168*f8a1b7d9SAlexander Kabaev * @endif 169*f8a1b7d9SAlexander Kabaev */ 170*f8a1b7d9SAlexander Kabaev template<typename _Tp> 171*f8a1b7d9SAlexander Kabaev struct _Derives_from_binary_function : __sfinae_types 172*f8a1b7d9SAlexander Kabaev { 173*f8a1b7d9SAlexander Kabaev private: 174*f8a1b7d9SAlexander Kabaev template<typename _T1, typename _T2, typename _Res> 175*f8a1b7d9SAlexander Kabaev static __one __test(const volatile binary_function<_T1, _T2, _Res>*); 176*f8a1b7d9SAlexander Kabaev 177*f8a1b7d9SAlexander Kabaev // It's tempting to change "..." to const volatile void*, but 178*f8a1b7d9SAlexander Kabaev // that fails when _Tp is a function type. 179*f8a1b7d9SAlexander Kabaev static __two __test(...); 180*f8a1b7d9SAlexander Kabaev 181*f8a1b7d9SAlexander Kabaev public: 182*f8a1b7d9SAlexander Kabaev static const bool value = sizeof(__test((_Tp*)0)) == 1; 183*f8a1b7d9SAlexander Kabaev }; 184*f8a1b7d9SAlexander Kabaev 185*f8a1b7d9SAlexander Kabaev /** 186*f8a1b7d9SAlexander Kabaev * @if maint 187*f8a1b7d9SAlexander Kabaev * Turns a function type into a function pointer type 188*f8a1b7d9SAlexander Kabaev * @endif 189*f8a1b7d9SAlexander Kabaev */ 190*f8a1b7d9SAlexander Kabaev template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value> 191*f8a1b7d9SAlexander Kabaev struct _Function_to_function_pointer 192*f8a1b7d9SAlexander Kabaev { 193*f8a1b7d9SAlexander Kabaev typedef _Tp type; 194*f8a1b7d9SAlexander Kabaev }; 195*f8a1b7d9SAlexander Kabaev 196*f8a1b7d9SAlexander Kabaev template<typename _Tp> 197*f8a1b7d9SAlexander Kabaev struct _Function_to_function_pointer<_Tp, true> 198*f8a1b7d9SAlexander Kabaev { 199*f8a1b7d9SAlexander Kabaev typedef _Tp* type; 200*f8a1b7d9SAlexander Kabaev }; 201*f8a1b7d9SAlexander Kabaev 202*f8a1b7d9SAlexander Kabaev /** 203*f8a1b7d9SAlexander Kabaev * @if maint 204*f8a1b7d9SAlexander Kabaev * Knowing which of unary_function and binary_function _Tp derives 205*f8a1b7d9SAlexander Kabaev * from, derives from the same and ensures that reference_wrapper 206*f8a1b7d9SAlexander Kabaev * will have a weak result type. See cases below. 207*f8a1b7d9SAlexander Kabaev * @endif 208*f8a1b7d9SAlexander Kabaev */ 209*f8a1b7d9SAlexander Kabaev template<bool _Unary, bool _Binary, typename _Tp> 210*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base_impl; 211*f8a1b7d9SAlexander Kabaev 212*f8a1b7d9SAlexander Kabaev // Not a unary_function or binary_function, so try a weak result type 213*f8a1b7d9SAlexander Kabaev template<typename _Tp> 214*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base_impl<false, false, _Tp> 215*f8a1b7d9SAlexander Kabaev : _Weak_result_type<_Tp> 216*f8a1b7d9SAlexander Kabaev { }; 217*f8a1b7d9SAlexander Kabaev 218*f8a1b7d9SAlexander Kabaev // unary_function but not binary_function 219*f8a1b7d9SAlexander Kabaev template<typename _Tp> 220*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base_impl<true, false, _Tp> 221*f8a1b7d9SAlexander Kabaev : unary_function<typename _Tp::argument_type, 222*f8a1b7d9SAlexander Kabaev typename _Tp::result_type> 223*f8a1b7d9SAlexander Kabaev { }; 224*f8a1b7d9SAlexander Kabaev 225*f8a1b7d9SAlexander Kabaev // binary_function but not unary_function 226*f8a1b7d9SAlexander Kabaev template<typename _Tp> 227*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base_impl<false, true, _Tp> 228*f8a1b7d9SAlexander Kabaev : binary_function<typename _Tp::first_argument_type, 229*f8a1b7d9SAlexander Kabaev typename _Tp::second_argument_type, 230*f8a1b7d9SAlexander Kabaev typename _Tp::result_type> 231*f8a1b7d9SAlexander Kabaev { }; 232*f8a1b7d9SAlexander Kabaev 233*f8a1b7d9SAlexander Kabaev // both unary_function and binary_function. import result_type to 234*f8a1b7d9SAlexander Kabaev // avoid conflicts. 235*f8a1b7d9SAlexander Kabaev template<typename _Tp> 236*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base_impl<true, true, _Tp> 237*f8a1b7d9SAlexander Kabaev : unary_function<typename _Tp::argument_type, 238*f8a1b7d9SAlexander Kabaev typename _Tp::result_type>, 239*f8a1b7d9SAlexander Kabaev binary_function<typename _Tp::first_argument_type, 240*f8a1b7d9SAlexander Kabaev typename _Tp::second_argument_type, 241*f8a1b7d9SAlexander Kabaev typename _Tp::result_type> 242*f8a1b7d9SAlexander Kabaev { 243*f8a1b7d9SAlexander Kabaev typedef typename _Tp::result_type result_type; 244*f8a1b7d9SAlexander Kabaev }; 245*f8a1b7d9SAlexander Kabaev 246*f8a1b7d9SAlexander Kabaev /** 247*f8a1b7d9SAlexander Kabaev * @if maint 248*f8a1b7d9SAlexander Kabaev * Derives from unary_function or binary_function when it 249*f8a1b7d9SAlexander Kabaev * can. Specializations handle all of the easy cases. The primary 250*f8a1b7d9SAlexander Kabaev * template determines what to do with a class type, which may 251*f8a1b7d9SAlexander Kabaev * derive from both unary_function and binary_function. 252*f8a1b7d9SAlexander Kabaev * @endif 253*f8a1b7d9SAlexander Kabaev */ 254*f8a1b7d9SAlexander Kabaev template<typename _Tp> 255*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base 256*f8a1b7d9SAlexander Kabaev : _Reference_wrapper_base_impl< 257*f8a1b7d9SAlexander Kabaev _Derives_from_unary_function<_Tp>::value, 258*f8a1b7d9SAlexander Kabaev _Derives_from_binary_function<_Tp>::value, 259*f8a1b7d9SAlexander Kabaev _Tp> 260*f8a1b7d9SAlexander Kabaev { }; 261*f8a1b7d9SAlexander Kabaev 262*f8a1b7d9SAlexander Kabaev // - a function type (unary) 263*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 264*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res(_T1)> 265*f8a1b7d9SAlexander Kabaev : unary_function<_T1, _Res> 266*f8a1b7d9SAlexander Kabaev { }; 267*f8a1b7d9SAlexander Kabaev 268*f8a1b7d9SAlexander Kabaev // - a function type (binary) 269*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 270*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res(_T1, _T2)> 271*f8a1b7d9SAlexander Kabaev : binary_function<_T1, _T2, _Res> 272*f8a1b7d9SAlexander Kabaev { }; 273*f8a1b7d9SAlexander Kabaev 274*f8a1b7d9SAlexander Kabaev // - a function pointer type (unary) 275*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 276*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res(*)(_T1)> 277*f8a1b7d9SAlexander Kabaev : unary_function<_T1, _Res> 278*f8a1b7d9SAlexander Kabaev { }; 279*f8a1b7d9SAlexander Kabaev 280*f8a1b7d9SAlexander Kabaev // - a function pointer type (binary) 281*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 282*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res(*)(_T1, _T2)> 283*f8a1b7d9SAlexander Kabaev : binary_function<_T1, _T2, _Res> 284*f8a1b7d9SAlexander Kabaev { }; 285*f8a1b7d9SAlexander Kabaev 286*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (unary, no qualifiers) 287*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 288*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)()> 289*f8a1b7d9SAlexander Kabaev : unary_function<_T1*, _Res> 290*f8a1b7d9SAlexander Kabaev { }; 291*f8a1b7d9SAlexander Kabaev 292*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (binary, no qualifiers) 293*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 294*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)(_T2)> 295*f8a1b7d9SAlexander Kabaev : binary_function<_T1*, _T2, _Res> 296*f8a1b7d9SAlexander Kabaev { }; 297*f8a1b7d9SAlexander Kabaev 298*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (unary, const) 299*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 300*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)() const> 301*f8a1b7d9SAlexander Kabaev : unary_function<const _T1*, _Res> 302*f8a1b7d9SAlexander Kabaev { }; 303*f8a1b7d9SAlexander Kabaev 304*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (binary, const) 305*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 306*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const> 307*f8a1b7d9SAlexander Kabaev : binary_function<const _T1*, _T2, _Res> 308*f8a1b7d9SAlexander Kabaev { }; 309*f8a1b7d9SAlexander Kabaev 310*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (unary, volatile) 311*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 312*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)() volatile> 313*f8a1b7d9SAlexander Kabaev : unary_function<volatile _T1*, _Res> 314*f8a1b7d9SAlexander Kabaev { }; 315*f8a1b7d9SAlexander Kabaev 316*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (binary, volatile) 317*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 318*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile> 319*f8a1b7d9SAlexander Kabaev : binary_function<volatile _T1*, _T2, _Res> 320*f8a1b7d9SAlexander Kabaev { }; 321*f8a1b7d9SAlexander Kabaev 322*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (unary, const volatile) 323*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1> 324*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)() const volatile> 325*f8a1b7d9SAlexander Kabaev : unary_function<const volatile _T1*, _Res> 326*f8a1b7d9SAlexander Kabaev { }; 327*f8a1b7d9SAlexander Kabaev 328*f8a1b7d9SAlexander Kabaev // - a pointer to member function type (binary, const volatile) 329*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _T1, typename _T2> 330*f8a1b7d9SAlexander Kabaev struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile> 331*f8a1b7d9SAlexander Kabaev : binary_function<const volatile _T1*, _T2, _Res> 332*f8a1b7d9SAlexander Kabaev { }; 333*f8a1b7d9SAlexander Kabaev 334*f8a1b7d9SAlexander Kabaev template<typename _Tp> 335*f8a1b7d9SAlexander Kabaev class reference_wrapper 336*f8a1b7d9SAlexander Kabaev : public _Reference_wrapper_base<typename remove_cv<_Tp>::type> 337*f8a1b7d9SAlexander Kabaev { 338*f8a1b7d9SAlexander Kabaev // If _Tp is a function type, we can't form result_of<_Tp(...)>, 339*f8a1b7d9SAlexander Kabaev // so turn it into a function pointer type. 340*f8a1b7d9SAlexander Kabaev typedef typename _Function_to_function_pointer<_Tp>::type 341*f8a1b7d9SAlexander Kabaev _M_func_type; 342*f8a1b7d9SAlexander Kabaev 343*f8a1b7d9SAlexander Kabaev _Tp* _M_data; 344*f8a1b7d9SAlexander Kabaev public: 345*f8a1b7d9SAlexander Kabaev typedef _Tp type; 346*f8a1b7d9SAlexander Kabaev explicit reference_wrapper(_Tp& __indata): _M_data(&__indata) 347*f8a1b7d9SAlexander Kabaev { } 348*f8a1b7d9SAlexander Kabaev 349*f8a1b7d9SAlexander Kabaev reference_wrapper(const reference_wrapper<_Tp>& __inref): 350*f8a1b7d9SAlexander Kabaev _M_data(__inref._M_data) 351*f8a1b7d9SAlexander Kabaev { } 352*f8a1b7d9SAlexander Kabaev 353*f8a1b7d9SAlexander Kabaev reference_wrapper& 354*f8a1b7d9SAlexander Kabaev operator=(const reference_wrapper<_Tp>& __inref) 355*f8a1b7d9SAlexander Kabaev { 356*f8a1b7d9SAlexander Kabaev _M_data = __inref._M_data; 357*f8a1b7d9SAlexander Kabaev return *this; 358*f8a1b7d9SAlexander Kabaev } 359*f8a1b7d9SAlexander Kabaev 360*f8a1b7d9SAlexander Kabaev operator _Tp&() const 361*f8a1b7d9SAlexander Kabaev { return this->get(); } 362*f8a1b7d9SAlexander Kabaev 363*f8a1b7d9SAlexander Kabaev _Tp& 364*f8a1b7d9SAlexander Kabaev get() const 365*f8a1b7d9SAlexander Kabaev { return *_M_data; } 366*f8a1b7d9SAlexander Kabaev 367*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_REPEAT_HEADER <tr1/ref_wrap_iterate.h> 368*f8a1b7d9SAlexander Kabaev#include <tr1/repeat.h> 369*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_REPEAT_HEADER 370*f8a1b7d9SAlexander Kabaev }; 371*f8a1b7d9SAlexander Kabaev 372*f8a1b7d9SAlexander Kabaev 373*f8a1b7d9SAlexander Kabaev // Denotes a reference should be taken to a variable. 374*f8a1b7d9SAlexander Kabaev template<typename _Tp> 375*f8a1b7d9SAlexander Kabaev inline reference_wrapper<_Tp> 376*f8a1b7d9SAlexander Kabaev ref(_Tp& __t) 377*f8a1b7d9SAlexander Kabaev { return reference_wrapper<_Tp>(__t); } 378*f8a1b7d9SAlexander Kabaev 379*f8a1b7d9SAlexander Kabaev // Denotes a const reference should be taken to a variable. 380*f8a1b7d9SAlexander Kabaev template<typename _Tp> 381*f8a1b7d9SAlexander Kabaev inline reference_wrapper<const _Tp> 382*f8a1b7d9SAlexander Kabaev cref(const _Tp& __t) 383*f8a1b7d9SAlexander Kabaev { return reference_wrapper<const _Tp>(__t); } 384*f8a1b7d9SAlexander Kabaev 385*f8a1b7d9SAlexander Kabaev template<typename _Tp> 386*f8a1b7d9SAlexander Kabaev inline reference_wrapper<_Tp> 387*f8a1b7d9SAlexander Kabaev ref(reference_wrapper<_Tp> __t) 388*f8a1b7d9SAlexander Kabaev { return ref(__t.get()); } 389*f8a1b7d9SAlexander Kabaev 390*f8a1b7d9SAlexander Kabaev template<typename _Tp> 391*f8a1b7d9SAlexander Kabaev inline reference_wrapper<const _Tp> 392*f8a1b7d9SAlexander Kabaev cref(reference_wrapper<_Tp> __t) 393*f8a1b7d9SAlexander Kabaev { return cref(__t.get()); } 394*f8a1b7d9SAlexander Kabaev 395*f8a1b7d9SAlexander Kabaev template<typename _Tp, bool> 396*f8a1b7d9SAlexander Kabaev struct _Mem_fn_const_or_non 397*f8a1b7d9SAlexander Kabaev { 398*f8a1b7d9SAlexander Kabaev typedef const _Tp& type; 399*f8a1b7d9SAlexander Kabaev }; 400*f8a1b7d9SAlexander Kabaev 401*f8a1b7d9SAlexander Kabaev template<typename _Tp> 402*f8a1b7d9SAlexander Kabaev struct _Mem_fn_const_or_non<_Tp, false> 403*f8a1b7d9SAlexander Kabaev { 404*f8a1b7d9SAlexander Kabaev typedef _Tp& type; 405*f8a1b7d9SAlexander Kabaev }; 406*f8a1b7d9SAlexander Kabaev 407*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class> 408*f8a1b7d9SAlexander Kabaev class _Mem_fn<_Res _Class::*> 409*f8a1b7d9SAlexander Kabaev { 410*f8a1b7d9SAlexander Kabaev // This bit of genius is due to Peter Dimov, improved slightly by 411*f8a1b7d9SAlexander Kabaev // Douglas Gregor. 412*f8a1b7d9SAlexander Kabaev template<typename _Tp> 413*f8a1b7d9SAlexander Kabaev _Res& 414*f8a1b7d9SAlexander Kabaev _M_call(_Tp& __object, _Class *) const 415*f8a1b7d9SAlexander Kabaev { return __object.*__pm; } 416*f8a1b7d9SAlexander Kabaev 417*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 418*f8a1b7d9SAlexander Kabaev _Res& 419*f8a1b7d9SAlexander Kabaev _M_call(_Tp& __object, _Up * const *) const 420*f8a1b7d9SAlexander Kabaev { return (*__object).*__pm; } 421*f8a1b7d9SAlexander Kabaev 422*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 423*f8a1b7d9SAlexander Kabaev const _Res& 424*f8a1b7d9SAlexander Kabaev _M_call(_Tp& __object, const _Up * const *) const 425*f8a1b7d9SAlexander Kabaev { return (*__object).*__pm; } 426*f8a1b7d9SAlexander Kabaev 427*f8a1b7d9SAlexander Kabaev template<typename _Tp> 428*f8a1b7d9SAlexander Kabaev const _Res& 429*f8a1b7d9SAlexander Kabaev _M_call(_Tp& __object, const _Class *) const 430*f8a1b7d9SAlexander Kabaev { return __object.*__pm; } 431*f8a1b7d9SAlexander Kabaev 432*f8a1b7d9SAlexander Kabaev template<typename _Tp> 433*f8a1b7d9SAlexander Kabaev const _Res& 434*f8a1b7d9SAlexander Kabaev _M_call(_Tp& __ptr, const volatile void*) const 435*f8a1b7d9SAlexander Kabaev { return (*__ptr).*__pm; } 436*f8a1b7d9SAlexander Kabaev 437*f8a1b7d9SAlexander Kabaev template<typename _Tp> static _Tp& __get_ref(); 438*f8a1b7d9SAlexander Kabaev 439*f8a1b7d9SAlexander Kabaev template<typename _Tp> 440*f8a1b7d9SAlexander Kabaev static __sfinae_types::__one __check_const(_Tp&, _Class*); 441*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 442*f8a1b7d9SAlexander Kabaev static __sfinae_types::__one __check_const(_Tp&, _Up * const *); 443*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Up> 444*f8a1b7d9SAlexander Kabaev static __sfinae_types::__two __check_const(_Tp&, const _Up * const *); 445*f8a1b7d9SAlexander Kabaev template<typename _Tp> 446*f8a1b7d9SAlexander Kabaev static __sfinae_types::__two __check_const(_Tp&, const _Class*); 447*f8a1b7d9SAlexander Kabaev template<typename _Tp> 448*f8a1b7d9SAlexander Kabaev static __sfinae_types::__two __check_const(_Tp&, const volatile void*); 449*f8a1b7d9SAlexander Kabaev 450*f8a1b7d9SAlexander Kabaev public: 451*f8a1b7d9SAlexander Kabaev template<typename _Tp> 452*f8a1b7d9SAlexander Kabaev struct _Result_type 453*f8a1b7d9SAlexander Kabaev : _Mem_fn_const_or_non< 454*f8a1b7d9SAlexander Kabaev _Res, 455*f8a1b7d9SAlexander Kabaev (sizeof(__sfinae_types::__two) 456*f8a1b7d9SAlexander Kabaev == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))> 457*f8a1b7d9SAlexander Kabaev { }; 458*f8a1b7d9SAlexander Kabaev 459*f8a1b7d9SAlexander Kabaev template<typename _Signature> 460*f8a1b7d9SAlexander Kabaev struct result; 461*f8a1b7d9SAlexander Kabaev 462*f8a1b7d9SAlexander Kabaev template<typename _CVMem, typename _Tp> 463*f8a1b7d9SAlexander Kabaev struct result<_CVMem(_Tp)> 464*f8a1b7d9SAlexander Kabaev : public _Result_type<_Tp> { }; 465*f8a1b7d9SAlexander Kabaev 466*f8a1b7d9SAlexander Kabaev template<typename _CVMem, typename _Tp> 467*f8a1b7d9SAlexander Kabaev struct result<_CVMem(_Tp&)> 468*f8a1b7d9SAlexander Kabaev : public _Result_type<_Tp> { }; 469*f8a1b7d9SAlexander Kabaev 470*f8a1b7d9SAlexander Kabaev explicit _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { } 471*f8a1b7d9SAlexander Kabaev 472*f8a1b7d9SAlexander Kabaev // Handle objects 473*f8a1b7d9SAlexander Kabaev _Res& operator()(_Class& __object) const 474*f8a1b7d9SAlexander Kabaev { return __object.*__pm; } 475*f8a1b7d9SAlexander Kabaev 476*f8a1b7d9SAlexander Kabaev const _Res& operator()(const _Class& __object) const 477*f8a1b7d9SAlexander Kabaev { return __object.*__pm; } 478*f8a1b7d9SAlexander Kabaev 479*f8a1b7d9SAlexander Kabaev // Handle pointers 480*f8a1b7d9SAlexander Kabaev _Res& operator()(_Class* __object) const 481*f8a1b7d9SAlexander Kabaev { return __object->*__pm; } 482*f8a1b7d9SAlexander Kabaev 483*f8a1b7d9SAlexander Kabaev const _Res& 484*f8a1b7d9SAlexander Kabaev operator()(const _Class* __object) const 485*f8a1b7d9SAlexander Kabaev { return __object->*__pm; } 486*f8a1b7d9SAlexander Kabaev 487*f8a1b7d9SAlexander Kabaev // Handle smart pointers and derived 488*f8a1b7d9SAlexander Kabaev template<typename _Tp> 489*f8a1b7d9SAlexander Kabaev typename _Result_type<_Tp>::type 490*f8a1b7d9SAlexander Kabaev operator()(_Tp& __unknown) const 491*f8a1b7d9SAlexander Kabaev { return _M_call(__unknown, &__unknown); } 492*f8a1b7d9SAlexander Kabaev 493*f8a1b7d9SAlexander Kabaev private: 494*f8a1b7d9SAlexander Kabaev _Res _Class::*__pm; 495*f8a1b7d9SAlexander Kabaev }; 496*f8a1b7d9SAlexander Kabaev 497*f8a1b7d9SAlexander Kabaev /** 498*f8a1b7d9SAlexander Kabaev * @brief Returns a function object that forwards to the member 499*f8a1b7d9SAlexander Kabaev * pointer @a pm. 500*f8a1b7d9SAlexander Kabaev */ 501*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Class> 502*f8a1b7d9SAlexander Kabaev inline _Mem_fn<_Tp _Class::*> 503*f8a1b7d9SAlexander Kabaev mem_fn(_Tp _Class::* __pm) 504*f8a1b7d9SAlexander Kabaev { 505*f8a1b7d9SAlexander Kabaev return _Mem_fn<_Tp _Class::*>(__pm); 506*f8a1b7d9SAlexander Kabaev } 507*f8a1b7d9SAlexander Kabaev 508*f8a1b7d9SAlexander Kabaev /** 509*f8a1b7d9SAlexander Kabaev * @brief Determines if the given type _Tp is a function object 510*f8a1b7d9SAlexander Kabaev * should be treated as a subexpression when evaluating calls to 511*f8a1b7d9SAlexander Kabaev * function objects returned by bind(). [TR1 3.6.1] 512*f8a1b7d9SAlexander Kabaev */ 513*f8a1b7d9SAlexander Kabaev template<typename _Tp> 514*f8a1b7d9SAlexander Kabaev struct is_bind_expression 515*f8a1b7d9SAlexander Kabaev { static const bool value = false; }; 516*f8a1b7d9SAlexander Kabaev 517*f8a1b7d9SAlexander Kabaev template<typename _Tp> 518*f8a1b7d9SAlexander Kabaev const bool is_bind_expression<_Tp>::value; 519*f8a1b7d9SAlexander Kabaev 520*f8a1b7d9SAlexander Kabaev /** 521*f8a1b7d9SAlexander Kabaev * @brief Determines if the given type _Tp is a placeholder in a 522*f8a1b7d9SAlexander Kabaev * bind() expression and, if so, which placeholder it is. [TR1 3.6.2] 523*f8a1b7d9SAlexander Kabaev */ 524*f8a1b7d9SAlexander Kabaev template<typename _Tp> 525*f8a1b7d9SAlexander Kabaev struct is_placeholder 526*f8a1b7d9SAlexander Kabaev { static const int value = 0; }; 527*f8a1b7d9SAlexander Kabaev 528*f8a1b7d9SAlexander Kabaev template<typename _Tp> 529*f8a1b7d9SAlexander Kabaev const int is_placeholder<_Tp>::value; 530*f8a1b7d9SAlexander Kabaev 531*f8a1b7d9SAlexander Kabaev /** 532*f8a1b7d9SAlexander Kabaev * @if maint 533*f8a1b7d9SAlexander Kabaev * The type of placeholder objects defined by libstdc++. 534*f8a1b7d9SAlexander Kabaev * @endif 535*f8a1b7d9SAlexander Kabaev */ 536*f8a1b7d9SAlexander Kabaev template<int _Num> struct _Placeholder { }; 537*f8a1b7d9SAlexander Kabaev 538*f8a1b7d9SAlexander Kabaev /** 539*f8a1b7d9SAlexander Kabaev * @if maint 540*f8a1b7d9SAlexander Kabaev * Partial specialization of is_placeholder that provides the placeholder 541*f8a1b7d9SAlexander Kabaev * number for the placeholder objects defined by libstdc++. 542*f8a1b7d9SAlexander Kabaev * @endif 543*f8a1b7d9SAlexander Kabaev */ 544*f8a1b7d9SAlexander Kabaev template<int _Num> 545*f8a1b7d9SAlexander Kabaev struct is_placeholder<_Placeholder<_Num> > 546*f8a1b7d9SAlexander Kabaev { static const int value = _Num; }; 547*f8a1b7d9SAlexander Kabaev 548*f8a1b7d9SAlexander Kabaev template<int _Num> 549*f8a1b7d9SAlexander Kabaev const int is_placeholder<_Placeholder<_Num> >::value; 550*f8a1b7d9SAlexander Kabaev 551*f8a1b7d9SAlexander Kabaev /** 552*f8a1b7d9SAlexander Kabaev * @if maint 553*f8a1b7d9SAlexander Kabaev * Maps an argument to bind() into an actual argument to the bound 554*f8a1b7d9SAlexander Kabaev * function object [TR1 3.6.3/5]. Only the first parameter should 555*f8a1b7d9SAlexander Kabaev * be specified: the rest are used to determine among the various 556*f8a1b7d9SAlexander Kabaev * implementations. Note that, although this class is a function 557*f8a1b7d9SAlexander Kabaev * object, isn't not entirely normal because it takes only two 558*f8a1b7d9SAlexander Kabaev * parameters regardless of the number of parameters passed to the 559*f8a1b7d9SAlexander Kabaev * bind expression. The first parameter is the bound argument and 560*f8a1b7d9SAlexander Kabaev * the second parameter is a tuple containing references to the 561*f8a1b7d9SAlexander Kabaev * rest of the arguments. 562*f8a1b7d9SAlexander Kabaev * @endif 563*f8a1b7d9SAlexander Kabaev */ 564*f8a1b7d9SAlexander Kabaev template<typename _Arg, 565*f8a1b7d9SAlexander Kabaev bool _IsBindExp = is_bind_expression<_Arg>::value, 566*f8a1b7d9SAlexander Kabaev bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> 567*f8a1b7d9SAlexander Kabaev class _Mu; 568*f8a1b7d9SAlexander Kabaev 569*f8a1b7d9SAlexander Kabaev /** 570*f8a1b7d9SAlexander Kabaev * @if maint 571*f8a1b7d9SAlexander Kabaev * If the argument is reference_wrapper<_Tp>, returns the 572*f8a1b7d9SAlexander Kabaev * underlying reference. [TR1 3.6.3/5 bullet 1] 573*f8a1b7d9SAlexander Kabaev * @endif 574*f8a1b7d9SAlexander Kabaev */ 575*f8a1b7d9SAlexander Kabaev template<typename _Tp> 576*f8a1b7d9SAlexander Kabaev class _Mu<reference_wrapper<_Tp>, false, false> 577*f8a1b7d9SAlexander Kabaev { 578*f8a1b7d9SAlexander Kabaev public: 579*f8a1b7d9SAlexander Kabaev typedef _Tp& result_type; 580*f8a1b7d9SAlexander Kabaev 581*f8a1b7d9SAlexander Kabaev /* Note: This won't actually work for const volatile 582*f8a1b7d9SAlexander Kabaev * reference_wrappers, because reference_wrapper::get() is const 583*f8a1b7d9SAlexander Kabaev * but not volatile-qualified. This might be a defect in the TR. 584*f8a1b7d9SAlexander Kabaev */ 585*f8a1b7d9SAlexander Kabaev template<typename _CVRef, typename _Tuple> 586*f8a1b7d9SAlexander Kabaev result_type 587*f8a1b7d9SAlexander Kabaev operator()(_CVRef& __arg, const _Tuple&) const volatile 588*f8a1b7d9SAlexander Kabaev { return __arg.get(); } 589*f8a1b7d9SAlexander Kabaev }; 590*f8a1b7d9SAlexander Kabaev 591*f8a1b7d9SAlexander Kabaev /** 592*f8a1b7d9SAlexander Kabaev * @if maint 593*f8a1b7d9SAlexander Kabaev * If the argument is a bind expression, we invoke the underlying 594*f8a1b7d9SAlexander Kabaev * function object with the same cv-qualifiers as we are given and 595*f8a1b7d9SAlexander Kabaev * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2] 596*f8a1b7d9SAlexander Kabaev * @endif 597*f8a1b7d9SAlexander Kabaev */ 598*f8a1b7d9SAlexander Kabaev template<typename _Arg> 599*f8a1b7d9SAlexander Kabaev class _Mu<_Arg, true, false> 600*f8a1b7d9SAlexander Kabaev { 601*f8a1b7d9SAlexander Kabaev public: 602*f8a1b7d9SAlexander Kabaev template<typename _Signature> class result; 603*f8a1b7d9SAlexander Kabaev 604*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_REPEAT_HEADER <tr1/mu_iterate.h> 605*f8a1b7d9SAlexander Kabaev# include <tr1/repeat.h> 606*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_REPEAT_HEADER 607*f8a1b7d9SAlexander Kabaev }; 608*f8a1b7d9SAlexander Kabaev 609*f8a1b7d9SAlexander Kabaev /** 610*f8a1b7d9SAlexander Kabaev * @if maint 611*f8a1b7d9SAlexander Kabaev * If the argument is a placeholder for the Nth argument, returns 612*f8a1b7d9SAlexander Kabaev * a reference to the Nth argument to the bind function object. 613*f8a1b7d9SAlexander Kabaev * [TR1 3.6.3/5 bullet 3] 614*f8a1b7d9SAlexander Kabaev * @endif 615*f8a1b7d9SAlexander Kabaev */ 616*f8a1b7d9SAlexander Kabaev template<typename _Arg> 617*f8a1b7d9SAlexander Kabaev class _Mu<_Arg, false, true> 618*f8a1b7d9SAlexander Kabaev { 619*f8a1b7d9SAlexander Kabaev public: 620*f8a1b7d9SAlexander Kabaev template<typename _Signature> class result; 621*f8a1b7d9SAlexander Kabaev 622*f8a1b7d9SAlexander Kabaev template<typename _CVMu, typename _CVArg, typename _Tuple> 623*f8a1b7d9SAlexander Kabaev class result<_CVMu(_CVArg, _Tuple)> 624*f8a1b7d9SAlexander Kabaev { 625*f8a1b7d9SAlexander Kabaev // Add a reference, if it hasn't already been done for us. 626*f8a1b7d9SAlexander Kabaev // This allows us to be a little bit sloppy in constructing 627*f8a1b7d9SAlexander Kabaev // the tuple that we pass to result_of<...>. 628*f8a1b7d9SAlexander Kabaev typedef typename tuple_element<(is_placeholder<_Arg>::value - 1), 629*f8a1b7d9SAlexander Kabaev _Tuple>::type __base_type; 630*f8a1b7d9SAlexander Kabaev 631*f8a1b7d9SAlexander Kabaev public: 632*f8a1b7d9SAlexander Kabaev typedef typename add_reference<__base_type>::type type; 633*f8a1b7d9SAlexander Kabaev }; 634*f8a1b7d9SAlexander Kabaev 635*f8a1b7d9SAlexander Kabaev template<typename _Tuple> 636*f8a1b7d9SAlexander Kabaev typename result<_Mu(_Arg, _Tuple)>::type 637*f8a1b7d9SAlexander Kabaev operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile 638*f8a1b7d9SAlexander Kabaev { 639*f8a1b7d9SAlexander Kabaev return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); 640*f8a1b7d9SAlexander Kabaev } 641*f8a1b7d9SAlexander Kabaev }; 642*f8a1b7d9SAlexander Kabaev 643*f8a1b7d9SAlexander Kabaev /** 644*f8a1b7d9SAlexander Kabaev * @if maint 645*f8a1b7d9SAlexander Kabaev * If the argument is just a value, returns a reference to that 646*f8a1b7d9SAlexander Kabaev * value. The cv-qualifiers on the reference are the same as the 647*f8a1b7d9SAlexander Kabaev * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4] 648*f8a1b7d9SAlexander Kabaev * @endif 649*f8a1b7d9SAlexander Kabaev */ 650*f8a1b7d9SAlexander Kabaev template<typename _Arg> 651*f8a1b7d9SAlexander Kabaev class _Mu<_Arg, false, false> 652*f8a1b7d9SAlexander Kabaev { 653*f8a1b7d9SAlexander Kabaev public: 654*f8a1b7d9SAlexander Kabaev template<typename _Signature> struct result; 655*f8a1b7d9SAlexander Kabaev 656*f8a1b7d9SAlexander Kabaev template<typename _CVMu, typename _CVArg, typename _Tuple> 657*f8a1b7d9SAlexander Kabaev struct result<_CVMu(_CVArg, _Tuple)> 658*f8a1b7d9SAlexander Kabaev { 659*f8a1b7d9SAlexander Kabaev typedef typename add_reference<_CVArg>::type type; 660*f8a1b7d9SAlexander Kabaev }; 661*f8a1b7d9SAlexander Kabaev 662*f8a1b7d9SAlexander Kabaev // Pick up the cv-qualifiers of the argument 663*f8a1b7d9SAlexander Kabaev template<typename _CVArg, typename _Tuple> 664*f8a1b7d9SAlexander Kabaev _CVArg& operator()(_CVArg& __arg, const _Tuple&) const volatile 665*f8a1b7d9SAlexander Kabaev { return __arg; } 666*f8a1b7d9SAlexander Kabaev }; 667*f8a1b7d9SAlexander Kabaev 668*f8a1b7d9SAlexander Kabaev /** 669*f8a1b7d9SAlexander Kabaev * @if maint 670*f8a1b7d9SAlexander Kabaev * Maps member pointers into instances of _Mem_fn but leaves all 671*f8a1b7d9SAlexander Kabaev * other function objects untouched. Used by tr1::bind(). The 672*f8a1b7d9SAlexander Kabaev * primary template handles the non--member-pointer case. 673*f8a1b7d9SAlexander Kabaev * @endif 674*f8a1b7d9SAlexander Kabaev */ 675*f8a1b7d9SAlexander Kabaev template<typename _Tp> 676*f8a1b7d9SAlexander Kabaev struct _Maybe_wrap_member_pointer 677*f8a1b7d9SAlexander Kabaev { 678*f8a1b7d9SAlexander Kabaev typedef _Tp type; 679*f8a1b7d9SAlexander Kabaev static const _Tp& __do_wrap(const _Tp& __x) { return __x; } 680*f8a1b7d9SAlexander Kabaev }; 681*f8a1b7d9SAlexander Kabaev 682*f8a1b7d9SAlexander Kabaev /** 683*f8a1b7d9SAlexander Kabaev * @if maint 684*f8a1b7d9SAlexander Kabaev * Maps member pointers into instances of _Mem_fn but leaves all 685*f8a1b7d9SAlexander Kabaev * other function objects untouched. Used by tr1::bind(). This 686*f8a1b7d9SAlexander Kabaev * partial specialization handles the member pointer case. 687*f8a1b7d9SAlexander Kabaev * @endif 688*f8a1b7d9SAlexander Kabaev */ 689*f8a1b7d9SAlexander Kabaev template<typename _Tp, typename _Class> 690*f8a1b7d9SAlexander Kabaev struct _Maybe_wrap_member_pointer<_Tp _Class::*> 691*f8a1b7d9SAlexander Kabaev { 692*f8a1b7d9SAlexander Kabaev typedef _Mem_fn<_Tp _Class::*> type; 693*f8a1b7d9SAlexander Kabaev static type __do_wrap(_Tp _Class::* __pm) { return type(__pm); } 694*f8a1b7d9SAlexander Kabaev }; 695*f8a1b7d9SAlexander Kabaev 696*f8a1b7d9SAlexander Kabaev /** 697*f8a1b7d9SAlexander Kabaev * @if maint 698*f8a1b7d9SAlexander Kabaev * Type of the function object returned from bind(). 699*f8a1b7d9SAlexander Kabaev * @endif 700*f8a1b7d9SAlexander Kabaev */ 701*f8a1b7d9SAlexander Kabaev template<typename _Signature> 702*f8a1b7d9SAlexander Kabaev struct _Bind; 703*f8a1b7d9SAlexander Kabaev 704*f8a1b7d9SAlexander Kabaev /** 705*f8a1b7d9SAlexander Kabaev * @if maint 706*f8a1b7d9SAlexander Kabaev * Type of the function object returned from bind<R>(). 707*f8a1b7d9SAlexander Kabaev * @endif 708*f8a1b7d9SAlexander Kabaev */ 709*f8a1b7d9SAlexander Kabaev template<typename _Result, typename _Signature> 710*f8a1b7d9SAlexander Kabaev struct _Bind_result; 711*f8a1b7d9SAlexander Kabaev 712*f8a1b7d9SAlexander Kabaev /** 713*f8a1b7d9SAlexander Kabaev * @if maint 714*f8a1b7d9SAlexander Kabaev * Class template _Bind is always a bind expression. 715*f8a1b7d9SAlexander Kabaev * @endif 716*f8a1b7d9SAlexander Kabaev */ 717*f8a1b7d9SAlexander Kabaev template<typename _Signature> 718*f8a1b7d9SAlexander Kabaev struct is_bind_expression<_Bind<_Signature> > 719*f8a1b7d9SAlexander Kabaev { static const bool value = true; }; 720*f8a1b7d9SAlexander Kabaev 721*f8a1b7d9SAlexander Kabaev template<typename _Signature> 722*f8a1b7d9SAlexander Kabaev const bool is_bind_expression<_Bind<_Signature> >::value; 723*f8a1b7d9SAlexander Kabaev 724*f8a1b7d9SAlexander Kabaev /** 725*f8a1b7d9SAlexander Kabaev * @if maint 726*f8a1b7d9SAlexander Kabaev * Class template _Bind_result is always a bind expression. 727*f8a1b7d9SAlexander Kabaev * @endif 728*f8a1b7d9SAlexander Kabaev */ 729*f8a1b7d9SAlexander Kabaev template<typename _Result, typename _Signature> 730*f8a1b7d9SAlexander Kabaev struct is_bind_expression<_Bind_result<_Result, _Signature> > 731*f8a1b7d9SAlexander Kabaev { static const bool value = true; }; 732*f8a1b7d9SAlexander Kabaev 733*f8a1b7d9SAlexander Kabaev template<typename _Result, typename _Signature> 734*f8a1b7d9SAlexander Kabaev const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value; 735*f8a1b7d9SAlexander Kabaev 736*f8a1b7d9SAlexander Kabaev /** 737*f8a1b7d9SAlexander Kabaev * @brief Exception class thrown when class template function's 738*f8a1b7d9SAlexander Kabaev * operator() is called with an empty target. 739*f8a1b7d9SAlexander Kabaev * 740*f8a1b7d9SAlexander Kabaev */ 741*f8a1b7d9SAlexander Kabaev class bad_function_call : public std::exception { }; 742*f8a1b7d9SAlexander Kabaev 743*f8a1b7d9SAlexander Kabaev /** 744*f8a1b7d9SAlexander Kabaev * @if maint 745*f8a1b7d9SAlexander Kabaev * The integral constant expression 0 can be converted into a 746*f8a1b7d9SAlexander Kabaev * pointer to this type. It is used by the function template to 747*f8a1b7d9SAlexander Kabaev * accept NULL pointers. 748*f8a1b7d9SAlexander Kabaev * @endif 749*f8a1b7d9SAlexander Kabaev */ 750*f8a1b7d9SAlexander Kabaev struct _M_clear_type; 751*f8a1b7d9SAlexander Kabaev 752*f8a1b7d9SAlexander Kabaev /** 753*f8a1b7d9SAlexander Kabaev * @if maint 754*f8a1b7d9SAlexander Kabaev * Trait identifying "location-invariant" types, meaning that the 755*f8a1b7d9SAlexander Kabaev * address of the object (or any of its members) will not escape. 756*f8a1b7d9SAlexander Kabaev * Also implies a trivial copy constructor and assignment operator. 757*f8a1b7d9SAlexander Kabaev * @endif 758*f8a1b7d9SAlexander Kabaev */ 759*f8a1b7d9SAlexander Kabaev template<typename _Tp> 760*f8a1b7d9SAlexander Kabaev struct __is_location_invariant 761*f8a1b7d9SAlexander Kabaev : integral_constant<bool, 762*f8a1b7d9SAlexander Kabaev (is_pointer<_Tp>::value 763*f8a1b7d9SAlexander Kabaev || is_member_pointer<_Tp>::value)> 764*f8a1b7d9SAlexander Kabaev { 765*f8a1b7d9SAlexander Kabaev }; 766*f8a1b7d9SAlexander Kabaev 767*f8a1b7d9SAlexander Kabaev class _Undefined_class; 768*f8a1b7d9SAlexander Kabaev 769*f8a1b7d9SAlexander Kabaev union _Nocopy_types 770*f8a1b7d9SAlexander Kabaev { 771*f8a1b7d9SAlexander Kabaev void* _M_object; 772*f8a1b7d9SAlexander Kabaev const void* _M_const_object; 773*f8a1b7d9SAlexander Kabaev void (*_M_function_pointer)(); 774*f8a1b7d9SAlexander Kabaev void (_Undefined_class::*_M_member_pointer)(); 775*f8a1b7d9SAlexander Kabaev }; 776*f8a1b7d9SAlexander Kabaev 777*f8a1b7d9SAlexander Kabaev union _Any_data { 778*f8a1b7d9SAlexander Kabaev void* _M_access() { return &_M_pod_data[0]; } 779*f8a1b7d9SAlexander Kabaev const void* _M_access() const { return &_M_pod_data[0]; } 780*f8a1b7d9SAlexander Kabaev 781*f8a1b7d9SAlexander Kabaev template<typename _Tp> _Tp& _M_access() 782*f8a1b7d9SAlexander Kabaev { return *static_cast<_Tp*>(_M_access()); } 783*f8a1b7d9SAlexander Kabaev 784*f8a1b7d9SAlexander Kabaev template<typename _Tp> const _Tp& _M_access() const 785*f8a1b7d9SAlexander Kabaev { return *static_cast<const _Tp*>(_M_access()); } 786*f8a1b7d9SAlexander Kabaev 787*f8a1b7d9SAlexander Kabaev _Nocopy_types _M_unused; 788*f8a1b7d9SAlexander Kabaev char _M_pod_data[sizeof(_Nocopy_types)]; 789*f8a1b7d9SAlexander Kabaev }; 790*f8a1b7d9SAlexander Kabaev 791*f8a1b7d9SAlexander Kabaev enum _Manager_operation 792*f8a1b7d9SAlexander Kabaev { 793*f8a1b7d9SAlexander Kabaev __get_type_info, 794*f8a1b7d9SAlexander Kabaev __get_functor_ptr, 795*f8a1b7d9SAlexander Kabaev __clone_functor, 796*f8a1b7d9SAlexander Kabaev __destroy_functor 797*f8a1b7d9SAlexander Kabaev }; 798*f8a1b7d9SAlexander Kabaev 799*f8a1b7d9SAlexander Kabaev /* Simple type wrapper that helps avoid annoying const problems 800*f8a1b7d9SAlexander Kabaev when casting between void pointers and pointers-to-pointers. */ 801*f8a1b7d9SAlexander Kabaev template<typename _Tp> 802*f8a1b7d9SAlexander Kabaev struct _Simple_type_wrapper 803*f8a1b7d9SAlexander Kabaev { 804*f8a1b7d9SAlexander Kabaev _Simple_type_wrapper(_Tp __value) : __value(__value) { } 805*f8a1b7d9SAlexander Kabaev 806*f8a1b7d9SAlexander Kabaev _Tp __value; 807*f8a1b7d9SAlexander Kabaev }; 808*f8a1b7d9SAlexander Kabaev 809*f8a1b7d9SAlexander Kabaev template<typename _Tp> 810*f8a1b7d9SAlexander Kabaev struct __is_location_invariant<_Simple_type_wrapper<_Tp> > 811*f8a1b7d9SAlexander Kabaev : __is_location_invariant<_Tp> 812*f8a1b7d9SAlexander Kabaev { 813*f8a1b7d9SAlexander Kabaev }; 814*f8a1b7d9SAlexander Kabaev 815*f8a1b7d9SAlexander Kabaev // Converts a reference to a function object into a callable 816*f8a1b7d9SAlexander Kabaev // function object. 817*f8a1b7d9SAlexander Kabaev template<typename _Functor> 818*f8a1b7d9SAlexander Kabaev inline _Functor& __callable_functor(_Functor& __f) { return __f; } 819*f8a1b7d9SAlexander Kabaev 820*f8a1b7d9SAlexander Kabaev template<typename _Member, typename _Class> 821*f8a1b7d9SAlexander Kabaev inline _Mem_fn<_Member _Class::*> 822*f8a1b7d9SAlexander Kabaev __callable_functor(_Member _Class::* &__p) 823*f8a1b7d9SAlexander Kabaev { return mem_fn(__p); } 824*f8a1b7d9SAlexander Kabaev 825*f8a1b7d9SAlexander Kabaev template<typename _Member, typename _Class> 826*f8a1b7d9SAlexander Kabaev inline _Mem_fn<_Member _Class::*> 827*f8a1b7d9SAlexander Kabaev __callable_functor(_Member _Class::* const &__p) 828*f8a1b7d9SAlexander Kabaev { return mem_fn(__p); } 829*f8a1b7d9SAlexander Kabaev 830*f8a1b7d9SAlexander Kabaev template<typename _Signature, typename _Functor> 831*f8a1b7d9SAlexander Kabaev class _Function_handler; 832*f8a1b7d9SAlexander Kabaev 833*f8a1b7d9SAlexander Kabaev template<typename _Signature> 834*f8a1b7d9SAlexander Kabaev class function; 835*f8a1b7d9SAlexander Kabaev 836*f8a1b7d9SAlexander Kabaev 837*f8a1b7d9SAlexander Kabaev /** 838*f8a1b7d9SAlexander Kabaev * @if maint 839*f8a1b7d9SAlexander Kabaev * Base class of all polymorphic function object wrappers. 840*f8a1b7d9SAlexander Kabaev * @endif 841*f8a1b7d9SAlexander Kabaev */ 842*f8a1b7d9SAlexander Kabaev class _Function_base 843*f8a1b7d9SAlexander Kabaev { 844*f8a1b7d9SAlexander Kabaev public: 845*f8a1b7d9SAlexander Kabaev static const std::size_t _M_max_size = sizeof(_Nocopy_types); 846*f8a1b7d9SAlexander Kabaev static const std::size_t _M_max_align = __alignof__(_Nocopy_types); 847*f8a1b7d9SAlexander Kabaev 848*f8a1b7d9SAlexander Kabaev template<typename _Functor> 849*f8a1b7d9SAlexander Kabaev class _Base_manager 850*f8a1b7d9SAlexander Kabaev { 851*f8a1b7d9SAlexander Kabaev protected: 852*f8a1b7d9SAlexander Kabaev static const bool __stored_locally = 853*f8a1b7d9SAlexander Kabaev (__is_location_invariant<_Functor>::value 854*f8a1b7d9SAlexander Kabaev && sizeof(_Functor) <= _M_max_size 855*f8a1b7d9SAlexander Kabaev && __alignof__(_Functor) <= _M_max_align 856*f8a1b7d9SAlexander Kabaev && (_M_max_align % __alignof__(_Functor) == 0)); 857*f8a1b7d9SAlexander Kabaev typedef integral_constant<bool, __stored_locally> _Local_storage; 858*f8a1b7d9SAlexander Kabaev 859*f8a1b7d9SAlexander Kabaev // Retrieve a pointer to the function object 860*f8a1b7d9SAlexander Kabaev static _Functor* _M_get_pointer(const _Any_data& __source) 861*f8a1b7d9SAlexander Kabaev { 862*f8a1b7d9SAlexander Kabaev const _Functor* __ptr = 863*f8a1b7d9SAlexander Kabaev __stored_locally? &__source._M_access<_Functor>() 864*f8a1b7d9SAlexander Kabaev /* have stored a pointer */ : __source._M_access<_Functor*>(); 865*f8a1b7d9SAlexander Kabaev return const_cast<_Functor*>(__ptr); 866*f8a1b7d9SAlexander Kabaev } 867*f8a1b7d9SAlexander Kabaev 868*f8a1b7d9SAlexander Kabaev // Clone a location-invariant function object that fits within 869*f8a1b7d9SAlexander Kabaev // an _Any_data structure. 870*f8a1b7d9SAlexander Kabaev static void 871*f8a1b7d9SAlexander Kabaev _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) 872*f8a1b7d9SAlexander Kabaev { 873*f8a1b7d9SAlexander Kabaev new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); 874*f8a1b7d9SAlexander Kabaev } 875*f8a1b7d9SAlexander Kabaev 876*f8a1b7d9SAlexander Kabaev // Clone a function object that is not location-invariant or 877*f8a1b7d9SAlexander Kabaev // that cannot fit into an _Any_data structure. 878*f8a1b7d9SAlexander Kabaev static void 879*f8a1b7d9SAlexander Kabaev _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) 880*f8a1b7d9SAlexander Kabaev { 881*f8a1b7d9SAlexander Kabaev __dest._M_access<_Functor*>() = 882*f8a1b7d9SAlexander Kabaev new _Functor(*__source._M_access<_Functor*>()); 883*f8a1b7d9SAlexander Kabaev } 884*f8a1b7d9SAlexander Kabaev 885*f8a1b7d9SAlexander Kabaev // Destroying a location-invariant object may still require 886*f8a1b7d9SAlexander Kabaev // destruction. 887*f8a1b7d9SAlexander Kabaev static void 888*f8a1b7d9SAlexander Kabaev _M_destroy(_Any_data& __victim, true_type) 889*f8a1b7d9SAlexander Kabaev { 890*f8a1b7d9SAlexander Kabaev __victim._M_access<_Functor>().~_Functor(); 891*f8a1b7d9SAlexander Kabaev } 892*f8a1b7d9SAlexander Kabaev 893*f8a1b7d9SAlexander Kabaev // Destroying an object located on the heap. 894*f8a1b7d9SAlexander Kabaev static void 895*f8a1b7d9SAlexander Kabaev _M_destroy(_Any_data& __victim, false_type) 896*f8a1b7d9SAlexander Kabaev { 897*f8a1b7d9SAlexander Kabaev delete __victim._M_access<_Functor*>(); 898*f8a1b7d9SAlexander Kabaev } 899*f8a1b7d9SAlexander Kabaev 900*f8a1b7d9SAlexander Kabaev public: 901*f8a1b7d9SAlexander Kabaev static bool 902*f8a1b7d9SAlexander Kabaev _M_manager(_Any_data& __dest, const _Any_data& __source, 903*f8a1b7d9SAlexander Kabaev _Manager_operation __op) 904*f8a1b7d9SAlexander Kabaev { 905*f8a1b7d9SAlexander Kabaev switch (__op) { 906*f8a1b7d9SAlexander Kabaev case __get_type_info: 907*f8a1b7d9SAlexander Kabaev __dest._M_access<const type_info*>() = &typeid(_Functor); 908*f8a1b7d9SAlexander Kabaev break; 909*f8a1b7d9SAlexander Kabaev 910*f8a1b7d9SAlexander Kabaev case __get_functor_ptr: 911*f8a1b7d9SAlexander Kabaev __dest._M_access<_Functor*>() = _M_get_pointer(__source); 912*f8a1b7d9SAlexander Kabaev break; 913*f8a1b7d9SAlexander Kabaev 914*f8a1b7d9SAlexander Kabaev case __clone_functor: 915*f8a1b7d9SAlexander Kabaev _M_clone(__dest, __source, _Local_storage()); 916*f8a1b7d9SAlexander Kabaev break; 917*f8a1b7d9SAlexander Kabaev 918*f8a1b7d9SAlexander Kabaev case __destroy_functor: 919*f8a1b7d9SAlexander Kabaev _M_destroy(__dest, _Local_storage()); 920*f8a1b7d9SAlexander Kabaev break; 921*f8a1b7d9SAlexander Kabaev } 922*f8a1b7d9SAlexander Kabaev return false; 923*f8a1b7d9SAlexander Kabaev } 924*f8a1b7d9SAlexander Kabaev 925*f8a1b7d9SAlexander Kabaev static void 926*f8a1b7d9SAlexander Kabaev _M_init_functor(_Any_data& __functor, const _Functor& __f) 927*f8a1b7d9SAlexander Kabaev { 928*f8a1b7d9SAlexander Kabaev _M_init_functor(__functor, __f, _Local_storage()); 929*f8a1b7d9SAlexander Kabaev } 930*f8a1b7d9SAlexander Kabaev 931*f8a1b7d9SAlexander Kabaev template<typename _Signature> 932*f8a1b7d9SAlexander Kabaev static bool 933*f8a1b7d9SAlexander Kabaev _M_not_empty_function(const function<_Signature>& __f) 934*f8a1b7d9SAlexander Kabaev { 935*f8a1b7d9SAlexander Kabaev return __f; 936*f8a1b7d9SAlexander Kabaev } 937*f8a1b7d9SAlexander Kabaev 938*f8a1b7d9SAlexander Kabaev template<typename _Tp> 939*f8a1b7d9SAlexander Kabaev static bool 940*f8a1b7d9SAlexander Kabaev _M_not_empty_function(const _Tp*& __fp) 941*f8a1b7d9SAlexander Kabaev { 942*f8a1b7d9SAlexander Kabaev return __fp; 943*f8a1b7d9SAlexander Kabaev } 944*f8a1b7d9SAlexander Kabaev 945*f8a1b7d9SAlexander Kabaev template<typename _Class, typename _Tp> 946*f8a1b7d9SAlexander Kabaev static bool 947*f8a1b7d9SAlexander Kabaev _M_not_empty_function(_Tp _Class::* const& __mp) 948*f8a1b7d9SAlexander Kabaev { 949*f8a1b7d9SAlexander Kabaev return __mp; 950*f8a1b7d9SAlexander Kabaev } 951*f8a1b7d9SAlexander Kabaev 952*f8a1b7d9SAlexander Kabaev template<typename _Tp> 953*f8a1b7d9SAlexander Kabaev static bool 954*f8a1b7d9SAlexander Kabaev _M_not_empty_function(const _Tp&) 955*f8a1b7d9SAlexander Kabaev { 956*f8a1b7d9SAlexander Kabaev return true; 957*f8a1b7d9SAlexander Kabaev } 958*f8a1b7d9SAlexander Kabaev 959*f8a1b7d9SAlexander Kabaev private: 960*f8a1b7d9SAlexander Kabaev static void 961*f8a1b7d9SAlexander Kabaev _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) 962*f8a1b7d9SAlexander Kabaev { 963*f8a1b7d9SAlexander Kabaev new (__functor._M_access()) _Functor(__f); 964*f8a1b7d9SAlexander Kabaev } 965*f8a1b7d9SAlexander Kabaev 966*f8a1b7d9SAlexander Kabaev static void 967*f8a1b7d9SAlexander Kabaev _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) 968*f8a1b7d9SAlexander Kabaev { 969*f8a1b7d9SAlexander Kabaev __functor._M_access<_Functor*>() = new _Functor(__f); 970*f8a1b7d9SAlexander Kabaev } 971*f8a1b7d9SAlexander Kabaev }; 972*f8a1b7d9SAlexander Kabaev 973*f8a1b7d9SAlexander Kabaev template<typename _Functor> 974*f8a1b7d9SAlexander Kabaev class _Ref_manager : public _Base_manager<_Functor*> 975*f8a1b7d9SAlexander Kabaev { 976*f8a1b7d9SAlexander Kabaev typedef _Function_base::_Base_manager<_Functor*> _Base; 977*f8a1b7d9SAlexander Kabaev 978*f8a1b7d9SAlexander Kabaev public: 979*f8a1b7d9SAlexander Kabaev static bool 980*f8a1b7d9SAlexander Kabaev _M_manager(_Any_data& __dest, const _Any_data& __source, 981*f8a1b7d9SAlexander Kabaev _Manager_operation __op) 982*f8a1b7d9SAlexander Kabaev { 983*f8a1b7d9SAlexander Kabaev switch (__op) { 984*f8a1b7d9SAlexander Kabaev case __get_type_info: 985*f8a1b7d9SAlexander Kabaev __dest._M_access<const type_info*>() = &typeid(_Functor); 986*f8a1b7d9SAlexander Kabaev break; 987*f8a1b7d9SAlexander Kabaev 988*f8a1b7d9SAlexander Kabaev case __get_functor_ptr: 989*f8a1b7d9SAlexander Kabaev __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); 990*f8a1b7d9SAlexander Kabaev return is_const<_Functor>::value; 991*f8a1b7d9SAlexander Kabaev break; 992*f8a1b7d9SAlexander Kabaev 993*f8a1b7d9SAlexander Kabaev default: 994*f8a1b7d9SAlexander Kabaev _Base::_M_manager(__dest, __source, __op); 995*f8a1b7d9SAlexander Kabaev } 996*f8a1b7d9SAlexander Kabaev return false; 997*f8a1b7d9SAlexander Kabaev } 998*f8a1b7d9SAlexander Kabaev 999*f8a1b7d9SAlexander Kabaev static void 1000*f8a1b7d9SAlexander Kabaev _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) 1001*f8a1b7d9SAlexander Kabaev { 1002*f8a1b7d9SAlexander Kabaev // TBD: Use address_of function instead 1003*f8a1b7d9SAlexander Kabaev _Base::_M_init_functor(__functor, &__f.get()); 1004*f8a1b7d9SAlexander Kabaev } 1005*f8a1b7d9SAlexander Kabaev }; 1006*f8a1b7d9SAlexander Kabaev 1007*f8a1b7d9SAlexander Kabaev _Function_base() : _M_manager(0) { } 1008*f8a1b7d9SAlexander Kabaev 1009*f8a1b7d9SAlexander Kabaev ~_Function_base() 1010*f8a1b7d9SAlexander Kabaev { 1011*f8a1b7d9SAlexander Kabaev if (_M_manager) 1012*f8a1b7d9SAlexander Kabaev { 1013*f8a1b7d9SAlexander Kabaev _M_manager(_M_functor, _M_functor, __destroy_functor); 1014*f8a1b7d9SAlexander Kabaev } 1015*f8a1b7d9SAlexander Kabaev } 1016*f8a1b7d9SAlexander Kabaev 1017*f8a1b7d9SAlexander Kabaev 1018*f8a1b7d9SAlexander Kabaev bool _M_empty() const { return !_M_manager; } 1019*f8a1b7d9SAlexander Kabaev 1020*f8a1b7d9SAlexander Kabaev typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, 1021*f8a1b7d9SAlexander Kabaev _Manager_operation); 1022*f8a1b7d9SAlexander Kabaev 1023*f8a1b7d9SAlexander Kabaev _Any_data _M_functor; 1024*f8a1b7d9SAlexander Kabaev _Manager_type _M_manager; 1025*f8a1b7d9SAlexander Kabaev }; 1026*f8a1b7d9SAlexander Kabaev 1027*f8a1b7d9SAlexander Kabaev // [3.7.2.7] null pointer comparisons 1028*f8a1b7d9SAlexander Kabaev 1029*f8a1b7d9SAlexander Kabaev /** 1030*f8a1b7d9SAlexander Kabaev * @brief Compares a polymorphic function object wrapper against 0 1031*f8a1b7d9SAlexander Kabaev * (the NULL pointer). 1032*f8a1b7d9SAlexander Kabaev * @returns @c true if the wrapper has no target, @c false otherwise 1033*f8a1b7d9SAlexander Kabaev * 1034*f8a1b7d9SAlexander Kabaev * This function will not throw an exception. 1035*f8a1b7d9SAlexander Kabaev */ 1036*f8a1b7d9SAlexander Kabaev template<typename _Signature> 1037*f8a1b7d9SAlexander Kabaev inline bool 1038*f8a1b7d9SAlexander Kabaev operator==(const function<_Signature>& __f, _M_clear_type*) 1039*f8a1b7d9SAlexander Kabaev { 1040*f8a1b7d9SAlexander Kabaev return !__f; 1041*f8a1b7d9SAlexander Kabaev } 1042*f8a1b7d9SAlexander Kabaev 1043*f8a1b7d9SAlexander Kabaev /** 1044*f8a1b7d9SAlexander Kabaev * @overload 1045*f8a1b7d9SAlexander Kabaev */ 1046*f8a1b7d9SAlexander Kabaev template<typename _Signature> 1047*f8a1b7d9SAlexander Kabaev inline bool 1048*f8a1b7d9SAlexander Kabaev operator==(_M_clear_type*, const function<_Signature>& __f) 1049*f8a1b7d9SAlexander Kabaev { 1050*f8a1b7d9SAlexander Kabaev return !__f; 1051*f8a1b7d9SAlexander Kabaev } 1052*f8a1b7d9SAlexander Kabaev 1053*f8a1b7d9SAlexander Kabaev /** 1054*f8a1b7d9SAlexander Kabaev * @brief Compares a polymorphic function object wrapper against 0 1055*f8a1b7d9SAlexander Kabaev * (the NULL pointer). 1056*f8a1b7d9SAlexander Kabaev * @returns @c false if the wrapper has no target, @c true otherwise 1057*f8a1b7d9SAlexander Kabaev * 1058*f8a1b7d9SAlexander Kabaev * This function will not throw an exception. 1059*f8a1b7d9SAlexander Kabaev */ 1060*f8a1b7d9SAlexander Kabaev template<typename _Signature> 1061*f8a1b7d9SAlexander Kabaev inline bool 1062*f8a1b7d9SAlexander Kabaev operator!=(const function<_Signature>& __f, _M_clear_type*) 1063*f8a1b7d9SAlexander Kabaev { 1064*f8a1b7d9SAlexander Kabaev return __f; 1065*f8a1b7d9SAlexander Kabaev } 1066*f8a1b7d9SAlexander Kabaev 1067*f8a1b7d9SAlexander Kabaev /** 1068*f8a1b7d9SAlexander Kabaev * @overload 1069*f8a1b7d9SAlexander Kabaev */ 1070*f8a1b7d9SAlexander Kabaev template<typename _Signature> 1071*f8a1b7d9SAlexander Kabaev inline bool 1072*f8a1b7d9SAlexander Kabaev operator!=(_M_clear_type*, const function<_Signature>& __f) 1073*f8a1b7d9SAlexander Kabaev { 1074*f8a1b7d9SAlexander Kabaev return __f; 1075*f8a1b7d9SAlexander Kabaev } 1076*f8a1b7d9SAlexander Kabaev 1077*f8a1b7d9SAlexander Kabaev // [3.7.2.8] specialized algorithms 1078*f8a1b7d9SAlexander Kabaev 1079*f8a1b7d9SAlexander Kabaev /** 1080*f8a1b7d9SAlexander Kabaev * @brief Swap the targets of two polymorphic function object wrappers. 1081*f8a1b7d9SAlexander Kabaev * 1082*f8a1b7d9SAlexander Kabaev * This function will not throw an exception. 1083*f8a1b7d9SAlexander Kabaev */ 1084*f8a1b7d9SAlexander Kabaev template<typename _Signature> 1085*f8a1b7d9SAlexander Kabaev inline void 1086*f8a1b7d9SAlexander Kabaev swap(function<_Signature>& __x, function<_Signature>& __y) 1087*f8a1b7d9SAlexander Kabaev { 1088*f8a1b7d9SAlexander Kabaev __x.swap(__y); 1089*f8a1b7d9SAlexander Kabaev } 1090*f8a1b7d9SAlexander Kabaev 1091*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE 1092*f8a1b7d9SAlexander Kabaev} 1093*f8a1b7d9SAlexander Kabaev 1094*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_JOIN(X,Y) _GLIBCXX_JOIN2( X , Y ) 1095*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_JOIN2(X,Y) _GLIBCXX_JOIN3(X,Y) 1096*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_JOIN3(X,Y) X##Y 1097*f8a1b7d9SAlexander Kabaev#define _GLIBCXX_REPEAT_HEADER <tr1/functional_iterate.h> 1098*f8a1b7d9SAlexander Kabaev#include <tr1/repeat.h> 1099*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_REPEAT_HEADER 1100*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_JOIN3 1101*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_JOIN2 1102*f8a1b7d9SAlexander Kabaev#undef _GLIBCXX_JOIN 1103*f8a1b7d9SAlexander Kabaev 1104*f8a1b7d9SAlexander Kabaev#include <tr1/functional_hash.h> 1105*f8a1b7d9SAlexander Kabaev 1106*f8a1b7d9SAlexander Kabaev#endif 1107