This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[libstdc++ PATCH] TR1 'function' and 'mem_fn' support


The attached patch adds support for std::tr1::function and std::tr1::mem_fn to 
libstdc++. The good news is that it implements the complete specification and 
passes all of the existing libstdc++ tests (plus the two new tests) on x86 
Linux. The bad news is that it only passes when using my (unreviewed) patch 
for making member pointers work properly with function types, posted here:

 http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01627.html

It is possible to work around the bugs fixed by that patch, but it's very, 
very ugly and will require a lot of new code. As it is, any implementation of 
these facilities requires a huge amount of repetition; in this case, I've 
chosen to repeatedly include a header file, using macros to generate 
different code each time. 

In addition to the patch and changelog, I've attached the two new test cases 
(.cc files). I was unable to find a way to get them into a patch, because 
they should be placed in a directory that does not yet exist 
(libstdc++-v3/testsuite/tr1/3_function_objects, e.g.).

Comments appreciated.

 Douglas Gregor
Index: include/Makefile.am
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/Makefile.am,v
retrieving revision 1.91
diff -c -3 -p -b -r1.91 Makefile.am
*** include/Makefile.am	7 Jan 2005 19:34:43 -0000	1.91
--- include/Makefile.am	26 Jan 2005 06:51:48 -0000
*************** tr1_builddir = ./tr1
*** 230,235 ****
--- 230,236 ----
  tr1_headers = \
  	${tr1_srcdir}/array \
  	${tr1_srcdir}/functional \
+ 	${tr1_srcdir}/functional_iterate.h \
  	${tr1_srcdir}/tuple \
  	${tr1_srcdir}/utility \
  	${tr1_srcdir}/type_traits \
Index: include/Makefile.in
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/Makefile.in,v
retrieving revision 1.119
diff -c -3 -p -b -r1.119 Makefile.in
*** include/Makefile.in	7 Jan 2005 19:34:44 -0000	1.119
--- include/Makefile.in	26 Jan 2005 06:51:48 -0000
*************** tr1_builddir = ./tr1
*** 446,451 ****
--- 446,452 ----
  tr1_headers = \
  	${tr1_srcdir}/array \
  	${tr1_srcdir}/functional \
+ 	${tr1_srcdir}/functional_iterate.h \
  	${tr1_srcdir}/tuple \
  	${tr1_srcdir}/utility \
  	${tr1_srcdir}/type_traits \
Index: include/tr1/functional
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/tr1/functional,v
retrieving revision 1.1
diff -c -3 -p -b -r1.1 functional
*** include/tr1/functional	24 Nov 2004 16:04:45 -0000	1.1
--- include/tr1/functional	26 Jan 2005 06:51:49 -0000
***************
*** 26,31 ****
--- 26,34 ----
  #define _TR1_FUNCTIONAL 1
  
  #include "../functional"
+ #include <typeinfo>
+ #include <tr1/type_traits>
+ #include "../bits/cpp_type_traits.h"
  
  namespace std
  {
*************** namespace tr1
*** 78,83 ****
--- 81,1050 ----
    template<typename _Tp>
      reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t)
      { return cref(__t.get()); }
