Skip to content
Open
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
641 changes: 641 additions & 0 deletions stl/inc/execution

Large diffs are not rendered by default.

109 changes: 2 additions & 107 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -60,111 +60,6 @@ namespace ranges {
template <bool _IsWrapped, class _Ty>
using _Maybe_wrapped = conditional_t<_IsWrapped, _Ty, _Unwrapped_t<_Ty>>;

namespace _Pipe {
// clang-format off
template <class _Left, class _Right>
concept _Can_pipe = requires(_Left&& __l, _Right&& __r) {
static_cast<_Right&&>(__r)(static_cast<_Left&&>(__l));
};

template <class _Left, class _Right>
concept _Can_compose = constructible_from<remove_cvref_t<_Left>, _Left>
&& constructible_from<remove_cvref_t<_Right>, _Right>;
// clang-format on

template <class, class>
struct _Pipeline;

template <class _Derived>
struct _Base {
template <class _Other>
requires _Can_compose<_Derived, _Other>
constexpr auto operator|(_Base<_Other>&& __r) && noexcept(
noexcept(_Pipeline{static_cast<_Derived&&>(*this), static_cast<_Other&&>(__r)})) {
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<_Derived&&>(*this), static_cast<_Other&&>(__r)};
}

template <class _Other>
requires _Can_compose<_Derived, const _Other&>
constexpr auto operator|(const _Base<_Other>& __r) && noexcept(
noexcept(_Pipeline{static_cast<_Derived&&>(*this), static_cast<const _Other&>(__r)})) {
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<_Derived&&>(*this), static_cast<const _Other&>(__r)};
}

template <class _Other>
requires _Can_compose<const _Derived&, _Other>
constexpr auto operator|(_Base<_Other>&& __r) const& noexcept(
noexcept(_Pipeline{static_cast<const _Derived&>(*this), static_cast<_Other&&>(__r)})) {
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<const _Derived&>(*this), static_cast<_Other&&>(__r)};
}

template <class _Other>
requires _Can_compose<const _Derived&, const _Other&>
constexpr auto operator|(const _Base<_Other>& __r) const& noexcept(
noexcept(_Pipeline{static_cast<const _Derived&>(*this), static_cast<const _Other&>(__r)})) {
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<const _Derived&>(*this), static_cast<const _Other&>(__r)};
}

template <_Can_pipe<const _Derived&> _Left>
friend constexpr auto operator|(_Left&& __l, const _Base& __r)
#ifdef __EDG__ // TRANSITION, VSO-1222776
noexcept(noexcept(_STD declval<const _Derived&>()(_STD forward<_Left>(__l))))
#else // ^^^ workaround / no workaround vvv
noexcept(noexcept(static_cast<const _Derived&>(__r)(_STD forward<_Left>(__l))))
#endif // TRANSITION, VSO-1222776
{
return static_cast<const _Derived&>(__r)(_STD forward<_Left>(__l));
}

template <_Can_pipe<_Derived> _Left>
friend constexpr auto operator|(_Left&& __l, _Base&& __r)
#ifdef __EDG__ // TRANSITION, VSO-1222776
noexcept(noexcept(_STD declval<_Derived>()(_STD forward<_Left>(__l))))
#else // ^^^ workaround / no workaround vvv
noexcept(noexcept(static_cast<_Derived&&>(__r)(_STD forward<_Left>(__l))))
#endif // TRANSITION, VSO-1222776
{
return static_cast<_Derived&&>(__r)(_STD forward<_Left>(__l));
}
};

template <class _Left, class _Right>
struct _Pipeline : _Base<_Pipeline<_Left, _Right>> {
/* [[no_unique_address]] */ _Left __l;
/* [[no_unique_address]] */ _Right __r;

template <class _Ty1, class _Ty2>
constexpr explicit _Pipeline(_Ty1&& _Val1, _Ty2&& _Val2) noexcept(
is_nothrow_convertible_v<_Ty1, _Left>&& is_nothrow_convertible_v<_Ty2, _Right>)
: __l(_STD forward<_Ty1>(_Val1)), __r(_STD forward<_Ty2>(_Val2)) {}

template <class _Ty>
_NODISCARD constexpr auto operator()(_Ty&& _Val) noexcept(
noexcept(__r(__l(_STD forward<_Ty>(_Val))))) requires requires {
__r(__l(static_cast<_Ty&&>(_Val)));
}
{ return __r(__l(_STD forward<_Ty>(_Val))); }

template <class _Ty>
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
noexcept(noexcept(__r(__l(_STD forward<_Ty>(_Val))))) requires requires {
__r(__l(static_cast<_Ty&&>(_Val)));
}
{ return __r(__l(_STD forward<_Ty>(_Val))); }
};

