Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ struct _Optimistic_temporary_buffer { // temporary storage with _alloca-like att

#ifdef __cpp_lib_concepts
namespace ranges {
// CONCEPT _Convertible_from
template <class _To, class _From>
concept _Convertible_from = convertible_to<_From, _To>;

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-attributes"
Expand Down Expand Up @@ -137,23 +133,6 @@ namespace ranges {
}
};

// STRUCT TEMPLATE in_out_result
template <class _In, class _Out>
struct in_out_result {
[[no_unique_address]] _In in;
[[no_unique_address]] _Out out;

template <_Convertible_from<const _In&> _IIn, _Convertible_from<const _Out&> _OOut>
constexpr operator in_out_result<_IIn, _OOut>() const& {
return {in, out};
}

template <_Convertible_from<_In> _IIn, _Convertible_from<_Out> _OOut>
constexpr operator in_out_result<_IIn, _OOut>() && {
return {_STD move(in), _STD move(out)};
}
};

// STRUCT TEMPLATE in_in_out_result
template <class _In1, class _In2, class _Out>
struct in_in_out_result {
Expand Down
98 changes: 98 additions & 0 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,39 @@ _STL_DISABLE_CLANG_WARNINGS
#undef new

_STD_BEGIN
#ifdef __cpp_lib_concepts
namespace ranges {
// clang-format off
// CONCEPT _No_throw_input_iterator
template <class _It>
concept _No_throw_input_iterator = input_iterator<_It>
&& is_lvalue_reference_v<iter_reference_t<_It>>
&& same_as<remove_cvref_t<iter_reference_t<_It>>, iter_value_t<_It>>;

// CONCEPT _No_throw_sentinel_for
template <class _Se, class _It>
concept _No_throw_sentinel_for = sentinel_for<_Se, _It>;

// CONCEPT _No_throw_forward_iterator
template <class _It>
concept _No_throw_forward_iterator = _No_throw_input_iterator<_It>
&& forward_iterator<_It>
&& _No_throw_sentinel_for<_It, _It>;

// CONCEPT _No_throw_input_range
template <class _Rng>
concept _No_throw_input_range = range<_Rng>
&& _No_throw_input_iterator<iterator_t<_Rng>>
&& _No_throw_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>;

// CONCEPT _No_throw_forward_range
template <class _Rng>
concept _No_throw_forward_range = _No_throw_input_range<_Rng>
&& _No_throw_forward_iterator<iterator_t<_Rng>>;
// clang-format on
} // namespace ranges
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE uninitialized_copy_n
#if _HAS_IF_CONSTEXPR
template <class _InIt, class _Diff, class _NoThrowFwdIt>
Expand Down Expand Up @@ -97,6 +130,71 @@ _NoThrowFwdIt uninitialized_move(const _InIt _First, const _InIt _Last, _NoThrow
return _Dest;
}

#ifdef __cpp_lib_concepts
namespace ranges {
// ALIAS TEMPLATE uninitialized_move_result
template <class _In, class _Out>
using uninitialized_move_result = in_out_result<_In, _Out>;

// VARIABLE ranges::uninitialized_move
class _Uninitialized_move_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;

// clang-format off
template <input_iterator _It1, sentinel_for<_It1> _Se1, _No_throw_forward_iterator _It2, _No_throw_sentinel_for<_It2> _Se2>
requires constructible_from<iter_value_t<_It2>, iter_rvalue_reference_t<_It1>>
uninitialized_move_result<_It1, _It2> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2) const {
// clang-format on
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
auto _UResult =
_Uninitialized_move_unchecked(_Get_unwrapped(_STD move(_First1)), _Get_unwrapped(_STD move(_Last1)),
_Get_unwrapped(_STD move(_First2)), _Get_unwrapped(_STD move(_Last2)));

_Seek_wrapped(_First1, _STD move(_UResult.in));
_Seek_wrapped(_First2, _STD move(_UResult.out));
return {_STD move(_First1), _STD move(_First2)};
}

// clang-format off
template <input_range _Rng1, _No_throw_forward_range _Rng2>
requires constructible_from<range_value_t<_Rng2>, range_rvalue_reference_t<_Rng1>>
uninitialized_move_result<borrowed_iterator_t<_Rng1>, borrowed_iterator_t<_Rng2>> operator()(
_Rng1&& _Range1, _Rng2&& _Range2) const {
// clang-format on
auto _First1 = _RANGES begin(_Range1);
auto _UResult = _Uninitialized_move_unchecked(
_Get_unwrapped(_STD move(_First1)), _Uend(_Range1), _Ubegin(_Range2), _Uend(_Range2));

_Seek_wrapped(_First1, _STD move(_UResult.in));
return {_STD move(_First1), _Rewrap_iterator(_Range2, _STD move(_UResult.out))};
}

private:
template <class _It1, class _Se1, class _It2, class _Se2>
_NODISCARD static uninitialized_move_result<_It1, _It2> _Uninitialized_move_unchecked(
_It1 _IFirst, const _Se1 _ILast, _It2 _OFirst, const _Se2 _OLast) {
_STL_INTERNAL_STATIC_ASSERT(input_iterator<_It1>);
_STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se1, _It1>);
_STL_INTERNAL_STATIC_ASSERT(_No_throw_forward_iterator<_It2>);
_STL_INTERNAL_STATIC_ASSERT(_No_throw_sentinel_for<_Se2, _It2>);
_STL_INTERNAL_STATIC_ASSERT(constructible_from<iter_value_t<_It2>, iter_rvalue_reference_t<_It1>>);

_Uninitialized_backout _Backout{_STD move(_OFirst)};

for (; _IFirst != _ILast && _Backout._Last != _OLast; ++_IFirst) {
_Backout._Emplace_back(_RANGES iter_move(_IFirst));
}

return {_STD move(_IFirst), _Backout._Release()};
}
};

