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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem
The STL uses boost-math headers to provide P0226R1 Mathematical Special Functions. We recommend using [vcpkg][] to
acquire this dependency.

1. Install Visual Studio 2019 16.8 Preview 3 or later.
1. Install Visual Studio 2019 16.8 Preview 4 or later.
* We recommend selecting "C++ CMake tools for Windows" in the VS Installer.
This will ensure that you're using supported versions of CMake and Ninja.
* Otherwise, install [CMake][] 3.17 or later, and [Ninja][] 1.8.2 or later.
Expand All @@ -158,7 +158,7 @@ acquire this dependency.

# How To Build With A Native Tools Command Prompt

1. Install Visual Studio 2019 16.8 Preview 3 or later.
1. Install Visual Studio 2019 16.8 Preview 4 or later.
* We recommend selecting "C++ CMake tools for Windows" in the VS Installer.
This will ensure that you're using supported versions of CMake and Ninja.
* Otherwise, install [CMake][] 3.17 or later, and [Ninja][] 1.8.2 or later.
Expand Down Expand Up @@ -235,7 +235,7 @@ C:\Users\username\Desktop>dumpbin /IMPORTS .\example.exe | findstr msvcp

1. Follow either [How To Build With A Native Tools Command Prompt][] or [How To Build With The Visual Studio IDE][].
2. Invoke `git submodule update --init llvm-project` at the root of the STL source tree.
3. Acquire [Python][] 3.8 or newer and have it on the `PATH` (or run it directly using its absolute or relative path).
3. Acquire [Python][] 3.9 or newer and have it on the `PATH` (or run it directly using its absolute or relative path).
4. Have LLVM's `bin` directory on the `PATH` (so `clang-cl.exe` is available).
* We recommend selecting "C++ Clang tools for Windows" in the VS Installer. This will automatically add LLVM to the
`PATH` of the x86 and x64 Native Tools Command Prompts, and will ensure that you're using a supported version.
Expand Down
2 changes: 1 addition & 1 deletion azure-devops/provision-image.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ $Workloads = @(
$ReleaseInPath = 'Preview'
$Sku = 'Enterprise'
$VisualStudioBootstrapperUrl = 'https://aka.ms/vs/16/pre/vs_enterprise.exe'
$PythonUrl = 'https://www.python.org/ftp/python/3.8.5/python-3.8.5-amd64.exe'
$PythonUrl = 'https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe'

$CudaUrl = `
'https://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_426.00_win10.exe'
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
variables:
tmpDir: 'D:\Temp'

pool: 'StlBuild-2020-09-14'
pool: 'StlBuild-2020-10-13'

stages:
- stage: Code_Format
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/condition_variable
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public:
template <class _Lock, class _Rep, class _Period, class _Predicate>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred) {
// wait for signal with timeout and check predicate
return wait_until(_Lck, chrono::steady_clock::now() + _Rel_time, _STD move(_Pred));
return wait_until(_Lck, _To_absolute_time(_Rel_time), _STD move(_Pred));
}

template <class _Lock>
Expand Down Expand Up @@ -232,7 +232,7 @@ public:

template <class _Lock, class _Rep, class _Period, class _Predicate>
bool wait_for(_Lock& _Lck, stop_token _Stoken, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred) {
return wait_until(_Lck, _STD move(_Stoken), chrono::steady_clock::now() + _Rel_time, _STD move(_Pred));
return wait_until(_Lck, _STD move(_Stoken), _To_absolute_time(_Rel_time), _STD move(_Pred));
}
#endif // _HAS_CXX20

Expand Down
116 changes: 52 additions & 64 deletions stl/inc/experimental/generator
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#error <experimental/generator> requires /std:c++latest or /await compiler options
#endif // ^^^ no coroutine support ^^^


#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
Expand All @@ -33,18 +32,16 @@ _STL_DISABLE_CLANG_WARNINGS
_STD_BEGIN

namespace experimental {

template <typename _Ty, typename _Alloc = allocator<char>>
// NOTE WELL: _CPPUNWIND currently affects the ABI of generator.
template <class _Ty, class _Alloc = allocator<char>>
struct generator {
struct promise_type {
_Ty const* _CurrentValue;
#if 1 // TRANSITION, VSO-1172852
#ifdef _CPPUNWIND
exception_ptr _Eptr;
#endif // _CPPUNWIND
const _Ty* _Value;
#ifdef _CPPUNWIND // TRANSITION, VSO-1172852
exception_ptr _Exception;
#endif // TRANSITION, VSO-1172852

auto get_return_object() {
generator get_return_object() noexcept {
return generator{*this};
}

Expand All @@ -56,38 +53,38 @@ namespace experimental {
return {};
}

#if defined(_CPPUNWIND) || defined(__cpp_impl_coroutine)
void unhandled_exception() noexcept {
#if 1 // TRANSITION, VSO-1172852
#ifndef _KERNEL_MODE
#ifdef _CPPUNWIND
_Eptr = _STD current_exception();
#else // ^^^ _CPPUNWIND / !_CPPUNWIND vvv
abort();
#endif // _CPPUNWIND
#if 1 // TRANSITION, VSO-1172852
void unhandled_exception() noexcept {
_Exception = _STD current_exception();
}
#else // ^^^ workaround / no workaround vvv
void unhandled_exception() {
throw;
#endif // TRANSITION, VSO-1172852
}
#endif // defined(_CPPUNWIND) || defined(__cpp_impl_coroutine)
#endif // TRANSITION, VSO-1172852
#else // ^^^ defined(_CPPUNWIND) / !defined(_CPPUNWIND) vvv
void unhandled_exception() noexcept {}
#endif // _CPPUNWIND
#endif // _KERNEL_MODE

#if 1 // TRANSITION, VSO-1172852
#ifdef _CPPUNWIND // TRANSITION, VSO-1172852
void _Rethrow_if_exception() {
#ifdef _CPPUNWIND
if (_Eptr) {
_STD rethrow_exception(_Eptr);
if (_Exception) {
_STD rethrow_exception(_Exception);
}
#endif // _CPPUNWIND
}
#endif // TRANSITION, VSO-1172852

auto yield_value(_Ty const& _Value) {
_CurrentValue = _STD addressof(_Value);
return suspend_always{};
suspend_always yield_value(const _Ty& _Val) noexcept {
_Value = _STD addressof(_Val);
return {};
}

void return_void() {}
void return_void() noexcept {}

template <typename _Uty>
template <class _Uty>
_Uty&& await_transform(_Uty&& _Whatever) {
static_assert(_Always_false<_Uty>,
"co_await is not supported in coroutines of type std::experimental::generator");
Expand All @@ -98,15 +95,16 @@ namespace experimental {
static_assert(is_same_v<char*, typename allocator_traits<_Alloc_char>::pointer>,
"generator does not support allocators with fancy pointer types");
static_assert(
allocator_traits<_Alloc_char>::is_always_equal::value, "generator only supports stateless allocators");
allocator_traits<_Alloc_char>::is_always_equal::value && is_default_constructible_v<_Alloc_char>,
"generator supports only stateless allocators");

static void* operator new(size_t _Size) {
_Alloc_char _Al;
_Alloc_char _Al{};
return allocator_traits<_Alloc_char>::allocate(_Al, _Size);
}

static void operator delete(void* _Ptr, size_t _Size) noexcept {
_Alloc_char _Al;
_Alloc_char _Al{};
return allocator_traits<_Alloc_char>::deallocate(_Al, static_cast<char*>(_Ptr), _Size);
}
};
Expand All @@ -115,21 +113,19 @@ namespace experimental {
using iterator_category = input_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = _Ty;
using reference = _Ty const&;
using pointer = _Ty const*;
using reference = const _Ty&;
using pointer = const _Ty*;

coroutine_handle<promise_type> _Coro = nullptr;

iterator() = default;
iterator(nullptr_t) : _Coro(nullptr) {}

iterator(coroutine_handle<promise_type> _CoroArg) : _Coro(_CoroArg) {}
explicit iterator(coroutine_handle<promise_type> _Coro_) noexcept : _Coro(_Coro_) {}

iterator& operator++() {
_Coro.resume();
if (_Coro.done()) {
#if 1 // TRANSITION, VSO-1172852
_STD exchange(_Coro, {}).promise()._Rethrow_if_exception();
#ifdef _CPPUNWIND // TRANSITION, VSO-1172852
_STD exchange(_Coro, nullptr).promise()._Rethrow_if_exception();
#else // ^^^ workaround / no workaround vvv
_Coro = nullptr;
#endif // TRANSITION, VSO-1172852
Expand All @@ -139,61 +135,54 @@ namespace experimental {
}

void operator++(int) {
// This postincrement operator meets the requirements of the Ranges TS
// InputIterator concept, but not those of Standard C++ InputIterator.
// This operator meets the requirements of the C++20 input_iterator concept,
// but not the Cpp17InputIterator requirements.
++*this;
}

_NODISCARD bool operator==(iterator const& _Right) const {
_NODISCARD bool operator==(const iterator& _Right) const noexcept {
return _Coro == _Right._Coro;
}

_NODISCARD bool operator!=(iterator const& _Right) const {
_NODISCARD bool operator!=(const iterator& _Right) const noexcept {
return !(*this == _Right);
}

_NODISCARD reference operator*() const {
return *_Coro.promise()._CurrentValue;
_NODISCARD reference operator*() const noexcept {
return *_Coro.promise()._Value;
}

_NODISCARD pointer operator->() const {
return _Coro.promise()._CurrentValue;
_NODISCARD pointer operator->() const noexcept {
return _Coro.promise()._Value;
}
};

_NODISCARD iterator begin() {
if (_Coro) {
_Coro.resume();
if (_Coro.done()) {
#if 1 // TRANSITION, VSO-1172852
#ifdef _CPPUNWIND // TRANSITION, VSO-1172852
_Coro.promise()._Rethrow_if_exception();
#endif // TRANSITION, VSO-1172852
return {nullptr};
return {};
}
}

return {_Coro};
return iterator{_Coro};
}

_NODISCARD iterator end() {
return {nullptr};
_NODISCARD iterator end() noexcept {
return {};
}

explicit generator(promise_type& _Prom) : _Coro(coroutine_handle<promise_type>::from_promise(_Prom)) {}
explicit generator(promise_type& _Prom) noexcept : _Coro(coroutine_handle<promise_type>::from_promise(_Prom)) {}

generator() = default;
generator(generator const&) = delete;
generator& operator=(generator const&) = delete;
generator() = default;

generator(generator&& _Right) : _Coro(_Right._Coro) {
_Right._Coro = nullptr;
}
generator(generator&& _Right) noexcept : _Coro(_STD exchange(_Right._Coro, nullptr)) {}

generator& operator=(generator&& _Right) {
if (this != _STD addressof(_Right)) {
_Coro = _Right._Coro;
_Right._Coro = nullptr;
}
generator& operator=(generator&& _Right) noexcept {
_Coro = _STD exchange(_Right._Coro, nullptr);
return *this;
}

Expand All @@ -206,7 +195,6 @@ namespace experimental {
private:
coroutine_handle<promise_type> _Coro = nullptr;
};

} // namespace experimental

_STD_END
Expand Down
Loading