===================================================================
@@ -49,20 +49,22 @@
*/
/** @file bits/stl_function.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _STL_FUNCTION_H
#define _STL_FUNCTION_H 1
+#include <bits/move.h> // for std::forward
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.1 base classes
/** @defgroup functors Function Objects
* @ingroup utilities
*
* Function objects, or @e functors, are objects with an @c operator()
* defined and accessible. They can be passed as arguments to algorithm
@@ -129,201 +131,514 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup functors
*
* Because basic math often needs to be done during an algorithm,
* the library provides functors for those operations. See the
* documentation for @link functors the base classes@endlink
* for examples of their use.
*
* @{
*/
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct plus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct plus<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) + std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) + std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) + std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct minus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x - __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct minus<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) - std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) - std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) - std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct multiplies : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct multiplies<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) * std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) * std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) * std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct divides : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x / __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct divides<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) / std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) / std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) / std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct modulus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x % __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct modulus<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) % std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) % std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) % std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link arithmetic_functors math functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct negate : public unary_function<_Tp, _Tp>
{
_Tp
operator()(const _Tp& __x) const
{ return -__x; }
};
+
+#if __cplusplus >= 201103L
+ template<>
+ struct negate<void>
+ {
+ template <class _Tp>
+ constexpr auto
+ operator()(_Tp&& __x) const
+ noexcept(noexcept(-std::forward<_Tp>(__x)))
+ -> decltype(-std::forward<_Tp>(__x))
+ {
+ return -std::forward<_Tp>(__x);
+ }
+ typedef void is_transparent;
+ };
+#endif
/** @} */
// 20.3.3 comparisons
/** @defgroup comparison_functors Comparison Classes
* @ingroup functors
*
* The library provides six wrapper functors for all the basic comparisons
* in C++, like @c <.
*
* @{
*/
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x == __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct equal_to<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) == std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) == std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) == std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct not_equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x != __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct not_equal_to<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) != std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) != std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) != std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct greater : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x > __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct greater<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) > std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) > std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) > std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct less : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct less<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) < std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) < std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) < std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct greater_equal : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x >= __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct greater_equal<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) >= std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) >= std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) >= std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link comparison_functors comparison functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct less_equal : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x <= __y; }
};
+
+#if __cplusplus >= 201103L
+ template<>
+ struct less_equal<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) <= std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) <= std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) <= std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/** @} */
// 20.3.4 logical operations
/** @defgroup logical_functors Boolean Operations Classes
* @ingroup functors
*
* Here are wrapper functors for Boolean operations: @c &&, @c ||,
* and @c !.
*
* @{
*/
/// One of the @link logical_functors Boolean operations functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct logical_and : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x && __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct logical_and<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) && std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) && std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) && std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link logical_functors Boolean operations functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct logical_or : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x || __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct logical_or<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) || std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) || std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) || std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
/// One of the @link logical_functors Boolean operations functors@endlink.
- template<typename _Tp>
+ template<typename _Tp = void>
struct logical_not : public unary_function<_Tp, bool>
{
bool
operator()(const _Tp& __x) const
{ return !__x; }
};
+
+#if __cplusplus >= 201103L
+ template<>
+ struct logical_not<void>
+ {
+ template <class _Tp>
+ constexpr auto
+ operator()(_Tp&& __x) const
+ noexcept(noexcept(!std::forward<_Tp>(__x)))
+ -> decltype(!std::forward<_Tp>(__x))
+ {
+ return !std::forward<_Tp>(__x);
+ }
+ typedef void is_transparent;
+ };
+#endif
/** @} */
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 660. Missing Bitwise Operations.
- template<typename _Tp>
+ template<typename _Tp = void>
struct bit_and : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x & __y; }
};
- template<typename _Tp>
+#if __cplusplus >= 201103L
+ template<>
+ struct bit_and<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) & std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) & std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) & std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
+ template<typename _Tp = void>
struct bit_or : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x | __y; }
};
- template<typename _Tp>
+#if __cplusplus >= 201103L
+ template<>
+ struct bit_or<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) | std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) | std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) | std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
+ template<typename _Tp = void>
struct bit_xor : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x ^ __y; }
};
+#if __cplusplus >= 201103L
+ template<>
+ struct bit_xor<void>
+ {
+ template <class _Tp, class _Up>
+ constexpr auto
+ operator()(_Tp&& __x, _Up&& __y) const
+ noexcept(noexcept(std::forward<_Tp>(__x) ^ std::forward<_Up>(__y)))
+ -> decltype(std::forward<_Tp>(__x) ^ std::forward<_Up>(__y))
+ {
+ return std::forward<_Tp>(__x) ^ std::forward<_Up>(__y);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
+ template<typename _Tp = void>
+ struct bit_not : public unary_function<_Tp, _Tp>
+ {
+ _Tp
+ operator()(const _Tp& __x) const
+ { return ~__x; }
+ };
+
+#if __cplusplus >= 201103L
+ template<>
+ struct bit_not<void>
+ {
+ template <class _Tp>
+ constexpr auto
+ operator()(_Tp&& __x) const
+ noexcept(noexcept(~std::forward<_Tp>(__x)))
+ -> decltype(~std::forward<_Tp>(__x))
+ {
+ return ~std::forward<_Tp>(__x);
+ }
+ typedef void is_transparent;
+ };
+#endif
+
// 20.3.5 negators
/** @defgroup negators Negators
* @ingroup functors
*
* The functions @c not1 and @c not2 each take a predicate functor
* and return an instance of @c unary_negate or
* @c binary_negate, respectively. These classes are functors whose
* @c operator() performs the stored predicate function and then returns
* the negation of the result.
*
===================================================================
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+#include <type_traits>
+
+struct A{};
+extern A a;
+struct B{};
+struct C{};
+C operator<(A&,B&&);
+struct D{};
+struct E{};
+E& operator~(D);
+static_assert (std::is_same<
+ decltype(std::less<void>{} (a, B{})),
+ C >::value, "Meh?");
+static_assert (std::is_same<
+ decltype(std::bit_not<void>{} (D{})),
+ E& >::value, "Bah...");