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