6d0dff49ca
This adds most of the new C++20 features to <iterator>, as well as a few initial pieces of <ranges> (but no actual <ranges> header just yet). * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/iterator_concepts.h: New header. (contiguous_iterator_tag, iter_reference_t, ranges::iter_move) (iter_rvalue_reference_t, incrementable_traits, iter_difference_t) (readable_traits, iter_value_t, readable, iter_common_reference_t) (writable, waekly_incrementable, incrementable) (input_or_output_iterator, sentinel_for, disable_sized_sentinel) (sized_sentinel_for, input_iterator, output_iterator) (forward_iterator, bidirectional_iterator, random_access_iterator) (contiguous_iterator, indirectly_unary_invocable) (indirectly_regular_unary_invocable, indirect_unary_predicate) (indirect_relation, indirect_strict_weak_order, indirect_result_t) (projected, indirectly_movable, indirectly_movable_storable) (indirectly_copyable, indirectly_copyable_storable, ranges::iter_swap) (indirectly_swappable, indirectly_comparable, permutable, mergeable) (sortable, unreachable_sentinel_t, unreachable_sentinel) (default_sentinel_t, default_sentinel): Define. (__detail::__cpp17_iterator, __detail::__cpp17_input_iterator) (__detail::__cpp17_fwd_iterator, __detail::__cpp17_bidi_iterator) (__detail::__cpp17_randacc_iterator): Define. (__iterator_traits): Define constrained specializations. * include/bits/move.h (move): Only use old concept check for C++98. * include/bits/range_access.h (ranges::disable_sized_range) (ranges::begin, ranges::end, ranges::cbegin, ranges::cend) (ranges::rbegin, ranges::rend, ranges::crbegin, ranges::crend) (ranges::size, ranges::empty, ranges::data, ranges::cdata): Define new customization points for C++20. (ranges::range, ranges::sized_range): Define new concepts for C++20. (ranges::advance, ranges::distance, ranges::next, ranges::prev): Define new functions for C++20. (__adl_end, __adl_cdata, __adl_cbegin, __adl_cend, __adl_rbegin) (__adl_rend, __adl_crbegin, __adl_crend, __adl_cdata, __adl_size) (__adl_empty): Remove. * include/bits/stl_iterator.h (disable_sized_sentinel): Specialize for reverse_iterator. * include/bits/stl_iterator_base_types.h (contiguous_iterator_tag): Define new struct for C++20. (iterator_traits<_Tp*>): Constrain partial specialization in C++20. * include/std/concepts (__is_class_or_enum): Move to __detail namespace. * testsuite/20_util/forward/c_neg.cc: Adjust dg-error line number. * testsuite/20_util/forward/f_neg.cc: Likewise. * testsuite/24_iterators/associated_types/incrementable.traits.cc: New test. * testsuite/24_iterators/associated_types/readable.traits.cc: New test. * testsuite/24_iterators/contiguous/concept.cc: New test. * testsuite/24_iterators/contiguous/tag.cc: New test. * testsuite/24_iterators/customization_points/iter_move.cc: New test. * testsuite/24_iterators/customization_points/iter_swap.cc: New test. * testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: New test. * testsuite/24_iterators/range_operations/advance.cc: New test. * testsuite/24_iterators/range_operations/distance.cc: New test. * testsuite/24_iterators/range_operations/next.cc: New test. * testsuite/24_iterators/range_operations/prev.cc: New test. * testsuite/26_numerics/adjacent_difference/requirements/ explicit_instantiation/2.cc: Rename types that conflict with C++20 concepts. * testsuite/26_numerics/adjacent_difference/requirements/ explicit_instantiation/pod.cc: Likewise. * testsuite/26_numerics/partial_sum/requirements/ explicit_instantiation/2.cc: Likewise. * testsuite/26_numerics/partial_sum/requirements/ explicit_instantiation/pod.cc: Likewise. * testsuite/experimental/iterator/requirements.cc: Likewise. * testsuite/std/ranges/access/begin.cc: New test. * testsuite/std/ranges/access/cbegin.cc: New test. * testsuite/std/ranges/access/cdata.cc: New test. * testsuite/std/ranges/access/cend.cc: New test. * testsuite/std/ranges/access/crbegin.cc: New test. * testsuite/std/ranges/access/crend.cc: New test. * testsuite/std/ranges/access/data.cc: New test. * testsuite/std/ranges/access/empty.cc: New test. * testsuite/std/ranges/access/end.cc: New test. * testsuite/std/ranges/access/rbegin.cc: New test. * testsuite/std/ranges/access/rend.cc: New test. * testsuite/std/ranges/access/size.cc: New test. * testsuite/util/testsuite_iterators.h (contiguous_iterator_wrapper) (test_range, test_sized_range): New test utilities. From-SVN: r277579
225 lines
6.5 KiB
C++
225 lines
6.5 KiB
C++
// Move, forward and identity for C++11 + swap -*- C++ -*-
|
|
|
|
// Copyright (C) 2007-2019 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.
|
|
|
|
// Under Section 7 of GPL version 3, you are granted additional
|
|
// permissions described in the GCC Runtime Library Exception, version
|
|
// 3.1, as published by the Free Software Foundation.
|
|
|
|
// You should have received a copy of the GNU General Public License and
|
|
// a copy of the GCC Runtime Library Exception along with this program;
|
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
/** @file bits/move.h
|
|
* This is an internal header file, included by other library headers.
|
|
* Do not attempt to use it directly. @headername{utility}
|
|
*/
|
|
|
|
#ifndef _MOVE_H
|
|
#define _MOVE_H 1
|
|
|
|
#include <bits/c++config.h>
|
|
#if __cplusplus < 201103L
|
|
# include <bits/concept_check.h>
|
|
#endif
|
|
|
|
namespace std _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|
|
|
// Used, in C++03 mode too, by allocators, etc.
|
|
/**
|
|
* @brief Same as C++11 std::addressof
|
|
* @ingroup utilities
|
|
*/
|
|
template<typename _Tp>
|
|
inline _GLIBCXX_CONSTEXPR _Tp*
|
|
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
|
|
{ return __builtin_addressof(__r); }
|
|
|
|
#if __cplusplus >= 201103L
|
|
|
|
_GLIBCXX_END_NAMESPACE_VERSION
|
|
} // namespace
|
|
|
|
#include <type_traits> // Brings in std::declval too.
|
|
|
|
namespace std _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|
|
|
/**
|
|
* @addtogroup utilities
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Forward an lvalue.
|
|
* @return The parameter cast to the specified type.
|
|
*
|
|
* This function is used to implement "perfect forwarding".
|
|
*/
|
|
template<typename _Tp>
|
|
constexpr _Tp&&
|
|
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
|
|
{ return static_cast<_Tp&&>(__t); }
|
|
|
|
/**
|
|
* @brief Forward an rvalue.
|
|
* @return The parameter cast to the specified type.
|
|
*
|
|
* This function is used to implement "perfect forwarding".
|
|
*/
|
|
template<typename _Tp>
|
|
constexpr _Tp&&
|
|
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
|
|
{
|
|
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
|
|
" substituting _Tp is an lvalue reference type");
|
|
return static_cast<_Tp&&>(__t);
|
|
}
|
|
|
|
/**
|
|
* @brief Convert a value to an rvalue.
|
|
* @param __t A thing of arbitrary type.
|
|
* @return The parameter cast to an rvalue-reference to allow moving it.
|
|
*/
|
|
template<typename _Tp>
|
|
constexpr typename std::remove_reference<_Tp>::type&&
|
|
move(_Tp&& __t) noexcept
|
|
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
|
|
|
|
|
|
template<typename _Tp>
|
|
struct __move_if_noexcept_cond
|
|
: public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
|
|
is_copy_constructible<_Tp>>::type { };
|
|
|
|
/**
|
|
* @brief Conditionally convert a value to an rvalue.
|
|
* @param __x A thing of arbitrary type.
|
|
* @return The parameter, possibly cast to an rvalue-reference.
|
|
*
|
|
* Same as std::move unless the type's move constructor could throw and the
|
|
* type is copyable, in which case an lvalue-reference is returned instead.
|
|
*/
|
|
template<typename _Tp>
|
|
constexpr typename
|
|
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
|
|
move_if_noexcept(_Tp& __x) noexcept
|
|
{ return std::move(__x); }
|
|
|
|
// declval, from type_traits.
|
|
|
|
#if __cplusplus > 201402L
|
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
|
// 2296. std::addressof should be constexpr
|
|
# define __cpp_lib_addressof_constexpr 201603
|
|
#endif
|
|
/**
|
|
* @brief Returns the actual address of the object or function
|
|
* referenced by r, even in the presence of an overloaded
|
|
* operator&.
|
|
* @param __r Reference to an object or function.
|
|
* @return The actual address.
|
|
*/
|
|
template<typename _Tp>
|
|
inline _GLIBCXX17_CONSTEXPR _Tp*
|
|
addressof(_Tp& __r) noexcept
|
|
{ return std::__addressof(__r); }
|
|
|
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
|
// 2598. addressof works on temporaries
|
|
template<typename _Tp>
|
|
const _Tp* addressof(const _Tp&&) = delete;
|
|
|
|
// C++11 version of std::exchange for internal use.
|
|
template <typename _Tp, typename _Up = _Tp>
|
|
_GLIBCXX20_CONSTEXPR
|
|
inline _Tp
|
|
__exchange(_Tp& __obj, _Up&& __new_val)
|
|
{
|
|
_Tp __old_val = std::move(__obj);
|
|
__obj = std::forward<_Up>(__new_val);
|
|
return __old_val;
|
|
}
|
|
|
|
/// @} group utilities
|
|
|
|
#define _GLIBCXX_MOVE(__val) std::move(__val)
|
|
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
|
|
#else
|
|
#define _GLIBCXX_MOVE(__val) (__val)
|
|
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
|
|
#endif
|
|
|
|
/**
|
|
* @addtogroup utilities
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Swaps two values.
|
|
* @param __a A thing of arbitrary type.
|
|
* @param __b Another thing of arbitrary type.
|
|
* @return Nothing.
|
|
*/
|
|
template<typename _Tp>
|
|
_GLIBCXX20_CONSTEXPR
|
|
inline
|
|
#if __cplusplus >= 201103L
|
|
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
|
|
is_move_constructible<_Tp>,
|
|
is_move_assignable<_Tp>>::value>::type
|
|
#else
|
|
void
|
|
#endif
|
|
swap(_Tp& __a, _Tp& __b)
|
|
_GLIBCXX_NOEXCEPT_IF(__and_<is_nothrow_move_constructible<_Tp>,
|
|
is_nothrow_move_assignable<_Tp>>::value)
|
|
{
|
|
#if __cplusplus < 201103L
|
|
// concept requirements
|
|
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
|
|
#endif
|
|
_Tp __tmp = _GLIBCXX_MOVE(__a);
|
|
__a = _GLIBCXX_MOVE(__b);
|
|
__b = _GLIBCXX_MOVE(__tmp);
|
|
}
|
|
|
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
|
// DR 809. std::swap should be overloaded for array types.
|
|
/// Swap the contents of two arrays.
|
|
template<typename _Tp, size_t _Nm>
|
|
_GLIBCXX20_CONSTEXPR
|
|
inline
|
|
#if __cplusplus >= 201103L
|
|
typename enable_if<__is_swappable<_Tp>::value>::type
|
|
#else
|
|
void
|
|
#endif
|
|
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
|
|
_GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Tp>::value)
|
|
{
|
|
for (size_t __n = 0; __n < _Nm; ++__n)
|
|
swap(__a[__n], __b[__n]);
|
|
}
|
|
|
|
/// @} group utilities
|
|
_GLIBCXX_END_NAMESPACE_VERSION
|
|
} // namespace
|
|
|
|
#endif /* _MOVE_H */
|