diff options
author | Daniel Kruegler <daniel.kruegler@gmail.com> | 2016-06-16 15:07:19 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-06-16 16:07:19 +0100 |
commit | 6b9539e2aa811e84847db2deb1adfc288c7157b7 (patch) | |
tree | d9c81b59eb0c9725f8f69924f452f5c2575a9472 /libstdc++-v3/include/std | |
parent | b6ca982f5108c5982762eb2e7c361a88c082bc5d (diff) | |
download | gcc-6b9539e2aa811e84847db2deb1adfc288c7157b7.zip gcc-6b9539e2aa811e84847db2deb1adfc288c7157b7.tar.gz gcc-6b9539e2aa811e84847db2deb1adfc288c7157b7.tar.bz2 |
Provide swappable traits (p0185r1)
2016-06-16 Daniel Kruegler <daniel.kruegler@gmail.com>
Provide swappable traits (p0185r1)
* include/std/type_traits (is_swappable, is_nothrow_swappable,
is_swappable_with, is_nothrow_swappable_with, is_swappable_v,
is_nothrow_swappable_v, is_swappable_with_v,
is_nothrow_swappable_with_v): New.
* include/bits/stl_pair.h: Use it as per p0185r1.
* include/bits/stl_queue.h: Likewise.
* include/bits/stl_stack.h: Likewise.
* include/bits/unique_ptr.h: Likewise.
* include/std/tuple: Likewise.
* include/std/array: Likewise. Fix zero-size member swap.
* include/bits/hashtable.h: Use __and_.
* testsuite/20_util/is_nothrow_swappable/requirements/
explicit_instantiation.cc: Change test options to std=gnu++17.
* testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_nothrow_swappable/value.cc: Likewise.
* testsuite/20_util/is_swappable/requirements/
explicit_instantiation.cc: Likewise.
* testsuite/20_util/is_swappable/requirements/typedefs.cc: Likewise.
* testsuite/20_util/is_swappable/value.cc: Likewise.
* testsuite/20_util/is_nothrow_swappable/requirements/
explicit_instantiation_ext.cc: New.
* testsuite/20_util/is_nothrow_swappable/requirements/typedefs_ext.cc:
New.
* testsuite/20_util/is_nothrow_swappable/value.h: New.
* testsuite/20_util/is_nothrow_swappable/value_ext.cc: New.
* testsuite/20_util/is_nothrow_swappable_with/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc:
New.
* testsuite/20_util/is_nothrow_swappable_with/value.cc: New.
* testsuite/20_util/is_swappable/requirements/
explicit_instantiation_ext.cc: New.
* testsuite/20_util/is_swappable/requirements/typedefs_ext.cc: New.
* testsuite/20_util/is_swappable/value.h: New.
* testsuite/20_util/is_swappable/value_ext.cc: New.
* testsuite/20_util/is_swappable_with/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_swappable_with/requirements/typedefs.cc: New.
* testsuite/20_util/is_swappable_with/value.cc: New.
* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust
dg-error line numbers.
* testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
Likewise.
From-SVN: r237531
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r-- | libstdc++-v3/include/std/array | 16 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 112 |
3 files changed, 133 insertions, 4 deletions
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index ee46f68..73d2669 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -48,6 +48,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER struct __array_traits { typedef _Tp _Type[_Nm]; + typedef __is_swappable<_Tp> _Is_swappable; + typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable; static constexpr _Tp& _S_ref(const _Type& __t, std::size_t __n) noexcept @@ -62,6 +64,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER struct __array_traits<_Tp, 0> { struct _Type { }; + typedef true_type _Is_swappable; + typedef true_type _Is_nothrow_swappable; static constexpr _Tp& _S_ref(const _Type&, std::size_t) noexcept @@ -114,7 +118,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(array& __other) - noexcept(__is_nothrow_swappable<_Tp>::value) + noexcept(_AT_Type::_Is_nothrow_swappable::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. @@ -271,7 +275,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Specialized algorithms. template<typename _Tp, std::size_t _Nm> - inline void + inline +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // Constrained free swap overload, see p0185r1 + typename enable_if< + _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value + >::type +#else + void +#endif swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) noexcept(noexcept(__one.swap(__two))) { __one.swap(__two); } diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 9c425e7..180a346 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -1569,7 +1569,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// swap template<typename... _Elements> - inline void + inline +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // Constrained free swap overload, see p0185r1 + typename enable_if<__and_<__is_swappable<_Elements>...>::value + >::type +#else + void +#endif swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index eac2492..e5c0d46 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -2631,7 +2631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static false_type __test(...); }; - } + } // namespace __swappable_details template<typename _Tp> struct __is_swappable_impl @@ -2657,6 +2657,116 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public __is_nothrow_swappable_impl<_Tp>::type { }; +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 +#define __cpp_lib_is_swappable 201603 + /// Metafunctions used for detecting swappable types: p0185r1 + + /// is_swappable + template<typename _Tp> + struct is_swappable + : public __is_swappable_impl<_Tp>::type + { }; + + /// is_nothrow_swappable + template<typename _Tp> + struct is_nothrow_swappable + : public __is_nothrow_swappable_impl<_Tp>::type + { }; + +#if __cplusplus >= 201402L + /// is_swappable_v + template<typename _Tp> + constexpr bool is_swappable_v = is_swappable<_Tp>::value; + + /// is_nothrow_swappable_v + template<typename _Tp> + constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; +#endif // __cplusplus >= 201402L + + namespace __swappable_with_details { + using std::swap; + + struct __do_is_swappable_with_impl + { + template<typename _Tp, typename _Up, typename + = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())), + typename + = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))> + static true_type __test(int); + + template<typename, typename> + static false_type __test(...); + }; + + struct __do_is_nothrow_swappable_with_impl + { + template<typename _Tp, typename _Up> + static __bool_constant< + noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())) + && + noexcept(swap(std::declval<_Up>(), std::declval<_Tp>())) + > __test(int); + + template<typename, typename> + static false_type __test(...); + }; + + } // namespace __swappable_with_details + + template<typename _Tp, typename _Up> + struct __is_swappable_with_impl + : public __swappable_with_details::__do_is_swappable_with_impl + { + typedef decltype(__test<_Tp, _Up>(0)) type; + }; + + // Optimization for the homogenous lvalue case, not required: + template<typename _Tp> + struct __is_swappable_with_impl<_Tp&, _Tp&> + : public __swappable_details::__do_is_swappable_impl + { + typedef decltype(__test<_Tp&>(0)) type; + }; + + template<typename _Tp, typename _Up> + struct __is_nothrow_swappable_with_impl + : public __swappable_with_details::__do_is_nothrow_swappable_with_impl + { + typedef decltype(__test<_Tp, _Up>(0)) type; + }; + + // Optimization for the homogenous lvalue case, not required: + template<typename _Tp> + struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> + : public __swappable_details::__do_is_nothrow_swappable_impl + { + typedef decltype(__test<_Tp&>(0)) type; + }; + + /// is_swappable_with + template<typename _Tp, typename _Up> + struct is_swappable_with + : public __is_swappable_with_impl<_Tp, _Up>::type + { }; + + /// is_nothrow_swappable_with + template<typename _Tp, typename _Up> + struct is_nothrow_swappable_with + : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type + { }; + +#if __cplusplus >= 201402L + /// is_swappable_with_v + template<typename _Tp, typename _Up> + constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; + + /// is_nothrow_swappable_with_v + template<typename _Tp, typename _Up> + constexpr bool is_nothrow_swappable_with_v = + is_nothrow_swappable_with<_Tp, _Up>::value; +#endif // __cplusplus >= 201402L +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std |