This was my proposal, so it's about time we supported it.
* include/bits/shared_ptr.h (owner_less): Add default template
argument.
* include/bits/shared_ptr_base.h (_Sp_owner_less<void, void>): Define
specialization.
(owner_less<void>): Define specialization.
* include/bits/stl_function.h (__cpp_lib_transparent_operators):
Update value.
* testsuite/20_util/owner_less/void.cc: New test.
* testsuite/experimental/feat-cxx14.cc: Update macro value tested.
Tested powerpc64-linux, committed to trunk.
commit 56bd2d871a7d7ddb930c0221188446e339c873ab
Author: Jonathan Wakely <[email protected]>
Date: Thu Apr 7 13:40:33 2016 +0100
Define std::owner_less<void> specialization (P0074R0)
* include/bits/shared_ptr.h (owner_less): Add default template
argument.
* include/bits/shared_ptr_base.h (_Sp_owner_less<void, void>): Define
specialization.
(owner_less<void>): Define specialization.
* include/bits/stl_function.h (__cpp_lib_transparent_operators):
Update value.
* testsuite/20_util/owner_less/void.cc: New test.
* testsuite/experimental/feat-cxx14.cc: Update macro value tested.
diff --git a/libstdc++-v3/include/bits/shared_ptr.h
b/libstdc++-v3/include/bits/shared_ptr.h
index b22477e..16f78f7 100644
--- a/libstdc++-v3/include/bits/shared_ptr.h
+++ b/libstdc++-v3/include/bits/shared_ptr.h
@@ -535,9 +535,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Primary template owner_less
- template<typename _Tp>
+ template<typename _Tp = void>
struct owner_less;
+ /// Void specialization of owner_less
+ template<>
+ struct owner_less<void> : _Sp_owner_less<void, void>
+ { };
+
/// Partial specialization of owner_less for shared_ptr.
template<typename _Tp>
struct owner_less<shared_ptr<_Tp>>
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h
b/libstdc++-v3/include/bits/shared_ptr_base.h
index e844c9c..1474df6 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -1506,6 +1506,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.owner_before(__rhs); }
};
+ template<>
+ struct _Sp_owner_less<void, void>
+ {
+ template<typename _Tp, typename _Up>
+ auto
+ operator()(const _Tp& __lhs, const _Up& __rhs) const
+ -> decltype(__lhs.owner_before(__rhs))
+ { return __lhs.owner_before(__rhs); }
+
+ using is_transparent = void;
+ };
+
template<typename _Tp, _Lock_policy _Lp>
struct owner_less<__shared_ptr<_Tp, _Lp>>
: public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
diff --git a/libstdc++-v3/include/bits/stl_function.h
b/libstdc++-v3/include/bits/stl_function.h
index 68f39ff..1408da6 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 201103L
-#define __cpp_lib_transparent_operators 201210
+#define __cpp_lib_transparent_operators 201510
template<>
struct plus<void>
diff --git a/libstdc++-v3/testsuite/20_util/owner_less/void.cc
b/libstdc++-v3/testsuite/20_util/owner_less/void.cc
new file mode 100644
index 0000000..4facbf5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/owner_less/void.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 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/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <memory>
+
+#if __cplusplus >= 201402L
+// The feature-test macro is only defined for C++14 and later.
+# if __cpp_lib_transparent_operators < 201510
+# error "__cpp_lib_transparent_operators < 201510"
+# endif
+#endif
+
+void
+test01()
+{
+ using namespace std;
+
+ static_assert(is_same<owner_less<>, owner_less<void>>::value,
+ "owner_less<> uses void specialization");
+
+ shared_ptr<int> sp1;
+ shared_ptr<void> sp2;
+ shared_ptr<long> sp3;
+ weak_ptr<int> wp1;
+
+ owner_less<> cmp;
+ cmp(sp1, sp2);
+ cmp(sp1, wp1);
+ cmp(sp1, sp3);
+ cmp(wp1, sp1);
+ cmp(wp1, wp1);
+}
diff --git a/libstdc++-v3/testsuite/experimental/feat-cxx14.cc
b/libstdc++-v3/testsuite/experimental/feat-cxx14.cc
index 42b633f6..c61f7b0 100644
--- a/libstdc++-v3/testsuite/experimental/feat-cxx14.cc
+++ b/libstdc++-v3/testsuite/experimental/feat-cxx14.cc
@@ -40,8 +40,8 @@
#ifndef __cpp_lib_transparent_operators
# error "__cpp_lib_transparent_operators"
-#elif __cpp_lib_transparent_operators != 201210
-# error "__cpp_lib_transparent_operators != 201210"
+#elif __cpp_lib_transparent_operators < 201210
+# error "__cpp_lib_transparent_operators < 201210"
#endif
#ifndef __cpp_lib_result_of_sfinae