re PR libstdc++/49668 ([C++0x] std::thread does not forward its args as rvalues)
[gcc.git] / libstdc++-v3 / include / std / functional
index 660e371b5997ca65fe66ec30dda763f9e4e08065..df3f9ceb7b43248a94be5430368f6289e945b4e9 100644 (file)
@@ -62,6 +62,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+  template<typename _MemberPointer>
+    class _Mem_fn;
+  template<typename _Tp, typename _Class>
+    _Mem_fn<_Tp _Class::*>
+    mem_fn(_Tp _Class::*);
+
 _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
   /// If we have found a result_type, extract it.
@@ -212,19 +218,6 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
       static const bool value = sizeof(__test((_Tp*)0)) == 1;
     };
 
-  /// Turns a function type into a function pointer type
-  template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value>
-    struct _Function_to_function_pointer
-    {
-      typedef _Tp type;
-    };
-
-  template<typename _Tp>
-    struct _Function_to_function_pointer<_Tp, true>
-    {
-      typedef _Tp* type;
-    };
-
   /**
    * Invoke a function object, which may be either a member pointer or a
    * function object. The first parameter will tell which.
@@ -235,20 +228,33 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
             (!is_member_pointer<_Functor>::value
              && !is_function<_Functor>::value
              && !is_function<typename remove_pointer<_Functor>::type>::value),
-            typename result_of<_Functor(_Args...)>::type
+            typename result_of<_Functor(_Args&&...)>::type
           >::type
     __invoke(_Functor& __f, _Args&&... __args)
     {
       return __f(std::forward<_Args>(__args)...);
     }
 
+  template<typename _Functor, typename... _Args>
+    inline
+    typename enable_if<
+             (is_member_pointer<_Functor>::value
+              && !is_function<_Functor>::value
+              && !is_function<typename remove_pointer<_Functor>::type>::value),
+             typename result_of<_Functor(_Args&&...)>::type
+           >::type
+    __invoke(_Functor& __f, _Args&&... __args)
+    {
+      return mem_fn(__f)(std::forward<_Args>(__args)...);
+    }
+
   // To pick up function references (that will become function pointers)
   template<typename _Functor, typename... _Args>
     inline
     typename enable_if<
             (is_pointer<_Functor>::value
              && is_function<typename remove_pointer<_Functor>::type>::value),
-            typename result_of<_Functor(_Args...)>::type
+            typename result_of<_Functor(_Args&&...)>::type
           >::type
     __invoke(_Functor __f, _Args&&... __args)
     {
@@ -263,40 +269,43 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
   template<bool _Unary, bool _Binary, typename _Tp>
     struct _Reference_wrapper_base_impl;
 
-  // Not a unary_function or binary_function, so try a weak result type.
+  // None of the nested argument types.
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<false, false, _Tp>
     : _Weak_result_type<_Tp>
     { };
 
-  // unary_function but not binary_function
+  // Nested argument_type only.
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<true, false, _Tp>
-    : unary_function<typename _Tp::argument_type,
-                    typename _Tp::result_type>
-    { };
+    : _Weak_result_type<_Tp>
+    {
+      typedef typename _Tp::argument_type argument_type;
+    };
 
-  // binary_function but not unary_function
+  // Nested first_argument_type and second_argument_type only.
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<false, true, _Tp>
-    : binary_function<typename _Tp::first_argument_type,
-                     typename _Tp::second_argument_type,
-                     typename _Tp::result_type>
-    { };
+    : _Weak_result_type<_Tp>
+    {
+      typedef typename _Tp::first_argument_type first_argument_type;
+      typedef typename _Tp::second_argument_type second_argument_type;
+    };
 
-  // Both unary_function and binary_function. Import result_type to
-  // avoid conflicts.
+  // All the nested argument types.
    template<typename _Tp>
     struct _Reference_wrapper_base_impl<true, true, _Tp>
-    : unary_function<typename _Tp::argument_type,
-                    typename _Tp::result_type>,
-      binary_function<typename _Tp::first_argument_type,
-                     typename _Tp::second_argument_type,
-                     typename _Tp::result_type>
+    : _Weak_result_type<_Tp>
     {
-      typedef typename _Tp::result_type result_type;
+      typedef typename _Tp::argument_type argument_type;
+      typedef typename _Tp::first_argument_type first_argument_type;
+      typedef typename _Tp::second_argument_type second_argument_type;
     };
 
+  _GLIBCXX_HAS_NESTED_TYPE(argument_type)
+  _GLIBCXX_HAS_NESTED_TYPE(first_argument_type)
+  _GLIBCXX_HAS_NESTED_TYPE(second_argument_type)
+
   /**
    *  Derives from unary_function or binary_function when it
    *  can. Specializations handle all of the easy cases. The primary
@@ -306,8 +315,9 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
   template<typename _Tp>
     struct _Reference_wrapper_base
     : _Reference_wrapper_base_impl<
-      _Derives_from_unary_function<_Tp>::value,
-      _Derives_from_binary_function<_Tp>::value,
+      __has_argument_type<_Tp>::value,
+      __has_first_argument_type<_Tp>::value
+      && __has_second_argument_type<_Tp>::value,
       _Tp>
     { };
 
@@ -422,41 +432,37 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
     class reference_wrapper
     : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
     {
-      // If _Tp is a function type, we can't form result_of<_Tp(...)>,
-      // so turn it into a function pointer type.
-      typedef typename _Function_to_function_pointer<_Tp>::type
-       _M_func_type;
-
       _Tp* _M_data;
+
     public:
       typedef _Tp type;
 
-      reference_wrapper(_Tp& __indata)
+      reference_wrapper(_Tp& __indata) noexcept
       : _M_data(std::__addressof(__indata))
       { }
 
       reference_wrapper(_Tp&&) = delete;
 
-      reference_wrapper(const reference_wrapper<_Tp>& __inref):
-      _M_data(__inref._M_data)
+      reference_wrapper(const reference_wrapper<_Tp>& __inref) noexcept
+      _M_data(__inref._M_data)
       { }
 
       reference_wrapper&
-      operator=(const reference_wrapper<_Tp>& __inref)
+      operator=(const reference_wrapper<_Tp>& __inref) noexcept
       {
        _M_data = __inref._M_data;
        return *this;
       }
 
-      operator _Tp&() const
+      operator _Tp&() const noexcept
       { return this->get(); }
 
       _Tp&
-      get() const
+      get() const noexcept
       { return *_M_data; }
 
       template<typename... _Args>
-       typename result_of<_M_func_type(_Args...)>::type
+       typename result_of<_Tp&(_Args&&...)>::type
        operator()(_Args&&... __args) const
        {
          return __invoke(get(), std::forward<_Args>(__args)...);
@@ -467,32 +473,35 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
   /// Denotes a reference should be taken to a variable.
   template<typename _Tp>
     inline reference_wrapper<_Tp>
-    ref(_Tp& __t)
+    ref(_Tp& __t) noexcept
     { return reference_wrapper<_Tp>(__t); }
 
   /// Denotes a const reference should be taken to a variable.
   template<typename _Tp>
     inline reference_wrapper<const _Tp>
-    cref(const _Tp& __t)
+    cref(const _Tp& __t) noexcept
     { return reference_wrapper<const _Tp>(__t); }
 
+  template<typename _Tp>
+    void ref(const _Tp&&) = delete;
+
+  template<typename _Tp>
+    void cref(const _Tp&&) = delete;
+
   /// Partial specialization.
   template<typename _Tp>
     inline reference_wrapper<_Tp>
-    ref(reference_wrapper<_Tp> __t)
+    ref(reference_wrapper<_Tp> __t) noexcept
     { return ref(__t.get()); }
 
   /// Partial specialization.
   template<typename _Tp>
     inline reference_wrapper<const _Tp>
-    cref(reference_wrapper<_Tp> __t)
+    cref(reference_wrapper<_Tp> __t) noexcept
     { return cref(__t.get()); }
 
   // @} group functors
 
-  template<typename _MemberPointer>
-    class _Mem_fn;
-
   /**
    * Derives from @c unary_function or @c binary_function, or perhaps
    * nothing, depending on the number of arguments provided. The
@@ -1201,7 +1210,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
       // Call as const
       template<typename... _Args, typename _Result
-       = decltype( std::declval<const _Functor>()(
+       = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+                      typename add_const<_Functor>::type>::type>()(
              _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
                                  std::declval<tuple<_Args...>&>() )... ) )>
        _Result
@@ -1214,7 +1224,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
       // Call as volatile
       template<typename... _Args, typename _Result
-       = decltype( std::declval<volatile _Functor>()(
+       = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+                       typename add_volatile<_Functor>::type>::type>()(
              _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
                                  std::declval<tuple<_Args...>&>() )... ) )>
        _Result
@@ -1227,7 +1238,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
       // Call as const volatile
       template<typename... _Args, typename _Result
-       = decltype( std::declval<const volatile _Functor>()(
+       = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+                       typename add_cv<_Functor>::type>::type>()(
              _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
                                  std::declval<tuple<_Args...>&>() )... ) )>
        _Result
@@ -1416,39 +1428,58 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
     struct is_bind_expression<_Bind_result<_Result, _Signature> >
     : public true_type { };
 
-  template<typename _Functor, typename... _ArgTypes>
+  // Trait type used to remove std::bind() from overload set via SFINAE
+  // when first argument has integer type, so that std::bind() will
+  // not be a better match than ::bind() from the BSD Sockets API.
+  template<typename _Tp>
+    class __is_socketlike
+    {
+      typedef typename decay<_Tp>::type _Tp2;
+    public:
+      static const bool value =
+       is_integral<_Tp2>::value || is_enum<_Tp2>::value;
+    };
+
+  template<bool _SocketLike, typename _Func, typename... _BoundArgs>
     struct _Bind_helper
     {
-      typedef _Maybe_wrap_member_pointer<typename decay<_Functor>::type>
+      typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
        __maybe_type;
-      typedef typename __maybe_type::type __functor_type;
-      typedef _Bind<__functor_type(typename decay<_ArgTypes>::type...)> type;
+      typedef typename __maybe_type::type __func_type;
+      typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type;
     };
 
+  // Partial specialization for is_socketlike == true, does not define
+  // nested type so std::bind() will not participate in overload resolution
+  // when the first argument might be a socket file descriptor.
+  template<typename _Func, typename... _BoundArgs>
+    struct _Bind_helper<true, _Func, _BoundArgs...>
+    { };
+
   /**
    *  @brief Function template for std::bind.
    *  @ingroup binders
    */