template <class _Ty1, class _Ty2>
_Pipeline(_Ty1, _Ty2) -> _Pipeline<_Ty1, _Ty2>;
} // namespace _Pipe

template <range _Rng, class _Derived>
class _Cached_position : public view_interface<_Derived> {
static_assert(_Always_false<_Rng>, "A range must be at least forward for position caching to be worthwhile.");
Expand Down Expand Up @@ -3906,7 +3801,7 @@ namespace ranges {
#else // ^^^ no workaround / workaround vvv
auto _Match = _RANGES search(subrange{_Current, _Last}, _Parent->_Pattern);
auto _Begin = _Match.begin();
auto _End = _Match.end();
auto _End = _Match.end();
#endif // TRANSITION, DevCom-1559808
if (_Begin != _Last && _RANGES empty(_Parent->_Pattern)) {
++_Begin;
Expand Down Expand Up @@ -3958,7 +3853,7 @@ namespace ranges {
#else // ^^^ no workaround / workaround vvv
auto _Match = _RANGES search(subrange{_It, _Last}, _Pattern);
auto _Begin = _Match.begin();
auto _End = _Match.end();
auto _End = _Match.end();
#endif // TRANSITION, DevCom-1559808
if (_Begin != _Last && _RANGES empty(_Pattern)) {
++_Begin;
Expand Down
7 changes: 7 additions & 0 deletions stl/inc/stop_token
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,13 @@ private:
template <class _Callback>
stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;

#ifdef __cpp_lib_executors
// TRANSITION: Implement stop token part
class never_stop_token {
_NODISCARD friend constexpr bool operator==(never_stop_token, never_stop_token) = default;
};
#endif // __cpp_lib_executors

_STD_END
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
Expand Down
115 changes: 115 additions & 0 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2276,6 +2276,121 @@ constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc&
_STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...));
}
#endif // _HAS_CXX20

#ifdef __cpp_lib_ranges
namespace ranges::_Pipe {
// clang-format off
template <class _Left, class _Right>
concept _Can_pipe = requires(_Left&& __l, _Right&& __r) {
static_cast<_Right&&>(__r)(static_cast<_Left&&>(__l));
};

template <class _Left, class _Right>
concept _Can_compose = constructible_from<remove_cvref_t<_Left>, _Left>
&& constructible_from<remove_cvref_t<_Right>, _Right>;
// clang-format on

template <class, class>
struct _Pipeline;

template <class _Derived>
struct _Base {
// clang-format off
template <class _Other>
requires _Can_compose<_Derived, _Other>
constexpr auto operator|(_Base<_Other>&& __r) && noexcept(
noexcept(_Pipeline{static_cast<_Derived&&>(*this), static_cast<_Other&&>(__r)})) {
// clang-format on
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<_Derived&&>(*this), static_cast<_Other&&>(__r)};
}

// clang-format off
template <class _Other>
requires _Can_compose<_Derived, const _Other&>
constexpr auto operator|(const _Base<_Other>& __r) && noexcept(
noexcept(_Pipeline{static_cast<_Derived&&>(*this), static_cast<const _Other&>(__r)})) {
// clang-format on
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<_Derived&&>(*this), static_cast<const _Other&>(__r)};
}

// clang-format off
template <class _Other>
requires _Can_compose<const _Derived&, _Other>
constexpr auto operator|(_Base<_Other>&& __r) const& noexcept(
noexcept(_Pipeline{static_cast<const _Derived&>(*this), static_cast<_Other&&>(__r)})) {
// clang-format on
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<const _Derived&>(*this), static_cast<_Other&&>(__r)};
}

// clang-format off
template <class _Other>
requires _Can_compose<const _Derived&, const _Other&>
constexpr auto operator|(const _Base<_Other>& __r) const& noexcept(
noexcept(_Pipeline{static_cast<const _Derived&>(*this), static_cast<const _Other&>(__r)})) {
// clang-format on
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Derived, _Base<_Derived>>);
_STL_INTERNAL_STATIC_ASSERT(derived_from<_Other, _Base<_Other>>);
return _Pipeline{static_cast<const _Derived&>(*this), static_cast<const _Other&>(__r)};
}