+ 
+   template<typename _MemberPointer>
+     class _Mem_fn;
+ 
+    template<typename _Tp, bool>
+      struct _Mem_fn_const_or_non
+      {
+        typedef const _Tp& type;
+      };
+ 
+     template<typename _Tp>
+       struct _Mem_fn_const_or_non<_Tp, false>
+       {
+         typedef _Tp& type;
+       };
+ 
+   template<typename _Res, typename _Class>
+   class _Mem_fn<_Res _Class::*>
+   {
+     // This bit of genius is due to Peter Dimov, improved slightly by
+     // Douglas Gregor.
+     template<typename _Tp>
+       _Res&
+       _M_call(_Tp& __object, _Class *) const
+       { return __object.*__pm; }
+ 
+     template<typename _Tp, typename _Up>
+       _Res&
+       _M_call(_Tp& __object, _Up * const *) const
+       { return (*__object).*__pm; }
+ 
+     template<typename _Tp, typename _Up>
+       const _Res&
+       _M_call(_Tp& __object, const _Up * const *) const
+       { return (*__object).*__pm; }
+ 
+     template<typename _Tp>
+       const _Res&
+       _M_call(_Tp& __object, const _Class *) const
+       { return __object.*__pm; }
+ 
+     template<typename _Tp>
+       const _Res&
+       _M_call(_Tp& __ptr, const volatile void*) const
+       { return (*__ptr).*__pm; }
+ 
+     template<typename _Tp> static _Tp& __get_ref();
+ 
+     template<typename _Tp>
+       static __sfinae_types::__one __check_const(_Tp&, _Class*);
+     template<typename _Tp, typename _Up>
+       static __sfinae_types::__one __check_const(_Tp&, _Up * const *);
+     template<typename _Tp, typename _Up>
+       static __sfinae_types::__two __check_const(_Tp&, const _Up * const *);
+     template<typename _Tp>
+       static __sfinae_types::__two __check_const(_Tp&, const _Class*);
+     template<typename _Tp>
+       static __sfinae_types::__two __check_const(_Tp&, const volatile void*);
+ 
+     template<typename _Tp>
+       struct _Result_type
+         : _Mem_fn_const_or_non<
+             _Res,
+             (sizeof(__sfinae_types::__two)
+              == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
+       { };
+ 
+   public:
+     explicit _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }
+ 
+     // Handle objects
+     _Res&       operator()(_Class& __object)       const
+     { return __object.*__pm; }
+ 
+     const _Res& operator()(const _Class& __object) const
+     { return __object.*__pm; }
+ 
+     // Handle pointers
+     _Res&       operator()(_Class* __object)       const
+     { return __object->*__pm; }
+ 
+     const _Res&
+     operator()(const _Class* __object) const
+     { return __object->*__pm; }
+ 
+     // Handle smart pointers and derived
+     template<typename _Tp>
+       typename _Result_type<_Tp>::type
+       operator()(_Tp& __unknown) const
+       { return _M_call(__unknown, &__unknown); }
+ 
+   private:
+     _Res _Class::*__pm;
+   };
+ 
+   /**
+    *  @brief Returns a function object that forwards to the member
+    *  pointer @a pm.
+    */
+   template<typename _T, typename _Class>
+     inline _Mem_fn<_T _Class::*>
+     mem_fn(_T _Class::* __pm)
+     {
+       return _Mem_fn<_T _Class::*>(__pm);
+     }
+ 
+   /**
+    *  @brief Exception class thrown when class template function's
+    *  operator() is called with an empty target.
+    *
+    */
+   class bad_function_call : public std::exception { };
+ 
+   /**
+    *  @if maint
+    *  The integral constant expression 0 can be converted into a
+    *  pointer to this type. It is used by the function template to
+    *  accept NULL pointers.
+    *  @endif
+    */
+   struct _M_clear_type;
+ 
+   /**
+    *  @if maint
+    *  Trait identifying "location-invariant" types, meaning that the
+    *  address of the object (or any of its members) will not escape.
+    *  Also implies a trivial copy constructor and assignment operator.
+    *   @endif
+    */
+   template<typename _Tp>
+     struct __is_location_invariant
+     : integral_constant<bool,
+                         (is_pointer<_Tp>::value
+                          || is_member_pointer<_Tp>::value)>
+     {
+     };
+ 
+   class _Undefined_class;
+ 
+   union _Nocopy_types
+   {
+     void*       _M_object;
+     const void* _M_const_object;
+     void (*_M_function_pointer)();
+     void (_Undefined_class::*_M_member_pointer)();
+   };
+ 
+   union _Any_data {
+     void*       _M_access()       { return &_M_pod_data[0]; }
+     const void* _M_access() const { return &_M_pod_data[0]; }
+ 
+     template<typename _Tp> _Tp& _M_access()
+     { return *static_cast<_Tp*>(_M_access()); }
+ 
+     template<typename _Tp> const _Tp& _M_access() const
+     { return *static_cast<const _Tp*>(_M_access()); }
+ 
+     _Nocopy_types _M_unused;
+     char _M_pod_data[sizeof(_Nocopy_types)];
+   };
+ 
+   enum _Manager_operation
+   {
+     __get_type_info,
+     __get_functor_ptr,
+     __clone_functor,
+     __destroy_functor
+   };
+ 
+   /* Simple type wrapper that helps avoid annoying const problems
+      when casting between void pointers and pointers-to-pointers. */
+   template<typename _Tp>
+     struct _Simple_type_wrapper
+     {
+       _Simple_type_wrapper(_Tp __value) : __value(__value) { }
+ 
+       _Tp __value;
+     };
+ 
+   template<typename _Tp>
+     struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
+       : __is_location_invariant<_Tp>
+     {
+     };
+ 
+   // Converts a reference to a function object into a callable
+   // function object.
+   template<typename _Functor>
+     inline _Functor& __callable_functor(_Functor& __f) { return __f; }
+ 
+   template<typename _Member, typename _Class>
+     inline _Mem_fn<_Member _Class::*>
+     __callable_functor(_Member _Class::* &__p)
+     { return mem_fn(__p); }
+ 
+   template<typename _Member, typename _Class>
+     inline _Mem_fn<_Member _Class::*>
+     __callable_functor(_Member _Class::* const &__p)
+     { return mem_fn(__p); }
+ 
+   template<typename _Signature, typename _Functor>
+     class _Function_handler;
+ 
+   template<typename _Signature>
+     class function;
+ 
+ 
+   /**
+    *  @if maint
+    *  Base class of all polymorphic function object wrappers.
+    *  @endif
+    */
+   class _Function_base
+   {
+   public:
+     static const std::size_t _M_max_size = sizeof(_Nocopy_types);
+     static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
+ 
+     template<typename _Functor>
+     class _Base_manager
+     {
+     protected:
+       static const bool __stored_locally =
+         (__is_location_invariant<_Functor>::value
+          && sizeof(_Functor) <= _M_max_size
+          && __alignof__(_Functor) <= _M_max_align
+          && (_M_max_align % __alignof__(_Functor) == 0));
+       typedef integral_constant<bool, __stored_locally> _Local_storage;
+ 
+       // Retrieve a pointer to the function object
+       static _Functor* _M_get_pointer(const _Any_data& __source)
+       {
+         const _Functor* __ptr =
+           __stored_locally? &__source._M_access<_Functor>()
+           /* have stored a pointer */ : __source._M_access<_Functor*>();
+         return const_cast<_Functor*>(__ptr);
+       }
+ 
+       // Clone a location-invariant function object that fits within
+       // an _Any_data structure.
+       static void
+       _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
+       {
+         new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
+       }
+ 
+       // Clone a function object that is not location-invariant or
+       // that cannot fit into an _Any_data structure.
+       static void
+       _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
+       {
+         __dest._M_access<_Functor*>() =
+           new _Functor(*__source._M_access<_Functor*>());
+       }
+ 
+       // Destroying a location-invariant object may still require
+       // destruction.
+       static void
+       _M_destroy(_Any_data& __victim, true_type)
+       {
+         __victim._M_access<_Functor>().~_Functor();
+       }
+ 
+       // Destroying an object located on the heap.
+       static void
+       _M_destroy(_Any_data& __victim, false_type)
+       {
+         delete __victim._M_access<_Functor*>();
+       }
+ 
+     public:
+       static bool
+       _M_manager(_Any_data& __dest, const _Any_data& __source,
+                  _Manager_operation __op)
+       {
+         switch (__op) {
+         case __get_type_info:
+           __dest._M_access<const type_info*>() = &typeid(_Functor);
+           break;
+ 
+         case __get_functor_ptr:
+           __dest._M_access<_Functor*>() = _M_get_pointer(__source);
+           break;
+ 
+         case __clone_functor:
+           _M_clone(__dest, __source, _Local_storage());
+           break;
+ 
+         case __destroy_functor:
+           _M_destroy(__dest, _Local_storage());
+           break;
+         }
+         return false;
+       }
+ 
+       static void
+       _M_init_functor(_Any_data& __functor, const _Functor& __f)
+       {
+         _M_init_functor(__functor, __f, _Local_storage());
+       }
+ 
+       template<typename _Signature>
+       static bool
+       _M_not_empty_function(const function<_Signature>& __f)
+       {
+         return __f;
+       }
+ 
+       template<typename _Tp>
+       static bool
+       _M_not_empty_function(const _Tp*& __fp)
+       {
+         return __fp;
+       }
+ 
+       template<typename _Class, typename _Tp>
+       static bool
+       _M_not_empty_function(_Tp _Class::* const& __mp)
+       {
+         return __mp;
+       }
+ 
+       template<typename _Tp>
+       static bool
+       _M_not_empty_function(const _Tp&)
+       {
+         return true;
+       }
+ 
+     private:
+       static void
+       _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type)
+       {
+         new (__functor._M_access()) _Functor(__f);
+       }
+ 
+       static void
+       _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type)
+       {
+         __functor._M_access<_Functor*>() = new _Functor(__f);
+       }
+     };
+ 
+     template<typename _Functor>
+     class _Ref_manager : public _Base_manager<_Functor*>
+     {
+       typedef _Function_base::_Base_manager<_Functor*> _Base;
+ 
+     public:
+       static bool
+       _M_manager(_Any_data& __dest, const _Any_data& __source,
+                  _Manager_operation __op)
+       {
+         switch (__op) {
+         case __get_type_info:
+           __dest._M_access<const type_info*>() = &typeid(_Functor);
+           break;
+ 
+         case __get_functor_ptr:
+           __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
+           return is_const<_Functor>::value;
+           break;
+ 
+         default:
+           _Base::_M_manager(__dest, __source, __op);
+         }
+         return false;
+       }
+ 
+       static void
+       _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
+       {
+         // TBD: Use address_of function instead
+         _Base::_M_init_functor(__functor, &__f.get());
+       }
+     };
+ 
+     _Function_base() : _M_manager(0) { }
+ 
+     ~_Function_base()
+     {
+       if (_M_manager)
+         {
+           _M_manager(_M_functor, _M_functor, __destroy_functor);
+         }
+     }
+ 
+ 
+     bool _M_empty() const { return !_M_manager; }
+ 
+     typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
+                                   _Manager_operation);
+ 
+     _Any_data     _M_functor;
+     _Manager_type _M_manager;
+   };
+ 
+ #define _GLIBCXX_NUM_ARGS 0
+ #define _GLIBCXX_COMMA
+ #define _GLIBCXX_TEMPLATE_PARAMS
+ #define _GLIBCXX_TEMPLATE_ARGS
+ #define _GLIBCXX_PARAMS
+ #define _GLIBCXX_ARGS
+ #define _GLIBCXX_COMMA_SHIFTED
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #define _GLIBCXX_PARAMS_SHIFTED
+ #define _GLIBCXX_ARGS_SHIFTED
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 1
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1
+ #define _GLIBCXX_TEMPLATE_ARGS _T1
+ #define _GLIBCXX_PARAMS _T1 __a1
+ #define _GLIBCXX_ARGS __a1
+ #define _GLIBCXX_COMMA_SHIFTED
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #define _GLIBCXX_PARAMS_SHIFTED
+ #define _GLIBCXX_ARGS_SHIFTED
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 2
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2
+ #define _GLIBCXX_ARGS __a1, __a2
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1
+ #define _GLIBCXX_ARGS_SHIFTED __a1
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 3
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3
+ #define _GLIBCXX_ARGS __a1, __a2, __a3
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 4
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 5
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 6
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 7
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 8
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 9
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 10
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 11
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 12
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 13
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 14
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 15
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 16
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 17
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 18
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17, typename _T18
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17, _T18
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17, _T18 __a18
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17, __a18
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 19
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17, typename _T18, typename _T19
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17, _T18, _T19
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17, _T18 __a18, _T19 __a19
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17, __a18, __a19
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17, typename _T18
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17, _T18
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17, _T18 __a18
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17, __a18
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+ #define _GLIBCXX_NUM_ARGS 20
+ #define _GLIBCXX_COMMA ,
+ #define _GLIBCXX_TEMPLATE_PARAMS typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17, typename _T18, typename _T19, typename _T20
+ #define _GLIBCXX_TEMPLATE_ARGS _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17, _T18, _T19, _T20
+ #define _GLIBCXX_PARAMS _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17, _T18 __a18, _T19 __a19, _T20 __a20
+ #define _GLIBCXX_ARGS __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17, __a18, __a19, __a20
+ #define _GLIBCXX_COMMA_SHIFTED ,
+ #define _GLIBCXX_TEMPLATE_PARAMS_SHIFTED typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _T10, typename _T11, typename _T12, typename _T13, typename _T14, typename _T15, typename _T16, typename _T17, typename _T18, typename _T19
+ #define _GLIBCXX_TEMPLATE_ARGS_SHIFTED _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, _T10, _T11, _T12, _T13, _T14, _T15, _T16, _T17, _T18, _T19
+ #define _GLIBCXX_PARAMS_SHIFTED _T1 __a1, _T2 __a2, _T3 __a3, _T4 __a4, _T5 __a5, _T6 __a6, _T7 __a7, _T8 __a8, _T9 __a9, _T10 __a10, _T11 __a11, _T12 __a12, _T13 __a13, _T14 __a14, _T15 __a15, _T16 __a16, _T17 __a17, _T18 __a18, _T19 __a19
+ #define _GLIBCXX_ARGS_SHIFTED __a1, __a2, __a3, __a4, __a5, __a6, __a7, __a8, __a9, __a10, __a11, __a12, __a13, __a14, __a15, __a16, __a17, __a18, __a19
+ #include <tr1/functional_iterate.h>
+ #undef _GLIBCXX_ARGS_SHIFTED
+ #undef _GLIBCXX_PARAMS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_ARGS_SHIFTED
+ #undef _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
+ #undef _GLIBCXX_COMMA_SHIFTED
+ #undef _GLIBCXX_ARGS
+ #undef _GLIBCXX_PARAMS
+ #undef _GLIBCXX_TEMPLATE_ARGS
+ #undef _GLIBCXX_TEMPLATE_PARAMS
+ #undef _GLIBCXX_COMMA
+ #undef _GLIBCXX_NUM_ARGS
+ 
+   // [3.7.2.7] null pointer comparisons
+ 
+   /**
+    *  @brief Compares a polymorphic function object wrapper against 0
+    *  (the NULL pointer).
+    *  @returns @c true if the wrapper has no target, @c false otherwise
+    *
+    *  This function will not throw an exception.
+    */
+   template<typename _Signature>
+     inline bool
+     operator==(const function<_Signature>& __f, _M_clear_type*)
+     {
+       return !__f;
+     }
+ 
+   /**
+    *  @overload
+    */
+   template<typename _Signature>
+     inline bool
+     operator==(_M_clear_type*, const function<_Signature>& __f)
+     {
+       return !__f;
+     }
+ 
+   /**
+    *  @brief Compares a polymorphic function object wrapper against 0
+    *  (the NULL pointer).
+    *  @returns @c false if the wrapper has no target, @c true otherwise
+    *
+    *  This function will not throw an exception.
+    */
+   template<typename _Signature>
+     inline bool
+     operator!=(const function<_Signature>& __f, _M_clear_type*)
+     {
+       return __f;
+     }
+ 
+   /**
+    *  @overload
+    */
+   template<typename _Signature>
+     inline bool
+     operator!=(_M_clear_type*, const function<_Signature>& __f)
+     {
+       return __f;
+     }
+ 
+   // [3.7.2.8] specialized algorithms
+ 
+   /**
+    *  @brief Swap the targets of two polymorphic function object wrappers.
+    *
+    *  This function will not throw an exception.
+    */
+   template<typename _Signature>
+     inline void
+     swap(function<_Signature>& __x, function<_Signature>& __y)
+     {
+       __x.swap(__y);
+     }
  }
  }
  