-  template<typename _Functor, typename... _ArgTypes>
-    inline
-    typename _Bind_helper<_Functor, _ArgTypes...>::type
-    bind(_Functor&& __f, _ArgTypes&&... __args)
+  template<typename _Func, typename... _BoundArgs>
+    inline typename
+    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
+    bind(_Func&& __f, _BoundArgs&&... __args)
     {
-      typedef _Bind_helper<_Functor, _ArgTypes...> __helper_type;
+      typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
       typedef typename __helper_type::__maybe_type __maybe_type;
       typedef typename __helper_type::type __result_type;
-      return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)),
-                          std::forward<_ArgTypes>(__args)...);
+      return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
+                          std::forward<_BoundArgs>(__args)...);
     }
 
-  template<typename _Result, typename _Functor, typename... _ArgTypes>
+  template<typename _Result, typename _Func, typename... _BoundArgs>
     struct _Bindres_helper
     {
-      typedef _Maybe_wrap_member_pointer<typename decay<_Functor>::type>
+      typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
        __maybe_type;
       typedef typename __maybe_type::type __functor_type;
       typedef _Bind_result<_Result,
-                          __functor_type(typename decay<_ArgTypes>::type...)>
+                          __functor_type(typename decay<_BoundArgs>::type...)>
        type;
     };
 