template <_Can_pipe<const _Derived&> _Left>
friend constexpr auto operator|(_Left&& __l, const _Base& __r)
#ifdef __EDG__ // TRANSITION, VSO-1222776
noexcept(noexcept(_STD declval<const _Derived&>()(_STD forward<_Left>(__l))))
#else // ^^^ workaround / no workaround vvv
noexcept(noexcept(static_cast<const _Derived&>(__r)(_STD forward<_Left>(__l))))
#endif // TRANSITION, VSO-1222776
{
return static_cast<const _Derived&>(__r)(_STD forward<_Left>(__l));
}

template <_Can_pipe<_Derived> _Left>
friend constexpr auto operator|(_Left&& __l, _Base&& __r)
#ifdef __EDG__ // TRANSITION, VSO-1222776
noexcept(noexcept(_STD declval<_Derived>()(_STD forward<_Left>(__l))))
#else // ^^^ workaround / no workaround vvv
noexcept(noexcept(static_cast<_Derived&&>(__r)(_STD forward<_Left>(__l))))
#endif // TRANSITION, VSO-1222776
{
return static_cast<_Derived&&>(__r)(_STD forward<_Left>(__l));
}
};

template <class _Left, class _Right>
struct _Pipeline : _Base<_Pipeline<_Left, _Right>> {
/* [[no_unique_address]] */ _Left __l;
/* [[no_unique_address]] */ _Right __r;

template <class _Ty1, class _Ty2>
constexpr explicit _Pipeline(_Ty1&& _Val1, _Ty2&& _Val2) noexcept(
is_nothrow_convertible_v<_Ty1, _Left>&& is_nothrow_convertible_v<_Ty2, _Right>)
: __l(_STD forward<_Ty1>(_Val1)), __r(_STD forward<_Ty2>(_Val2)) {}

template <class _Ty>
_NODISCARD constexpr auto operator()(_Ty&& _Val) noexcept(
noexcept(__r(__l(_STD forward<_Ty>(_Val))))) requires requires {
__r(__l(static_cast<_Ty&&>(_Val)));
}
{ return __r(__l(_STD forward<_Ty>(_Val))); }

template <class _Ty>
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
noexcept(noexcept(__r(__l(_STD forward<_Ty>(_Val))))) requires requires {
__r(__l(static_cast<_Ty&&>(_Val)));
}
{ return __r(__l(_STD forward<_Ty>(_Val))); }
};

template <class _Ty1, class _Ty2>
_Pipeline(_Ty1, _Ty2) -> _Pipeline<_Ty1, _Ty2>;
} // namespace ranges::_Pipe
#endif // __cpp_lib_ranges
_STD_END

#pragma pop_macro("new")
Expand Down
92 changes: 92 additions & 0 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,98 @@ template <class _Fn, class... _Its>
using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Its>...>;
// clang-format on

#ifdef __cpp_lib_executors
template <class _Ty>
struct _Non_associated_entity {
struct _Type {
using type = _Ty;
};
};

template <class _Ty>
using _Unassociate = typename _Non_associated_entity<_Ty>::_Type;

template <class _Ty>
using _Reassociate = typename _Ty::type;

template <class _Ty>
concept _Non_associated = same_as<_Ty, _Unassociate<_Reassociate<_Ty>>>;


template <class _Fn, class... _Args>
concept _Callable = requires(_Fn&& __fn, _Args&&... __args) {
{_STD forward<_Fn>(__fn)(_STD forward<_Args>(__args)...)};
};

template <class _Fn, class... _Args>
concept _Nothrow_callable = requires(_Fn&& __fn, _Args&&... __args) {
{ _STD forward<_Fn>(__fn)(_STD forward<_Args>(__args)...) }
noexcept;
};