inline constexpr _Uninitialized_move_fn uninitialized_move{_Not_quite_object::_Construct_tag{}};
} // namespace ranges
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE uninitialized_move_n
template <class _InIt, class _Diff, class _NoThrowFwdIt>
pair<_InIt, _NoThrowFwdIt> uninitialized_move_n(_InIt _First, const _Diff _Count_raw, _NoThrowFwdIt _Dest) {
Expand Down
66 changes: 56 additions & 10 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,19 @@ _Pointer _Refancy(_Pointer _Ptr) noexcept {
}

// FUNCTION TEMPLATE _Destroy_in_place
template <class _NoThrowFwdIt, class _NoThrowSentinel>
/* _CONSTEXPR20_DYNALLOC */ void _Destroy_range(_NoThrowFwdIt _First, _NoThrowSentinel _Last) noexcept;

template <class _Ty>
void _Destroy_in_place(_Ty& _Obj) noexcept {
_Obj.~_Ty();
/* _CONSTEXPR20_DYNALLOC */ void _Destroy_in_place(_Ty& _Obj) noexcept {
#if _HAS_IF_CONSTEXPR
if constexpr (is_array_v<_Ty>) {
_Destroy_range(_Obj, _Obj + extent_v<_Ty>);
} else
#endif // _HAS_IF_CONSTEXPR
{
_Obj.~_Ty();
}
}

// FUNCTION TEMPLATE _Const_cast
Expand Down Expand Up @@ -948,7 +958,8 @@ void _Pocs(_Alloc& _Left, _Alloc& _Right) noexcept {

// FUNCTION TEMPLATE _Destroy_range WITH ALLOC
template <class _Alloc>
void _Destroy_range(_Alloc_ptr_t<_Alloc> _First, const _Alloc_ptr_t<_Alloc> _Last, _Alloc& _Al) noexcept {
/* _CONSTEXPR20_DYNALLOC */ void _Destroy_range(
_Alloc_ptr_t<_Alloc> _First, const _Alloc_ptr_t<_Alloc> _Last, _Alloc& _Al) noexcept {
// note that this is an optimization for debug mode codegen; in release mode the BE removes all of this
using _Ty = typename _Alloc::value_type;
if _CONSTEXPR_IF (!conjunction_v<is_trivially_destructible<_Ty>, _Uses_default_destroy<_Alloc, _Ty*>>) {
Expand All @@ -959,8 +970,8 @@ void _Destroy_range(_Alloc_ptr_t<_Alloc> _First, const _Alloc_ptr_t<_Alloc> _Las
}

// FUNCTION TEMPLATE _Destroy_range
template <class _NoThrowFwdIt>
void _Destroy_range(_NoThrowFwdIt _First, const _NoThrowFwdIt _Last) noexcept {
template <class _NoThrowFwdIt, class _NoThrowSentinel>
/* _CONSTEXPR20_DYNALLOC */ void _Destroy_range(_NoThrowFwdIt _First, const _NoThrowSentinel _Last) noexcept {
// note that this is an optimization for debug mode codegen; in release mode the BE removes all of this
if _CONSTEXPR_IF (!is_trivially_destructible_v<_Iter_value_t<_NoThrowFwdIt>>) {
for (; _First != _Last; ++_First) {
Expand Down Expand Up @@ -1414,29 +1425,64 @@ struct _Uninitialized_backout { // struct to undo partially constructed ranges i
_NoThrowFwdIt _First;
_NoThrowFwdIt _Last;

explicit _Uninitialized_backout(_NoThrowFwdIt _Dest) : _First(_Dest), _Last(_Dest) {}
constexpr explicit _Uninitialized_backout(_NoThrowFwdIt _Dest) : _First(_Dest), _Last(_Dest) {}

_Uninitialized_backout(_NoThrowFwdIt _First_, _NoThrowFwdIt _Last_) : _First(_First_), _Last(_Last_) {}
constexpr _Uninitialized_backout(_NoThrowFwdIt _First_, _NoThrowFwdIt _Last_) : _First(_First_), _Last(_Last_) {}

_Uninitialized_backout(const _Uninitialized_backout&) = delete;
_Uninitialized_backout& operator=(const _Uninitialized_backout&) = delete;

~_Uninitialized_backout() {
/* _CONSTEXPR20_DYNALLOC */ ~_Uninitialized_backout() {
_Destroy_range(_First, _Last);
}

template <class... _Types>
void _Emplace_back(_Types&&... _Vals) { // construct a new element at *_Last and increment
/* _CONSTEXPR20_DYNALLOC */ void _Emplace_back(_Types&&... _Vals) {
// construct a new element at *_Last and increment
_Construct_in_place(*_Last, _STD forward<_Types>(_Vals)...);
++_Last;
}

_NoThrowFwdIt _Release() { // suppress any exception handling backout and return _Last
/* _CONSTEXPR20_DYNALLOC */ _NoThrowFwdIt _Release() { // suppress any exception handling backout and return _Last
_First = _Last;
return _Last;
}
};

#ifdef __cpp_lib_concepts
namespace ranges {
// CONCEPT _Convertible_from
template <class _To, class _From>
concept _Convertible_from = convertible_to<_From, _To>;

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-attributes"
#endif // __clang__

// STRUCT TEMPLATE in_out_result
template <class _In, class _Out>
struct in_out_result {
[[no_unique_address]] _In in;
[[no_unique_address]] _Out out;

template <_Convertible_from<const _In&> _IIn, _Convertible_from<const _Out&> _OOut>
constexpr operator in_out_result<_IIn, _OOut>() const& {
return {in, out};
}

template <_Convertible_from<_In> _IIn, _Convertible_from<_Out> _OOut>
constexpr operator in_out_result<_IIn, _OOut>() && {
return {_STD move(in), _STD move(out)};
}
};

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
} // namespace ranges
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE _Uninitialized_move_unchecked
#if _HAS_IF_CONSTEXPR
template <class _InIt, class _NoThrowFwdIt>
Expand Down
3 changes: 1 addition & 2 deletions tests/std/include/range_algorithm_support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,7 @@ namespace test {
++ptr_;
}

[[nodiscard]] constexpr friend std::remove_cv_t<Element> iter_move(iterator const& i)
requires at_least<input> && std::constructible_from<std::remove_cv_t<Element>, Element> {
[[nodiscard]] constexpr friend Element&& iter_move(iterator const& i) requires at_least<input> {
return std::move(*i.ptr_);
}

Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ tests\P0896R4_ranges_alg_shuffle
tests\P0896R4_ranges_alg_swap_ranges
tests\P0896R4_ranges_alg_transform_binary
tests\P0896R4_ranges_alg_transform_unary
tests\P0896R4_ranges_alg_uninitialized_move
tests\P0896R4_ranges_alg_unique
tests\P0896R4_ranges_alg_unique_copy
tests\P0896R4_ranges_iterator_machinery
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P0896R4_ranges_alg_uninitialized_move/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_matrix.lst
Loading