@@ -1456,16 +1487,87 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
    *  @brief Function template for std::bind<R>.
    *  @ingroup binders
    */
-  template<typename _Result, typename _Functor, typename... _ArgTypes>
+  template<typename _Result, typename _Func, typename... _BoundArgs>
     inline
-    typename _Bindres_helper<_Result, _Functor, _ArgTypes...>::type
-    bind(_Functor&& __f, _ArgTypes&&... __args)
+    typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
+    bind(_Func&& __f, _BoundArgs&&... __args)
     {
-      typedef _Bindres_helper<_Result, _Functor, _ArgTypes...> __helper_type;
+      typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type;
       typedef typename __helper_type::__maybe_type __maybe_type;
       typedef typename __helper_type::type __result_type;
-      return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)),
-                          std::forward<_ArgTypes>(__args)...);
+      return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
+                          std::forward<_BoundArgs>(__args)...);
+    }
+
+  template<typename _Signature>
+    struct _Bind_simple;
+
+  template<typename _Callable, typename... _Args>
+    struct _Bind_simple<_Callable(_Args...)>
+    {
+      typedef typename result_of<_Callable(_Args...)>::type result_type;
+
+      template<typename... _Args2, typename = typename
+               enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type>
+        explicit
+        _Bind_simple(const _Callable& __callable, _Args2&&... __args)
+        : _M_bound(__callable, std::forward<_Args2>(__args)...)
+        { }
+
+      template<typename... _Args2, typename = typename
+               enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type>
+        explicit
+        _Bind_simple(_Callable&& __callable, _Args2&&... __args)
+        : _M_bound(std::move(__callable), std::forward<_Args2>(__args)...)
+        { }
+
+      _Bind_simple(const _Bind_simple&) = default;
+      _Bind_simple(_Bind_simple&&) = default;
+
+      result_type
+      operator()()
+      {
+        typedef typename _Build_index_tuple<sizeof...(_Args)>::__type _Indices;
+        return _M_invoke(_Indices());
+      }
+
+    private:
+
+      template<int... _Indices>
+        typename result_of<_Callable(_Args...)>::type
+        _M_invoke(_Index_tuple<_Indices...>)
+        {
+         // std::bind always forwards bound arguments as lvalues,
+         // but this type can call functions which only accept rvalues.
+          return std::forward<_Callable>(std::get<0>(_M_bound))(
+              std::forward<_Args>(std::get<_Indices+1>(_M_bound))...);
+        }
+
+      std::tuple<_Callable, _Args...> _M_bound;
+    };
+
+  template<typename _Func, typename... _BoundArgs>
+    struct _Bind_simple_helper
+    {
+      typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
+        __maybe_type;
+      typedef typename __maybe_type::type __func_type;
+      typedef _Bind_simple<__func_type(typename decay<_BoundArgs>::type...)>
+               __type;
+    };
+
+  // Simplified version of std::bind for internal use, without support for
+  // unbound arguments, placeholders or nested bind expressions.
+  template<typename _Callable, typename... _Args>
+    typename _Bind_simple_helper<_Callable, _Args...>::__type
+    __bind_simple(_Callable&& __callable, _Args&&... __args)
+    {
+      typedef _Bind_simple_helper<_Callable, _Args...> __helper_type;
+      typedef typename __helper_type::__maybe_type __maybe_type;
+      typedef typename __helper_type::__type __result_type;
+      return __result_type(
+          __maybe_type::__do_wrap( std::forward<_Callable>(__callable)),
+          std::forward<_Args>(__args)...);
     }
 
   /**
@@ -1882,13 +1984,15 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
        *  @brief Default construct creates an empty function call wrapper.
        *  @post @c !(bool)*this
        */