template <class _Fn, class... _Args>
using _Call_result_t = decltype(_STD declval<_Fn>()(_STD declval<_Args>()...));
template <auto& _Tag>
using tag_t = decay_t<decltype(_Tag)>;

namespace _Tag_invoke {
void tag_invoke();

template <class _Tag, class... _Args>
concept _Tag_invocable_no_adl = _Has_class_or_enum_type<_Tag> && requires {
{tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...)};
};

template <class _Tag, class... _Args>
concept _Nothrow_tag_invocable_no_adl = _Has_class_or_enum_type<_Tag> && requires {
{ tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...) }
noexcept;
};

template <class _Tag, class _Arg>
concept _Tag_observable_no_adl = _Has_class_or_enum_type<_Tag> && requires {
{ tag_invoke(_STD declval<_Tag>(), _STD declval<add_const_t<_Arg>>()) }
noexcept;
};

class _Cpo {
public:
template <class _Tag, class... _Args>
requires _Tag_invocable_no_adl<_Tag, _Args...>
constexpr auto operator()(_Tag _Tag_, _Args&&... _Args_) const
noexcept(noexcept(tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...)))
-> decltype(tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...)) {
return tag_invoke(_STD forward<_Tag>(_Tag_), _STD forward<_Args>(_Args_)...);
}
};
} // namespace _Tag_invoke

inline namespace _Cpos {
inline constexpr _Tag_invoke::_Cpo tag_invoke;
}

template <class _Tag, class... _Args>
concept tag_invocable = _Tag_invoke::_Tag_invocable_no_adl<_Tag, _Args...>;

template <class _Tag, class... _Args>
concept nothrow_tag_invocable = _Tag_invoke::_Nothrow_tag_invocable_no_adl<_Tag, _Args...>;

template <class _Tag, class _Arg>
concept tag_observable = _Tag_invoke::_Tag_observable_no_adl<_Tag, _Arg>;

template <class _Tag, class... _Args>
struct tag_invoke_result {};

template <class _Tag, class... _Args>
requires _Tag_invoke::_Tag_invocable_no_adl<_Tag, _Args...>
struct tag_invoke_result<_Tag, _Args...> {
using type = decltype(tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...));
};

template <class _Tag, class... _Args>
using tag_invoke_result_t = decltype(tag_invoke(_STD declval<_Tag>(), _STD declval<_Args>()...));
#endif // __cpp_lib_executors

#pragma warning(push)
#pragma warning(disable : 5046) // '%s': Symbol involving type with internal linkage not defined
#ifdef __clang__
Expand Down
4 changes: 3 additions & 1 deletion stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,8 @@
#define __cpp_lib_byteswap 202110L

#ifdef __cpp_lib_concepts
#define __cpp_lib_expected 202202L
#define __cpp_lib_executors 202306L
#define __cpp_lib_expected 202202L
#endif // __cpp_lib_concepts

#define __cpp_lib_invoke_r 202106L
Expand Down Expand Up @@ -1537,6 +1538,7 @@ compiler option, or define _ALLOW_RTCc_IN_STL to acknowledge that you have recei
#define _STD ::std::
#define _CHRONO ::std::chrono::
#define _RANGES ::std::ranges::
#define _EXEC ::std::execution::

// We use the stdext (standard extension) namespace to contain extensions that are not part of the current standard
#define _STDEXT_BEGIN namespace stdext {
Expand Down
5 changes: 5 additions & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@ tests\P2136R3_invoke_r
tests\P2162R2_std_visit_for_derived_classes_from_variant
tests\P2231R1_complete_constexpr_optional_variant
tests\P2273R3_constexpr_unique_ptr
tests\P2300R2_executors_factories
tests\P2300R2_executors_receiver
tests\P2300R2_executors_scheduler
tests\P2300R2_executors_sender
tests\P2300R2_executors_tag_invoke
tests\P2321R2_proxy_reference
tests\P2401R0_conditional_noexcept_for_exchange
tests\P2415R2_owning_view
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P2300R2_executors_adaptors_on/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 ..\strict_concepts_latest_matrix.lst
Loading