Index: include/tr1/functional_iterate.h
===================================================================
RCS file: include/tr1/functional_iterate.h
diff -N include/tr1/functional_iterate.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- include/tr1/functional_iterate.h	26 Jan 2005 06:51:49 -0000
***************
*** 0 ****
--- 1,684 ----
+ // TR1 functional -*- C++ -*-
+ 
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Writtten by Douglas Gregor <dgregor@cs.indiana.edu>
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ /** @file function_iterate.h
+  *  This is an internal header file, included by other library headers.
+  *  You should not attempt to use it directly.
+  */
+ 
+ #if _GLIBCXX_NUM_ARGS > 0
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
+ #if _GLIBCXX_NUM_ARGS == 1
+   : public unary_function<_Class*, _Res>
+ #elif _GLIBCXX_NUM_ARGS == 2
+     : public binary_function<_Class*, _T1, _Res>
+ #endif
+   {
+     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+   public:
+     typedef _Res result_type;
+ 
+     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+ 
+     // Handle objects
+     _Res
+     operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle pointers
+     _Res
+     operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle smart pointers, references and pointers to derived
+     template<typename _Tp>
+       _Res
+       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
+                  _GLIBCXX_PARAMS_SHIFTED) const
+       {
+         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
+                        _GLIBCXX_ARGS_SHIFTED);
+       }
+ 
+   private:
+     _Functor __pmf;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
+ #if _GLIBCXX_NUM_ARGS == 1
+   : public unary_function<const _Class*, _Res>
+ #elif _GLIBCXX_NUM_ARGS == 2
+     : public binary_function<const _Class*, _T1, _Res>
+ #endif
+   {
+     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
+ 
+      template<typename _Tp>
+       _Res
+       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+   public:
+     typedef _Res result_type;
+ 
+     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+ 
+     // Handle objects
+     _Res
+     operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle pointers
+     _Res
+     operator()(const _Class* __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle smart pointers, references and pointers to derived
+     template<typename _Tp>
+       _Res
+       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
+                  _GLIBCXX_PARAMS_SHIFTED) const
+       {
+         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
+                        _GLIBCXX_ARGS_SHIFTED);
+       }
+ 
+   private:
+     _Functor __pmf;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
+ #if _GLIBCXX_NUM_ARGS == 1
+   : public unary_function<volatile _Class*, _Res>
+ #elif _GLIBCXX_NUM_ARGS == 2
+     : public binary_function<volatile _Class*, _T1, _Res>
+ #endif
+   {
+     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+   public:
+     typedef _Res result_type;
+ 
+     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+ 
+     // Handle objects
+     _Res
+     operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle pointers
+     _Res
+     operator()(volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle smart pointers, references and pointers to derived
+     template<typename _Tp>
+       _Res
+       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
+                  _GLIBCXX_PARAMS_SHIFTED) const
+       {
+         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
+                        _GLIBCXX_ARGS_SHIFTED);
+       }
+   private:
+     _Functor __pmf;
+   };
+ 
+ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
+          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
+   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
+ #if _GLIBCXX_NUM_ARGS == 1
+   : public unary_function<const volatile _Class*, _Res>
+ #elif _GLIBCXX_NUM_ARGS == 2
+     : public binary_function<const volatile _Class*, _T1, _Res>
+ #endif
+   {
+     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
+               const volatile;
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     template<typename _Tp>
+       _Res
+       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
+               _GLIBCXX_PARAMS_SHIFTED) const
+       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+   public:
+     typedef _Res result_type;
+ 
+     explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+ 
+     // Handle objects
+     _Res
+     operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle pointers
+     _Res
+     operator()(const volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
+                _GLIBCXX_PARAMS_SHIFTED) const
+     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
+ 
+     // Handle smart pointers, references and pointers to derived
+     template<typename _Tp>
+       _Res
+       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
+                  _GLIBCXX_PARAMS_SHIFTED) const
+       {
+         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
+                        _GLIBCXX_ARGS_SHIFTED);
+       }
+ 
+   private:
+     _Functor __pmf;
+   };
+ #endif
+ 
+ template<typename _Signature, typename _Functor> class _Function_handler;
+ 
+ template<typename _Res, typename _Functor _GLIBCXX_COMMA
+          _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Functor>
+   : public _Function_base::_Base_manager<_Functor>
+ {
+   typedef _Function_base::_Base_manager<_Functor> _Base;
+ 
+  public:
+   static _Res
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Functor>
+   : public _Function_base::_Base_manager<_Functor>
+ {
+   typedef _Function_base::_Base_manager<_Functor> _Base;
+ 
+  public:
+   static void
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Res, typename _Functor _GLIBCXX_COMMA
+          _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS),
+                         reference_wrapper<_Functor> >
+   : public _Function_base::_Ref_manager<_Functor>
+ {
+   typedef _Function_base::_Ref_manager<_Functor> _Base;
+ 
+  public:
+   static _Res
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     return __callable_functor(**_Base::_M_get_pointer(__functor))
+              (_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS),
+                         reference_wrapper<_Functor> >
+   : public _Function_base::_Ref_manager<_Functor>
+ {
+   typedef _Function_base::_Ref_manager<_Functor> _Base;
+ 
+  public:
+   static void
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Class, typename _Member, typename _Res
+          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
+   : public _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
+ {
+   typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
+     _Base;
+ 
+  public:
+   static _Res
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
+              (_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Class, typename _Member
+          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
+   : public _Function_base::_Base_manager<
+              _Simple_type_wrapper< _Member _Class::* > >
+ {
+   typedef _Member _Class::* _Functor;
+   typedef _Simple_type_wrapper< _Functor > _Wrapper;
+   typedef _Function_base::_Base_manager<_Wrapper> _Base;
+ 
+  public:
+   static bool
+   _M_manager(_Any_data& __dest, const _Any_data& __source,
+              _Manager_operation __op)
+   {
+     switch (__op) {
+     case __get_type_info:
+       __dest._M_access<const type_info*>() = &typeid(_Functor);
+       break;
+ 
+     case __get_functor_ptr:
+       __dest._M_access<_Functor*>() =
+         &_Base::_M_get_pointer(__source)->__value;
+       break;
+ 
+     default:
+       _Base::_M_manager(__dest, __source, __op);
+     }
+     return false;
+   }
+ 
+   static void
+   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
+   {
+     std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
+       (_GLIBCXX_ARGS);
+   }
+ };
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ class function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
+ #if _GLIBCXX_NUM_ARGS == 1
+   : public unary_function<_T1, _Res>, private _Function_base
+ #elif _GLIBCXX_NUM_ARGS == 2
+   : public binary_function<_T1, _T2, _Res>, private _Function_base
+ #else
+   : private _Function_base
+ #endif
+ {
+   /**
+    *  @if maint
+    *  This class is used to implement the safe_bool idiom.
+    *  @endif
+    */
+   struct _Hidden_type
+   {
+     _Hidden_type* _M_bool;
+   };
+ 
+   /**
+    *  @if maint
+    *  This typedef is used to implement the safe_bool idiom.
+    *  @endif
+    */
+   typedef _Hidden_type* _Hidden_type::* _Safe_bool;
+ 
+   typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
+ 
+   struct _Useless {};
+ 
+  public:
+   typedef _Res result_type;
+ 
+   // [3.7.2.1] construct/copy/destroy
+ 
+   /**
+    *  @brief Default construct creates an empty function call wrapper.
+    *  @post @c !(bool)*this
+    */
+   function() : _Function_base() { }
+ 
+   /**
+    *  @brief Default construct creates an empty function call wrapper.
+    *  @post @c !(bool)*this
+    */
+   function(_M_clear_type*) : _Function_base() { }
+ 
+   /**
+    *  @brief %Function copy constructor.
+    *  @param x A %function object with identical call signature.
+    *  @pre @c (bool)*this == (bool)x
+    *
+    *  The newly-created %function contains a copy of the target of @a
+    *  x (if it has one).
+    */
+   function(const function& __x);
+ 
+   /**
+    *  @brief Builds a %function that targets a copy of the incoming
+    *  function object.
+    *  @param f A %function object that is callable with parameters of
+    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
+    *  to @c Res.
+    *
+    *  The newly-created %function object will target a copy of @a
+    *  f. If @a f is @c reference_wrapper<F>, then this function
+    *  object will contain a reference to the function object @c
+    *  f.get(). If @a f is a NULL function pointer or NULL
+    *  pointer-to-member, the newly-created object will be empty.
+    *
+    *  If @a f is a non-NULL function pointer or an object of type @c
+    *  reference_wrapper<F>, this function will not throw.
+    */
+   template<typename _Functor>
+     function(_Functor __f,
+              typename __enable_if<_Useless,
+              !is_integral<_Functor>::value>::_M_type
+              = _Useless());
+ 
+   /**
+    *  @brief %Function assignment operator.
+    *  @param x A %function with identical call signature.
+    *  @post @c (bool)*this == (bool)x
+    *  @returns @c *this
+    *
+    *  The target of @a x is copied to @c *this. If @a x has no
+    *  target, then @c *this will be empty.
+    *
+    *  If @a x targets a function pointer or a reference to a function
+    *  object, then this operation will not throw an exception.
+    */
+   function& operator=(const function& __x)
+     {
+       function(__x).swap(*this);
+       return *this;
+     }
+ 
+   /**
+    *  @brief %Function assignment to zero.
+    *  @post @c !(bool)*this
+    *  @returns @c *this
+    *
+    *  The target of @a *this is deallocated, leaving it empty.
+    */
+   function& operator=(_M_clear_type*)
+     {
+       if (_M_manager) {
+         _M_manager(_M_functor, _M_functor, __destroy_functor);
+         _M_manager = 0;
+         _M_invoker = 0;
+       }
+       return *this;
+     }
+ 
+   /**
+    *  @brief %Function assignment to a new target.
+    *  @param f A %function object that is callable with parameters of
+    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
+    *  to @c Res.
+    *  @return @c *this
+    *
+    *  This  %function object wrapper will target a copy of @a
+    *  f. If @a f is @c reference_wrapper<F>, then this function
+    *  object will contain a reference to the function object @c
+    *  f.get(). If @a f is a NULL function pointer or NULL
+    *  pointer-to-member, @c this object will be empty.
+    *
+    *  If @a f is a non-NULL function pointer or an object of type @c
+    *  reference_wrapper<F>, this function will not throw.
+    */
+   template<typename _Functor>
+     typename __enable_if<function&, !is_integral<_Functor>::value>::_M_type
+     operator=(_Functor __f)
+     {
+       function(__f).swap(*this);
+       return *this;
+     }
+ 
+   // [3.7.2.2] function modifiers
+ 
+   /**
+    *  @brief Swap the targets of two %function objects.
+    *  @param f A %function with identical call signature.
+    *
+    *  Swap the targets of @c this function object and @a f. This
+    *  function will not throw an exception.
+    */
+   void swap(function& __x)
+   {
+     _Any_data __old_functor = _M_functor;
+     _M_functor = __x._M_functor;
+     __x._M_functor = __old_functor;
+     _Manager_type __old_manager = _M_manager;
+     _M_manager = __x._M_manager;
+     __x._M_manager = __old_manager;
+     _Invoker_type __old_invoker = _M_invoker;
+     _M_invoker = __x._M_invoker;
+     __x._M_invoker = __old_invoker;
+   }
+ 
+   // [3.7.2.3] function capacity
+ 
+   /**
+    *  @brief Determine if the %function wrapper has a target.
+    *
+    *  @return @c true when this %function object contains a target,
+    *  or @c false when it is empty.
+    *
+    *  This function will not throw an exception.
+    */
+   operator _Safe_bool() const
+     {
+       if (_M_empty())
+         {
+           return 0;
+         }
+       else
+         {
+           return &_Hidden_type::_M_bool;
+         }
+     }
+ 
+   // [3.7.2.4] function invocation
+ 
+   /**
+    *  @brief Invokes the function targeted by @c *this.
+    *  @returns the result of the target.
+    *  @throws bad_function_call when @c !(bool)*this
+    *
+    *  The function call operator invokes the target function object
+    *  stored by @c this.
+    */
+   _Res operator()(_GLIBCXX_PARAMS) const;
+ 
+   // [3.7.2.5] function target access
+   /**
+    *  @brief Determine the type of the target of this function object
+    *  wrapper.
+    *
+    *  @returns the type identifier of the target function object, or
+    *  @c typeid(void) if @c !(bool)*this.
+    *
+    *  This function will not throw an exception.
+    */
+   const type_info& target_type() const;
+ 
+   /**
+    *  @brief Access the stored target function object.
+    *
+    *  @return Returns a pointer to the stored target function object,
+    *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
+    *  pointer.
+    *
+    * This function will not throw an exception.
+    */
+   template<typename _Functor>       _Functor* target();
+ 
+   /**
+    *  @overload
+    */
+   template<typename _Functor> const _Functor* target() const;
+ 
+  private:
+   // [3.7.2.6] undefined operators
+   template<typename _Function>
+     void operator==(const function<_Function>&) const;
+   template<typename _Function>
+     void operator!=(const function<_Function>&) const;
+ 
+   typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA _GLIBCXX_PARAMS);
+   _Invoker_type _M_invoker;
+ };
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
+     : _Function_base()
+   {
+     if (__x) {
+       _M_invoker = __x._M_invoker;
+       _M_manager = __x._M_manager;
+       __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
+     }
+   }
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ template<typename _Functor>
+   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
+   ::function(_Functor __f,
+              typename __enable_if<_Useless,
+                                   !is_integral<_Functor>::value>::_M_type)
+     : _Function_base()
+ {
+   typedef _Function_handler<_Signature_type, _Functor> _My_handler;
+   if (_My_handler::_M_not_empty_function(__f)) {
+     _M_invoker = &_My_handler::_M_invoke;
+     _M_manager = &_My_handler::_M_manager;
+     _My_handler::_M_init_functor(_M_functor, __f);
+   }
+ }
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   _Res function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
+   {
+     if (_M_empty()) throw bad_function_call();
+     return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
+   }
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+   const type_info&
+   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
+   {
+     if (_M_manager)
+       {
+         _Any_data __typeinfo_result;
+         _M_manager(__typeinfo_result, _M_functor, __get_type_info);
+         return *__typeinfo_result._M_access<const type_info*>();
+       }
+     else
+       {
+         return typeid(void);
+       }
+   }
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ template<typename _Functor>
+   _Functor*
+   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
+   {
+     if (typeid(_Functor) == target_type() && _M_manager)
+       {
+         _Any_data __ptr;
+         if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
+             && !is_const<_Functor>::value)
+           return 0;
+         else
+           return __ptr._M_access<_Functor*>();
+       }
+     else
+       {
+         return 0;
+       }
+   }
+ 
+ template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
+ template<typename _Functor>
+   const _Functor*
+   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
+   {
+     if (typeid(_Functor) == target_type() && _M_manager)
+       {
+         _Any_data __ptr;
+         _M_manager(__ptr, _M_functor, __get_functor_ptr);
+         return __ptr._M_access<const _Functor*>();
+       }
+     else
+       {
+         return 0;
+       }
+   }
+ 

Attachment: ChangeLog
Description: Text document

// 2005-01-26 Douglas Gregor <dgregor@cs.indiana.edu>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// 3.5 function template mem_fn
#include <tr1/functional>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>

struct X { int bar; };

struct Y : X { };

template<typename T>
struct dumb_ptr
{
  dumb_ptr(T* p) : p(p) {}

  T& operator*() const { return *p; }

 private:
  T* p;
};

// Test mem_fn with a data member
void test01()
{
  using std::tr1::mem_fn;

  X x;
  Y y;
  const X& xc = x;
  const Y& yc = y;
  X* xp = &x;
  Y* yp =&y;
  const X* xpc = xp;
  const Y* ypc = yp;
  dumb_ptr<X> xd(xp);
  dumb_ptr<Y> yd(yp);
  const dumb_ptr<X>& xdc = xd;
  const dumb_ptr<Y>& ydc = yd;

  int& bx = mem_fn(&X::bar)(x);
  const int& bxc = mem_fn(&X::bar)(xc);
  int& bxp = mem_fn(&X::bar)(xp);
  const int& bxpc = mem_fn(&X::bar)(xpc);
  const int& bxd = mem_fn(&X::bar)(xd);
  const int& bxdc = mem_fn(&X::bar)(xdc);

  int& by = mem_fn(&X::bar)(y);
  const int& byc = mem_fn(&X::bar)(yc);
  int& byp = mem_fn(&X::bar)(yp);
  const int& bypc = mem_fn(&X::bar)(ypc);
  const int& byd = mem_fn(&X::bar)(yd);
  const int& bydc = mem_fn(&X::bar)(ydc);
}

int main()
{
  test01();
  return 0;
}
// 2005-01-15 Douglas Gregor <dgregor@cs.indiana.edu>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// 3.7.2 polymorphic function object wrapper
#include <tr1/functional>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>

int truncate_float(float x) { return (int)x; }
long truncate_double(double x) { return (long)x; }

struct do_truncate_float_t
{
  do_truncate_float_t()
  {
    ++live_objects;
  }

  do_truncate_float_t(const do_truncate_float_t&)
  {
    ++live_objects;
  }

  ~do_truncate_float_t()
  {
    --live_objects;
  }

  int operator()(float x) { return (int)x; }

  static int live_objects;
};

int do_truncate_float_t::live_objects = 0;

struct do_truncate_double_t
{
  do_truncate_double_t()
  {
    ++live_objects;
  }

  do_truncate_double_t(const do_truncate_double_t&)
  {
    ++live_objects;
  }

  ~do_truncate_double_t()
  {
    --live_objects;
  }

  long operator()(double x) { return (long)x; }

  static int live_objects;
};

int do_truncate_double_t::live_objects = 0;

struct X
{
  int bar;

  int foo()                   { return 1; }
  int foo_c() const           { return 2; }
  int foo_v()  volatile       { return 3; }
  int foo_cv() const volatile { return 4; }
};

bool test = true;

// Operations on empty function<> objects
void test01()
{
  using std::tr1::function;
  using std::tr1::bad_function_call;

  // Default-construction
  function<int(float)> f1;
  VERIFY( ((bool)f1 == false) );
  VERIFY( !f1 );
  VERIFY( f1 == 0 );
  VERIFY( 0 == f1 );
  VERIFY( !(f1 != 0) );
  VERIFY( !(0 != f1) );

  // Copy-construction
  function<int(float)> f2(f1);
  VERIFY( !f2 );

  // Construct with NULL pointer
  function<int(float)> f3(0);
  VERIFY( !f3 );

  // Assignment
  f1 = f2;
  VERIFY( !f1);

  // Assignment to NULL pointer
  f1 = 0;
  VERIFY( !f1 );

  // Swap
  swap(f1, f2);
  VERIFY( !f1 );
  VERIFY( !f2 );

  // Invocation should throw bad_function_call
  bool thrown = false;
  try
    {
      f1(3.14159f);
      VERIFY( false );
    }
  catch (bad_function_call)
    {
      thrown = true;
    }
  VERIFY( thrown );

  // target_type returns typeid(void)
  VERIFY( f1.target_type() == typeid(void) );

  // target() always returns a NULL pointer
  VERIFY( f1.target<int (*)(float)>() == 0);

  // Check const version
  const function<int(float)>& f1c = f1;
  VERIFY( f1c.target<int (*)(float)>() == 0 );
  VERIFY( !f1c );
}

// Put function pointers into function<> wrappers
void test02()
{
  using std::tr1::function;

  function<int(float)> f1(truncate_float);
  VERIFY( f1 );
  VERIFY( !!f1 );
  VERIFY( !(f1 == 0) );
  VERIFY( !(0 == f1) );
  VERIFY( f1 != 0 );
  VERIFY( 0 != f1 );

  // Copy-construction
  function<int(float)> f2(f1);
  VERIFY( f2 );

  // Invocation
  VERIFY( f1(3.1f) == 3 );
  VERIFY( f2(3.1f) == 3 );

  // Assignment to zero
  f1 = 0;
  VERIFY( !f1 );

  // Swap
  f1.swap(f2);
  VERIFY( f1 );
  VERIFY( !f2 );
  VERIFY( f1(3.1f) == 3 );

  // Assignment from a function pointer
  f2 = truncate_float;
  VERIFY( f2(3.1f) == 3 );

  // target_type and target() functions
  const function<int(float)>& f1c = f1;
  VERIFY( typeid(int(*)(float)) == f1.target_type() );
  VERIFY( f2.target<int(*)(float)>() != 0 );
  VERIFY( *f2.target<int(*)(float)>() == &truncate_float );
  VERIFY( f1c.target<int(*)(float)>() != 0 );
  VERIFY( *f1c.target<int(*)(float)>() == &truncate_float );
}

// Put nearly-matching function pointers into function<> wrappers
void test03()
{
  using std::tr1::function;

  function<int(float)> f1(truncate_double);
  VERIFY( f1 );
  VERIFY( !!f1 );
  VERIFY( !(f1 == 0) );
  VERIFY( !(0 == f1) );
  VERIFY( f1 != 0 );
  VERIFY( 0 != f1 );

  // Copy-construction
  function<int(float)> f2(f1);
  VERIFY( f2 );

  // Invocation
  VERIFY( f1(3.1f) == 3 );
  VERIFY( f2(3.1f) == 3 );

  // Assignment to zero
  f1 = 0;
  VERIFY( !f1 );

  // Swap
  f1.swap(f2);
  VERIFY( f1 );
  VERIFY( !f2 );
  VERIFY( f1(3.1f) == 3 );

  // Assignment from a function pointer
  f2 = truncate_double;
  VERIFY( f2(3.1f) == 3 );

  // target_type and target() functions
  const function<int(float)>& f1c = f1;
  VERIFY( typeid(long(*)(double)) == f1.target_type() );
  VERIFY( f2.target<long(*)(double)>() != 0 );
  VERIFY( *f2.target<long(*)(double)>() == &truncate_double );
  VERIFY( f1c.target<long(*)(double)>() != 0 );
  VERIFY( *f1c.target<long(*)(double)>() == &truncate_double );
}

// Put function objects into function<> wrappers
void test04()
{
  using std::tr1::function;

  do_truncate_float_t truncate_float;

  function<int(float)> f1(truncate_float);
  VERIFY( f1 );
  VERIFY( !!f1 );
  VERIFY( !(f1 == 0) );
  VERIFY( !(0 == f1) );
  VERIFY( f1 != 0 );
  VERIFY( 0 != f1 );

  // Copy-construction
  function<int(float)> f2(f1);
  VERIFY( f2 );

  // Invocation
  VERIFY( f1(3.1f) == 3 );
  VERIFY( f2(3.1f) == 3 );

  // Assignment to zero
  f1 = 0;
  VERIFY( !f1 );

  // Swap
  f1.swap(f2);
  VERIFY( f1 );
  VERIFY( !f2 );
  VERIFY( f1(3.1f) == 3 );

  // Assignment from a function pointer
  f2 = do_truncate_float_t();
  VERIFY( f2(3.1f) == 3 );

  // target_type and target() functions
  const function<int(float)>& f1c = f1;
  VERIFY( typeid(do_truncate_float_t) == f1.target_type() );
  VERIFY( f2.target<do_truncate_float_t>() != 0 );
  VERIFY( f1c.target<do_truncate_float_t>() != 0 );
}

// Put member pointers into function<> wrappers
void test05()
{
  using std::tr1::function;

  X x;
  x.bar = 17;

  function<int(X&)> frm(&X::bar);
  VERIFY( frm );
  VERIFY( frm(x) == 17 );
  VERIFY( typeid(int X::*) == frm.target_type() );
  VERIFY( *frm.target<int X::*>() == &X::bar );

  function<int(X&)> fr(&X::foo);
  VERIFY( fr );
  VERIFY( fr(x) == 1 );
  VERIFY( typeid(int (X::*)()) == fr.target_type() );
  VERIFY( *fr.target<int (X::*)()>() == &X::foo );

  function<int(const X&)> frc(&X::foo_c);
  VERIFY( frc );
  VERIFY( frc(x) == 2 );
  VERIFY( typeid(int (X::*)() const) == frc.target_type() );
  VERIFY( *frc.target<int (X::*)() const >() == &X::foo_c );

  function<int(volatile X&)> frv(&X::foo_v);
  VERIFY( frv );
  VERIFY( frv(x) == 3 );
  VERIFY( typeid(int (X::*)() volatile) == frv.target_type() );
  VERIFY( *frv.target<int (X::*)() volatile >() == &X::foo_v );
  VERIFY( frv.target<int (X::*)() const volatile>() == 0 );

  function<int(const volatile X&)> frcv(&X::foo_cv);
  VERIFY( frcv );
  VERIFY( frcv(x) == 4 );
  VERIFY( typeid(int (X::*)() const volatile) == frcv.target_type() );
  VERIFY( *frcv.target<int (X::*)() const volatile >() == &X::foo_cv );
  VERIFY( frcv.target<int (X::*)() const>() == 0 );

  function<int(X*)> grm(&X::bar);
  VERIFY( grm );
  VERIFY( grm(&x) == 17 );
  VERIFY( typeid(int X::*) == grm.target_type() );
  VERIFY( *grm.target<int X::*>() == &X::bar );

  function<int(X*)> gr(&X::foo);
  VERIFY( gr );
  VERIFY( gr(&x) == 1 );
  VERIFY( typeid(int (X::*)()) == gr.target_type() );
  VERIFY( *gr.target<int (X::*)()>() == &X::foo );

  function<int(const X*)> grc(&X::foo_c);
  VERIFY( grc );
  VERIFY( grc(&x) == 2 );
  VERIFY( typeid(int (X::*)() const) == grc.target_type() );
  VERIFY( *grc.target<int (X::*)() const >() == &X::foo_c );

  function<int(volatile X*)> grv(&X::foo_v);
  VERIFY( grv );
  VERIFY( grv(&x) == 3 );
  VERIFY( typeid(int (X::*)() volatile) == grv.target_type() );
  VERIFY( *grv.target<int (X::*)() volatile >() == &X::foo_v );
  VERIFY( grv.target<int (X::*)() const volatile>() == 0 );

  function<int(const volatile X*)> grcv(&X::foo_cv);
  VERIFY( grcv );
  VERIFY( grcv(&x) == 4 );
  VERIFY( typeid(int (X::*)() const volatile) == grcv.target_type() );
  VERIFY( *grcv.target<int (X::*)() const volatile >() == &X::foo_cv );
  VERIFY( grcv.target<int (X::*)() const>() == 0 );
}

struct secret {};

struct noncopyable_function_object_type
{
  noncopyable_function_object_type(secret) {}

  int operator()() const { return 42; }
  int operator()()       { return 17; }

 private:
  noncopyable_function_object_type();
  noncopyable_function_object_type(const noncopyable_function_object_type&);
  void operator=(const noncopyable_function_object_type&);
};

// Put reference_wrappers into function<> wrappers
void test06()
{
  using std::tr1::function;
  using std::tr1::ref;
  using std::tr1::cref;

  secret password;
  noncopyable_function_object_type x(password);

  function<int()> f(ref(x));
  VERIFY( f );
  VERIFY( f() == 17 );
  VERIFY( f.target_type() == typeid(noncopyable_function_object_type) );
  VERIFY( f.target<noncopyable_function_object_type>() == &x );

  function<int()> g = f;
  VERIFY( g );
  VERIFY( g() == 17 );
  VERIFY( g.target_type() == typeid(noncopyable_function_object_type) );
  VERIFY( g.target<noncopyable_function_object_type>() == &x );

  function<int()> h = cref(x);
  VERIFY( h );
  VERIFY( h() == 42 );
  VERIFY( h.target_type() == typeid(noncopyable_function_object_type) );
  VERIFY( h.target<const noncopyable_function_object_type>() == &x );
  VERIFY( h.target<const noncopyable_function_object_type>() == &x );

  const function<int()>& hc = h;
  VERIFY( h.target<noncopyable_function_object_type>() == 0 );
  VERIFY( hc.target<noncopyable_function_object_type>() == &x );
}

// Put reference_wrappers to function pointers into function<> wrappers
void test07()
{
  using std::tr1::function;
  using std::tr1::ref;
  using std::tr1::cref;

  int (*fptr)(float) = truncate_float;

  function<int(float)> f1(ref(fptr));
  VERIFY( f1 );
  VERIFY( !!f1 );
  VERIFY( !(f1 == 0) );
  VERIFY( !(0 == f1) );
  VERIFY( f1 != 0 );
  VERIFY( 0 != f1 );

  // Invocation
  VERIFY( f1(3.1f) == 3 );

  // target_type and target() functions
  const function<int(float)>& f1c = f1;
  VERIFY( typeid(int(*)(float)) == f1.target_type() );
  VERIFY( f1.target<int(*)(float)>() != 0 );
  VERIFY( f1.target<int(*)(float)>() == &fptr );
  VERIFY( f1c.target<int(*)(float)>() != 0 );
  VERIFY( f1c.target<int(*)(float)>() == &fptr );

  function<int(float)> f2(cref(fptr));
  VERIFY( f2 );
  VERIFY( !!f2 );
  VERIFY( !(f2 == 0) );
  VERIFY( !(0 == f2) );
  VERIFY( f2 != 0 );
  VERIFY( 0 != f2 );

  // Invocation
  VERIFY( f2(3.1f) == 3 );

  // target_type and target() functions
  const function<int(float)>& f2c = f2;
  VERIFY( typeid(int(*)(float)) == f2.target_type() );
  VERIFY( f2.target<int(*)(float)>() == 0 );
  VERIFY( f2.target<int(* const)(float)>() == &fptr );
  VERIFY( f2c.target<int(*)(float)>() != 0 );
  VERIFY( f2c.target<int(*)(float)>() == &fptr );
}

// Put reference_wrappers to member pointers
void test08()
{
  using std::tr1::function;
  using std::tr1::ref;
  using std::tr1::cref;

  int X::* X_bar = &X::bar;
  int (X::* X_foo)() = &X::foo;
  int (X::* X_foo_c)() const = &X::foo_c;
  int (X::* X_foo_v)() volatile = &X::foo_v;
  int (X::* X_foo_cv)() const volatile = &X::foo_cv;

  X x;
  x.bar = 17;

  function<int(X&)> frm(ref(X_bar));
  VERIFY( frm );
  VERIFY( frm(x) == 17 );
  VERIFY( typeid(int X::*) == frm.target_type() );
  VERIFY( frm.target<int X::*>() == &X_bar );

  function<int(X&)> fr(ref(X_foo));
  VERIFY( fr );
  VERIFY( fr(x) == 1 );
  VERIFY( typeid(int (X::*)()) == fr.target_type() );
  VERIFY( fr.target<int (X::*)()>() == &X_foo );

  function<int(const X&)> frc(ref(X_foo_c));
  VERIFY( frc );
  VERIFY( frc(x) == 2 );
  VERIFY( typeid(int (X::*)() const) == frc.target_type() );
  VERIFY( frc.target<int (X::*)() const >() == &X_foo_c );

  function<int(volatile X&)> frv(ref(X_foo_v));
  VERIFY( frv );
  VERIFY( frv(x) == 3 );
  VERIFY( typeid(int (X::*)() volatile) == frv.target_type() );
  VERIFY( *frv.target<int (X::*)() volatile >() == X_foo_v );
  VERIFY( frv.target<int (X::*)() const volatile>() == 0 );

  function<int(const volatile X&)> frcv(ref(X_foo_cv));
  VERIFY( frcv );
  VERIFY( frcv(x) == 4 );
  VERIFY( typeid(int (X::*)() const volatile) == frcv.target_type() );
  VERIFY( *frcv.target<int (X::*)() const volatile >() == X_foo_cv );
  VERIFY( frcv.target<int (X::*)() const>() == 0 );

  function<int(X*)> grm(ref(X_bar));
  VERIFY( grm );
  VERIFY( grm(&x) == 17 );
  VERIFY( typeid(int X::*) == grm.target_type() );
  VERIFY( *grm.target<int X::*>() == X_bar );

  function<int(X*)> gr(ref(X_foo));
  VERIFY( gr );
  VERIFY( gr(&x) == 1 );
  VERIFY( typeid(int (X::*)()) == gr.target_type() );
  VERIFY( *gr.target<int (X::*)()>() == X_foo );

  function<int(const X*)> grc(ref(X_foo_c));
  VERIFY( grc );
  VERIFY( grc(&x) == 2 );
  VERIFY( typeid(int (X::*)() const) == grc.target_type() );
  VERIFY( *grc.target<int (X::*)() const >() == X_foo_c );

  function<int(volatile X*)> grv(ref(X_foo_v));
  VERIFY( grv );
  VERIFY( grv(&x) == 3 );
  VERIFY( typeid(int (X::*)() volatile) == grv.target_type() );
  VERIFY( *grv.target<int (X::*)() volatile >() == X_foo_v );
  VERIFY( grv.target<int (X::*)() const volatile>() == 0 );

  function<int(const volatile X*)> grcv(ref(X_foo_cv));
  VERIFY( grcv );
  VERIFY( grcv(&x) == 4 );
  VERIFY( typeid(int (X::*)() const volatile) == grcv.target_type() );
  VERIFY( *grcv.target<int (X::*)() const volatile >() == X_foo_cv );
  VERIFY( grcv.target<int (X::*)() const>() == 0 );

  function<int(X&)> hrm(cref(X_bar));
  VERIFY( hrm );
  VERIFY( hrm(x) == 17 );
  VERIFY( typeid(int X::*) == hrm.target_type() );
  VERIFY( hrm.target<int X::*>() == 0 );
  VERIFY( hrm.target<int X::* const>() == &X_bar );

  function<int(X&)> hr(cref(X_foo));
  VERIFY( hr );
  VERIFY( hr(x) == 1 );
  VERIFY( typeid(int (X::*)()) == hr.target_type() );
  VERIFY( hr.target<int (X::* const)()>() == &X_foo );

  function<int(const X&)> hrc(cref(X_foo_c));
  VERIFY( hrc );
  VERIFY( hrc(x) == 2 );
  VERIFY( typeid(int (X::*)() const) == hrc.target_type() );
  VERIFY( hrc.target<int (X::* const)() const >() == &X_foo_c );

  function<int(volatile X&)> hrv(cref(X_foo_v));
  VERIFY( hrv );
  VERIFY( hrv(x) == 3 );
  VERIFY( typeid(int (X::*)() volatile) == hrv.target_type() );
  VERIFY( hrv.target<int (X::* const)() volatile >() == &X_foo_v );
  VERIFY( hrv.target<int (X::* const)() const volatile>() == 0 );

  function<int(const volatile X&)> hrcv(cref(X_foo_cv));
  VERIFY( hrcv );
  VERIFY( hrcv(x) == 4 );
  VERIFY( typeid(int (X::*)() const volatile) == hrcv.target_type() );
  VERIFY( hrcv.target<int (X::* const)() const volatile >() == &X_foo_cv );
  VERIFY( hrcv.target<int (X::* const)() const>() == 0 );
}

// Put function objects into a void-returning function<> wrapper
void test09()
{
  using std::tr1::function;
  using std::tr1::ref;
  using std::tr1::cref;

  int (X::*X_foo_c)() const = &X::foo_c;
  function<void(X&)> f(&X::bar);
  f = &X::foo;
  f = ref(X_foo_c);
  f = cref(X_foo_c);

  function<void(float)> g = &truncate_float;
  g = do_truncate_float_t();
}

int main()
{
  test01();
  test02();
  test03();
  test04();
  test05();
  test06();
  test07();
  test08();
  test09();

  VERIFY( do_truncate_double_t::live_objects == 0 );
  VERIFY( do_truncate_float_t::live_objects == 0 );

  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]