-      function() : _Function_base() { }
+      function() noexcept
+      : _Function_base() { }
 
       /**
        *  @brief Creates an empty function call wrapper.
        *  @post @c !(bool)*this
        */
-      function(nullptr_t) : _Function_base() { }
+      function(nullptr_t) noexcept
+      : _Function_base() { }
 
       /**
        *  @brief %Function copy constructor.
@@ -2019,7 +2123,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
       /// @overload
       template<typename _Functor>
        typename enable_if<!is_integral<_Functor>::value, function&>::type
-       operator=(reference_wrapper<_Functor> __f)
+       operator=(reference_wrapper<_Functor> __f) noexcept
        {
          function(__f).swap(*this);
          return *this;
@@ -2062,7 +2166,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
        *
        *  This function will not throw an %exception.
        */
-      explicit operator bool() const
+      explicit operator bool() const noexcept
       { return !_M_empty(); }
 
       // [3.7.2.4] function invocation
@@ -2088,7 +2192,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
        *
        *  This function will not throw an %exception.
        */
-      const type_info& target_type() const;
+      const type_info& target_type() const noexcept;
 
       /**
        *  @brief Access the stored target function object.
@@ -2099,10 +2203,10 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
        *
        * This function will not throw an %exception.
        */
-      template<typename _Functor>       _Functor* target();
+      template<typename _Functor>       _Functor* target() noexcept;
 
       /// @overload
-      template<typename _Functor> const _Functor* target() const;
+      template<typename _Functor> const _Functor* target() const noexcept;
 #endif
 
     private:
@@ -2156,7 +2260,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
   template<typename _Res, typename... _ArgTypes>
     const type_info&
     function<_Res(_ArgTypes...)>::
-    target_type() const
+    target_type() const noexcept
     {
       if (_M_manager)
        {
@@ -2172,7 +2276,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
     template<typename _Functor>
       _Functor*
       function<_Res(_ArgTypes...)>::
-      target()
+      target() noexcept
       {
        if (typeid(_Functor) == target_type() && _M_manager)
          {
@@ -2191,7 +2295,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
     template<typename _Functor>
       const _Functor*
       function<_Res(_ArgTypes...)>::
-      target() const
+      target() const noexcept
       {
        if (typeid(_Functor) == target_type() && _M_manager)
          {
@@ -2215,13 +2319,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
    */
   template<typename _Res, typename... _Args>
     inline bool
-    operator==(const function<_Res(_Args...)>& __f, nullptr_t)
+    operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
     { return !static_cast<bool>(__f); }
 
   /// @overload
   template<typename _Res, typename... _Args>
     inline bool
-    operator==(nullptr_t, const function<_Res(_Args...)>& __f)
+    operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
     { return !static_cast<bool>(__f); }
 
   /**
@@ -2233,13 +2337,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
    */
   template<typename _Res, typename... _Args>
     inline bool
-    operator!=(const function<_Res(_Args...)>& __f, nullptr_t)
+    operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
     { return static_cast<bool>(__f); }
 
   /// @overload
   template<typename _Res, typename... _Args>
     inline bool
-    operator!=(nullptr_t, const function<_Res(_Args...)>& __f)
+    operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
     { return static_cast<bool>(__f); }
 
   // [20.7.15.2.7] specialized algorithms