diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f977d62bd1..5029bd03aec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,8 +67,7 @@ add_compile_definitions( _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH WIN32_LEAN_AND_MEAN STRICT _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS _CRT_DECLARE_NONSTDC_NAMES=1 ) -# TRANSITION, /analyze ? -add_compile_options(/diagnostics:caret /W4 /WX /w14265 /w15038 /d1FastFail /guard:cf /Z7 /d2Zi+ /Gm- /Gy /Zp8 /std:c++latest /permissive- /Zc:threadSafeInit- /Zl) +add_compile_options(/diagnostics:caret /W4 /WX /w14265 /w15038 /d1FastFail /guard:cf /Z7 /Gm- /Gy /Zp8 /std:c++latest /permissive- /Zc:threadSafeInit- /Zl) set(VCLIBS_DEBUG_OPTIONS "/Od") set(VCLIBS_RELEASE_OPTIONS "/O2;/Os") # TRANSITION: Potentially remove /Os diff --git a/README.md b/README.md index 5b361a006e4..0a4d9dff453 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # Microsoft's C++ Standard Library This is the official repository for Microsoft's implementation of the C++ Standard Library (also known as the STL), -which ships as part of the MSVC toolset and the Visual Studio IDE. Our [Changelog][] tracks which updates to this -repository appear in each VS release. +which ships as part of the MSVC toolset and the Visual Studio IDE. + +* Our [Changelog][] tracks which updates to this repository appear in each VS release. +* Our [Status Chart][] displays our overall progress over time. +* Join our [Discord server][]. [![Build Status](https://dev.azure.com/vclibs/STL/_apis/build/status/microsoft.STL?branchName=master)][Pipelines] @@ -140,38 +143,46 @@ 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 1 or later. -2. Invoke `git clone https://github.com/microsoft/vcpkg` -3. Invoke `cd vcpkg` -4. Invoke `.\bootstrap-vcpkg.bat` -5. Assuming you are targeting x86 and x64, invoke `.\vcpkg.exe install boost-math:x86-windows boost-math:x64-windows` - to install the boost-math dependency. Add `boost-math:arm-windows boost-math:arm64-windows` to this to target ARM - and ARM64. -6. Run `.\vcpkg.exe integrate install` which tells Visual Studio which vcpkg instance you wish to use. If you have never - done this before, you may be prompted to elevate. -7. Open Visual Studio, and choose the "Clone or check out code" option. Enter the URL to this - repository, typically `https://github.com/microsoft/STL` -8. Choose the architecture you wish to build in the IDE, and build as you would any other project. All necessary CMake - settings are set by `CMakeSettings.json` and `vcpkg integrate` +1. Install Visual Studio 2019 16.8 Preview 2 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. +2. Open Visual Studio, and choose the "Clone or check out code" option. Enter the URL of this repository, + `https://github.com/microsoft/STL`. +3. Open a terminal in the IDE with `` Ctrl + ` `` (by default) or press on "View" in the top bar, and then "Terminal". +4. In the terminal, invoke `git submodule update --init vcpkg` +5. In the terminal, invoke `.\vcpkg\bootstrap-vcpkg.bat` +6. In the terminal, invoke `.\vcpkg\vcpkg.exe install boost-math:x86-windows boost-math:x64-windows` +7. Choose the architecture you wish to build in the IDE, and build as you would any other project. All necessary CMake + settings are set by `CMakeSettings.json`. # How To Build With A Native Tools Command Prompt -These instructions assume you're targeting `x64-windows`; you can change this constant below to target other -architectures. - -1. Install Visual Studio 2019 16.8 Preview 1 or later. +1. Install Visual Studio 2019 16.8 Preview 2 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. -2. Open an "x64 Native Tools Command Prompt for VS 2019". +2. Open a command prompt. 3. Change directories to a location where you'd like a clone of this STL repository. -4. Invoke `git clone https://github.com/microsoft/STL` -5. Invoke `cd STL` -6. Invoke `git submodule update --init vcpkg` -7. Invoke `.\vcpkg\bootstrap-vcpkg.bat` -8. Invoke `.\vcpkg\vcpkg.exe install boost-math:x86-windows boost-math:x64-windows` to install the boost-math dependency. -9. Invoke `cmake -G Ninja -S . -B {wherever you want binaries}` to configure the project. For example, `cmake -G Ninja -S . -B out\build\x64` -10. Invoke `ninja -C {wherever you want binaries}` to build the project. For example, `ninja -C out\build\x64` +4. `git clone https://github.com/microsoft/STL` +5. `cd STL` +6. `git submodule update --init vcpkg` +7. `.\vcpkg\bootstrap-vcpkg.bat` +8. `.\vcpkg\vcpkg.exe install boost-math:x86-windows boost-math:x64-windows` + +To build the x86 target: + +1. Open an "x86 Native Tools Command Prompt for VS 2019". +2. Change directories to the previously cloned `STL` directory. +3. `cmake -G Ninja -S . -B out\build\x86` +4. `ninja -C out\build\x86` + +To build the x64 target: + +1. Open an "x64 Native Tools Command Prompt for VS 2019". +2. Change directories to the previously cloned `STL` directory. +3. `cmake -G Ninja -S . -B out\build\x64` +4. `ninja -C out\build\x64` # How To Consume @@ -197,26 +208,26 @@ for DLL dependencies according to directories in the `PATH` environment variable "x64 Native Tools Command Prompt for VS 2019": ``` -C:\Users\bion\Desktop>set INCLUDE=C:\Dev\STL\out\build\x64\out\inc;%INCLUDE% +C:\Users\username\Desktop>set INCLUDE=C:\Dev\STL\out\build\x64\out\inc;%INCLUDE% -C:\Users\bion\Desktop>set LIB=C:\Dev\STL\out\build\x64\out\lib\amd64;%LIB% +C:\Users\username\Desktop>set LIB=C:\Dev\STL\out\build\x64\out\lib\amd64;%LIB% -C:\Users\bion\Desktop>set PATH=C:\Dev\STL\out\build\x64\out\bin\amd64;%PATH% +C:\Users\username\Desktop>set PATH=C:\Dev\STL\out\build\x64\out\bin\amd64;%PATH% -C:\Users\bion\Desktop>type example.cpp +C:\Users\username\Desktop>type example.cpp #include int main() { std::cout << "Hello STL OSS world!\n"; } -C:\Users\bion\Desktop>cl /nologo /EHsc /W4 /WX /MDd /std:c++latest .\example.cpp +C:\Users\username\Desktop>cl /nologo /EHsc /W4 /WX /MDd /std:c++latest .\example.cpp example.cpp -C:\Users\bion\Desktop>.\example.exe +C:\Users\username\Desktop>.\example.exe Hello STL OSS world! -C:\Users\bion\Desktop>dumpbin /IMPORTS .\example.exe | findstr msvcp +C:\Users\username\Desktop>dumpbin /IMPORTS .\example.exe | findstr msvcp msvcp140d_oss.dll ``` @@ -245,29 +256,20 @@ under a category in libcxx, or running a single test in `std` and `tr1`. ## Examples -``` -:: This command will run all of the testsuites with verbose output. - -C:\STL\out\build\x64>ctest -V - -:: This command will also run all of the testsuites. - -C:\STL\out\build\x64>python tests\utils\stl-lit\stl-lit.py ..\..\..\llvm-project\libcxx\test ..\..\..\tests\std ..\..\..\tests\tr1 - -:: This command will run all of the std testsuite. - -C:\STL\out\build\x64>python tests\utils\stl-lit\stl-lit.py ..\..\..\tests\std - -:: If you want to run a subset of a testsuite you need to point it to the right place in the sources. The following -:: will run the single test found under VSO_0000000_any_calling_conventions. - -C:\STL\out\build\x64>python tests\utils\stl-lit\stl-lit.py ..\..\..\tests\std\tests\VSO_0000000_any_calling_conventions - -:: You can invoke stl-lit with any arbitrary subdirectory of a testsuite. In libcxx this allows you to have finer -:: control over what category of tests you would like to run. The following will run all the libcxx map tests. - -C:\STL\out\build\x64>python tests\utils\stl-lit\stl-lit.py ..\..\..\llvm-project\libcxx\test\std\containers\associative\map -``` +These examples assume that your current directory is `C:\Dev\STL\out\build\x64`. + +* This command will run all of the testsuites with verbose output. + + `ctest -V` +* This command will also run all of the testsuites. + + `python tests\utils\stl-lit\stl-lit.py ..\..\..\llvm-project\libcxx\test ..\..\..\tests\std ..\..\..\tests\tr1` +* This command will run all of the std testsuite. + + `python tests\utils\stl-lit\stl-lit.py ..\..\..\tests\std` +* If you want to run a subset of a testsuite, you need to point it to the right place in the sources. The following +will run the single test found under VSO_0000000_any_calling_conventions. + + `python tests\utils\stl-lit\stl-lit.py ..\..\..\tests\std\tests\VSO_0000000_any_calling_conventions` +* You can invoke `stl-lit` with any arbitrary subdirectory of a testsuite. In libcxx this allows you to have finer +control over what category of tests you would like to run. The following will run all the libcxx map tests. + + `python tests\utils\stl-lit\stl-lit.py ..\..\..\llvm-project\libcxx\test\std\containers\associative\map` ## Interpreting The Results Of Tests @@ -396,6 +398,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception [Code of Conduct FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ [Compiler Explorer]: https://godbolt.org [Developer Community]: https://developercommunity.visualstudio.com/spaces/62/index.html +[Discord server]: https://discord.gg/XWanNww [How To Build With A Native Tools Command Prompt]: #how-to-build-with-a-native-tools-command-prompt [How To Build With The Visual Studio IDE]: #how-to-build-with-the-visual-studio-ide [LICENSE.txt]: LICENSE.txt @@ -409,6 +412,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception [Pipelines]: https://dev.azure.com/vclibs/STL/_build/latest?definitionId=2&branchName=master [Python]: https://www.python.org/downloads/windows/ [Roadmap]: https://github.com/microsoft/STL/wiki/Roadmap +[Status Chart]: https://microsoft.github.io/STL/ [Wandbox]: https://wandbox.org [bug tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3Abug [cxx20 tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3Acxx20 diff --git a/azure-devops/create-vmss.ps1 b/azure-devops/create-vmss.ps1 index e476dd02f66..ad595569987 100644 --- a/azure-devops/create-vmss.ps1 +++ b/azure-devops/create-vmss.ps1 @@ -15,6 +15,8 @@ at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps or are running from Azure Cloud Shell. #> +$ErrorActionPreference = 'Stop' + $Location = 'westus2' $Prefix = 'StlBuild-' + (Get-Date -Format 'yyyy-MM-dd') $VMSize = 'Standard_D16as_v4' diff --git a/azure-devops/provision-image.ps1 b/azure-devops/provision-image.ps1 index 010233d008b..fb09a22eeea 100644 --- a/azure-devops/provision-image.ps1 +++ b/azure-devops/provision-image.ps1 @@ -99,7 +99,8 @@ $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' -$CudaUrl = 'https://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_426.00_win10.exe' +$CudaUrl = ` + 'https://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_426.00_win10.exe' $CudaFeatures = 'nvcc_10.1 cuobjdump_10.1 nvprune_10.1 cupti_10.1 gpu_library_advisor_10.1 memcheck_10.1 ' + ` 'nvdisasm_10.1 nvprof_10.1 visual_profiler_10.1 visual_studio_integration_10.1 cublas_10.1 cublas_dev_10.1 ' + ` 'cudart_10.1 cufft_10.1 cufft_dev_10.1 curand_10.1 curand_dev_10.1 cusolver_10.1 cusolver_dev_10.1 cusparse_10.1 ' + ` diff --git a/azure-devops/run-build.yml b/azure-devops/run-build.yml index 35e2f959607..0a517388607 100644 --- a/azure-devops/run-build.yml +++ b/azure-devops/run-build.yml @@ -65,6 +65,7 @@ jobs: cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=$(vcpkgLocation)\scripts\buildsystems\vcpkg.cmake ^ -DVCPKG_TARGET_TRIPLET=${{ parameters.targetPlatform }}-windows -DCMAKE_CXX_COMPILER=cl ^ -DCMAKE_BUILD_TYPE=Release -DLIT_FLAGS=$(litFlags) ^ + -DCMAKE_CXX_FLAGS=/analyze ^ -S $(Build.SourcesDirectory) -B $(buildOutputLocation) cmake --build $(buildOutputLocation) displayName: 'Build the STL' diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b9fa7b9da98..69b79c443a4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,7 @@ # Build STL targeting x86, x64, arm, arm64 variables: - agentPool: 'StlBuild-2020-08-11' + agentPool: 'StlBuild-2020-08-26' tmpDir: 'D:\Temp' stages: diff --git a/stl/inc/atomic b/stl/inc/atomic index 40a8edc9e93..07fd8d8316d 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -1058,7 +1058,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics return reinterpret_cast<_TVal&>(_As_bytes); } -#if defined(_M_IX86) && defined(__clang__) // TRANSITION, LLVM-46595 +#ifdef _M_IX86 _TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) noexcept { // exchange with (effectively) sequential consistency _TVal _Temp{load()}; @@ -1067,7 +1067,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics return _Temp; } -#else // ^^^ defined(_M_IX86) && defined(__clang__), LLVM-46595 / !defined(_M_IX86) || !defined(__clang__) vvv +#else // ^^^ _M_IX86 / !_M_IX86 vvv _TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) noexcept { // exchange with given memory order long long _As_bytes; @@ -1075,7 +1075,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics _Atomic_reinterpret_as(_Value)); return reinterpret_cast<_TVal&>(_As_bytes); } -#endif // ^^^ !defined(_M_IX86) || !defined(__clang__) ^^^ +#endif // _M_IX86 bool compare_exchange_strong(_TVal& _Expected, const _TVal _Desired, const memory_order _Order = memory_order_seq_cst) noexcept { // CAS with given memory order @@ -1517,7 +1517,7 @@ struct _Atomic_integral<_Ty, 8> : _Atomic_storage<_Ty> { // atomic integral oper using _Base::_Base; #endif // ^^^ no workaround ^^^ -#if defined(_M_IX86) && defined(__clang__) // TRANSITION, LLVM-46595 +#ifdef _M_IX86 _TVal fetch_add(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept { // effectively sequential consistency _TVal _Temp{this->load()}; @@ -1570,7 +1570,7 @@ struct _Atomic_integral<_Ty, 8> : _Atomic_storage<_Ty> { // atomic integral oper return fetch_add(static_cast<_TVal>(-1)) - static_cast<_TVal>(1); } -#else // ^^^ defined(_M_IX86) && defined(__clang__), LLVM-46595 / !defined(_M_IX86) || !defined(__clang__) vvv +#else // ^^^ _M_IX86 / !_M_IX86 vvv _TVal fetch_add(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept { long long _Result; _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _InterlockedExchangeAdd64, @@ -1620,7 +1620,7 @@ struct _Atomic_integral<_Ty, 8> : _Atomic_storage<_Ty> { // atomic integral oper _TVal operator--() noexcept { return static_cast<_TVal>(_InterlockedDecrement64(_Atomic_address_as(this->_Storage))); } -#endif // ^^^ !defined(_M_IX86) || !defined(__clang__) ^^^ +#endif // _M_IX86 }; #if 1 // TRANSITION, ABI diff --git a/stl/inc/deque b/stl/inc/deque index 8800b649baa..3da10106758 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -51,91 +51,91 @@ public: _Deque_unchecked_const_iterator(_Size_type _Off, const _Container_base12* _Pdeque) noexcept : _Mycont(static_cast(_Pdeque)), _Myoff(_Off) {} - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { _Size_type _Block = _Mycont->_Getblock(_Myoff); _Size_type _Off = _Myoff % _DEQUESIZ; return _Mycont->_Map[_Block][_Off]; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Deque_unchecked_const_iterator& operator++() { + _Deque_unchecked_const_iterator& operator++() noexcept { ++_Myoff; return *this; } - _Deque_unchecked_const_iterator operator++(int) { + _Deque_unchecked_const_iterator operator++(int) noexcept { _Deque_unchecked_const_iterator _Tmp = *this; ++_Myoff; return _Tmp; } - _Deque_unchecked_const_iterator& operator--() { + _Deque_unchecked_const_iterator& operator--() noexcept { --_Myoff; return *this; } - _Deque_unchecked_const_iterator operator--(int) { + _Deque_unchecked_const_iterator operator--(int) noexcept { _Deque_unchecked_const_iterator _Tmp = *this; --_Myoff; return _Tmp; } - _Deque_unchecked_const_iterator& operator+=(const difference_type _Off) { + _Deque_unchecked_const_iterator& operator+=(const difference_type _Off) noexcept { _Myoff += _Off; return *this; } - _NODISCARD _Deque_unchecked_const_iterator operator+(const difference_type _Off) const { + _NODISCARD _Deque_unchecked_const_iterator operator+(const difference_type _Off) const noexcept { _Deque_unchecked_const_iterator _Tmp = *this; return _Tmp += _Off; } - _Deque_unchecked_const_iterator& operator-=(const difference_type _Off) { + _Deque_unchecked_const_iterator& operator-=(const difference_type _Off) noexcept { _Myoff -= _Off; return *this; } - _NODISCARD _Deque_unchecked_const_iterator operator-(const difference_type _Off) const { + _NODISCARD _Deque_unchecked_const_iterator operator-(const difference_type _Off) const noexcept { _Deque_unchecked_const_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD difference_type operator-(const _Deque_unchecked_const_iterator& _Right) const noexcept { return static_cast(_Myoff - _Right._Myoff); } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } - _NODISCARD bool operator==(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Deque_unchecked_const_iterator& _Right) const noexcept { return _Myoff == _Right._Myoff; } - _NODISCARD bool operator!=(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Deque_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD bool operator<(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator<(const _Deque_unchecked_const_iterator& _Right) const noexcept { return _Myoff < _Right._Myoff; } - _NODISCARD bool operator>(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator>(const _Deque_unchecked_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD bool operator<=(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator<=(const _Deque_unchecked_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD bool operator>=(const _Deque_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator>=(const _Deque_unchecked_const_iterator& _Right) const noexcept { return !(*this < _Right); } - const _Container_base12* _Getcont() const { // get container pointer + const _Container_base12* _Getcont() const noexcept { // get container pointer return _Mycont; } @@ -146,7 +146,7 @@ public: template _NODISCARD _Deque_unchecked_const_iterator<_Mydeque> operator+( typename _Deque_unchecked_const_iterator<_Mydeque>::difference_type _Off, - _Deque_unchecked_const_iterator<_Mydeque> _Next) { + _Deque_unchecked_const_iterator<_Mydeque> _Next) noexcept { return _Next += _Off; } @@ -167,68 +167,69 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Deque_unchecked_iterator& operator++() { + _Deque_unchecked_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Deque_unchecked_iterator operator++(int) { + _Deque_unchecked_iterator operator++(int) noexcept { _Deque_unchecked_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Deque_unchecked_iterator& operator--() { + _Deque_unchecked_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Deque_unchecked_iterator operator--(int) { + _Deque_unchecked_iterator operator--(int) noexcept { _Deque_unchecked_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; } - _Deque_unchecked_iterator& operator+=(const difference_type _Off) { + _Deque_unchecked_iterator& operator+=(const difference_type _Off) noexcept { _Mybase::operator+=(_Off); return *this; } - _NODISCARD _Deque_unchecked_iterator operator+(const difference_type _Off) const { + _NODISCARD _Deque_unchecked_iterator operator+(const difference_type _Off) const noexcept { _Deque_unchecked_iterator _Tmp = *this; return _Tmp += _Off; } - _Deque_unchecked_iterator& operator-=(const difference_type _Off) { + _Deque_unchecked_iterator& operator-=(const difference_type _Off) noexcept { _Mybase::operator-=(_Off); return *this; } - _NODISCARD _Deque_unchecked_iterator operator-(const difference_type _Off) const { + _NODISCARD _Deque_unchecked_iterator operator-(const difference_type _Off) const noexcept { _Deque_unchecked_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _Mybase& _Right) const { + _NODISCARD difference_type operator-(const _Mybase& _Right) const noexcept { return _Mybase::operator-(_Right); } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return const_cast(_Mybase::operator[](_Off)); } }; template _NODISCARD _Deque_unchecked_iterator<_Mydeque> operator+( - typename _Deque_unchecked_iterator<_Mydeque>::difference_type _Off, _Deque_unchecked_iterator<_Mydeque> _Next) { + typename _Deque_unchecked_iterator<_Mydeque>::difference_type _Off, + _Deque_unchecked_iterator<_Mydeque> _Next) noexcept { return _Next += _Off; } @@ -256,7 +257,7 @@ public: _Setcont(static_cast(_Pdeque)); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { const auto _Mycont = static_cast(this->_Getcont()); #if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Mycont, "cannot dereference value-initialized deque iterator"); @@ -269,11 +270,11 @@ public: return _Mycont->_Map[_Block][_Off]; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Deque_const_iterator& operator++() { + _Deque_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Mycont, "cannot increment value-initialized deque iterator"); @@ -284,13 +285,13 @@ public: return *this; } - _Deque_const_iterator operator++(int) { + _Deque_const_iterator operator++(int) noexcept { _Deque_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _Deque_const_iterator& operator--() { + _Deque_const_iterator& operator--() noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Mycont, "cannot decrement value-initialized deque iterator"); @@ -301,13 +302,13 @@ public: return *this; } - _Deque_const_iterator operator--(int) { + _Deque_const_iterator operator--(int) noexcept { _Deque_const_iterator _Tmp = *this; --*this; return _Tmp; } - _Deque_const_iterator& operator+=(const difference_type _Off) { + _Deque_const_iterator& operator+=(const difference_type _Off) noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 if (_Off != 0) { const auto _Mycont = static_cast(this->_Getcont()); @@ -322,56 +323,56 @@ public: return *this; } - _NODISCARD _Deque_const_iterator operator+(const difference_type _Off) const { + _NODISCARD _Deque_const_iterator operator+(const difference_type _Off) const noexcept { _Deque_const_iterator _Tmp = *this; return _Tmp += _Off; } - _Deque_const_iterator& operator-=(const difference_type _Off) { + _Deque_const_iterator& operator-=(const difference_type _Off) noexcept { return *this += -_Off; } - _NODISCARD _Deque_const_iterator operator-(const difference_type _Off) const { + _NODISCARD _Deque_const_iterator operator-(const difference_type _Off) const noexcept { _Deque_const_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _Deque_const_iterator& _Right) const { + _NODISCARD difference_type operator-(const _Deque_const_iterator& _Right) const noexcept { _Compat(_Right); return static_cast(this->_Myoff - _Right._Myoff); } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } - _NODISCARD bool operator==(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Deque_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myoff == _Right._Myoff; } - _NODISCARD bool operator!=(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Deque_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD bool operator<(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator<(const _Deque_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myoff < _Right._Myoff; } - _NODISCARD bool operator>(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator>(const _Deque_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD bool operator<=(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator<=(const _Deque_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD bool operator>=(const _Deque_const_iterator& _Right) const { + _NODISCARD bool operator>=(const _Deque_const_iterator& _Right) const noexcept { return !(*this < _Right); } - void _Compat(const _Deque_const_iterator& _Right) const { // test for compatible iterator pair + void _Compat(const _Deque_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 (void) _Right; #else // _ITERATOR_DEBUG_LEVEL == 0 @@ -379,13 +380,13 @@ public: #endif // _ITERATOR_DEBUG_LEVEL == 0 } - void _Setcont(const _Mydeque* _Pdeque) { // set container pointer + void _Setcont(const _Mydeque* _Pdeque) noexcept { // set container pointer this->_Adopt(_Pdeque); } using _Prevent_inheriting_unwrap = _Deque_const_iterator; - _NODISCARD _Deque_unchecked_const_iterator<_Mydeque> _Unwrapped() const { + _NODISCARD _Deque_unchecked_const_iterator<_Mydeque> _Unwrapped() const noexcept { return {this->_Myoff, this->_Getcont()}; } @@ -404,13 +405,13 @@ public: } #if _ITERATOR_DEBUG_LEVEL != 0 - friend void _Verify_range(const _Deque_const_iterator& _First, const _Deque_const_iterator& _Last) { + friend void _Verify_range(const _Deque_const_iterator& _First, const _Deque_const_iterator& _Last) noexcept { // note _Compat check inside operator<= _STL_VERIFY(_First <= _Last, "deque iterators transposed"); } #endif // _ITERATOR_DEBUG_LEVEL != 0 - void _Seek_to(const _Deque_unchecked_const_iterator<_Mydeque>& _UIt) { + void _Seek_to(const _Deque_unchecked_const_iterator<_Mydeque>& _UIt) noexcept { _Myoff = _UIt._Myoff; } @@ -419,7 +420,7 @@ public: template _NODISCARD _Deque_const_iterator<_Mydeque> operator+( - typename _Deque_const_iterator<_Mydeque>::difference_type _Off, _Deque_const_iterator<_Mydeque> _Next) { + typename _Deque_const_iterator<_Mydeque>::difference_type _Off, _Deque_const_iterator<_Mydeque> _Next) noexcept { return _Next += _Off; } @@ -441,72 +442,72 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Deque_iterator& operator++() { + _Deque_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Deque_iterator operator++(int) { + _Deque_iterator operator++(int) noexcept { _Deque_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Deque_iterator& operator--() { + _Deque_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Deque_iterator operator--(int) { + _Deque_iterator operator--(int) noexcept { _Deque_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; } - _Deque_iterator& operator+=(const difference_type _Off) { + _Deque_iterator& operator+=(const difference_type _Off) noexcept { _Mybase::operator+=(_Off); return *this; } - _NODISCARD _Deque_iterator operator+(const difference_type _Off) const { + _NODISCARD _Deque_iterator operator+(const difference_type _Off) const noexcept { _Deque_iterator _Tmp = *this; return _Tmp += _Off; } - _Deque_iterator& operator-=(const difference_type _Off) { + _Deque_iterator& operator-=(const difference_type _Off) noexcept { _Mybase::operator-=(_Off); return *this; } using _Mybase::operator-; - _NODISCARD _Deque_iterator operator-(const difference_type _Off) const { + _NODISCARD _Deque_iterator operator-(const difference_type _Off) const noexcept { _Deque_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return const_cast(_Mybase::operator[](_Off)); } using _Prevent_inheriting_unwrap = _Deque_iterator; - _NODISCARD _Deque_unchecked_iterator<_Mydeque> _Unwrapped() const { + _NODISCARD _Deque_unchecked_iterator<_Mydeque> _Unwrapped() const noexcept { return {this->_Myoff, this->_Getcont()}; } }; template _NODISCARD _Deque_iterator<_Mydeque> operator+( - typename _Deque_iterator<_Mydeque>::difference_type _Off, _Deque_iterator<_Mydeque> _Next) { + typename _Deque_iterator<_Mydeque>::difference_type _Off, _Deque_iterator<_Mydeque> _Next) noexcept { return _Next += _Off; } diff --git a/stl/inc/exception b/stl/inc/exception index 37cf6e1227e..0b0f52e749c 100644 --- a/stl/inc/exception +++ b/stl/inc/exception @@ -204,7 +204,7 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrAssign(_Inout_ void*, _ _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrCompare(_In_ const void*, _In_ const void*) noexcept; _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrToBool(_In_ const void*) noexcept; _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*, _Inout_ void*) noexcept; -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(_Out_ void*) noexcept; +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void*) noexcept; [[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrRethrow(_In_ const void*); _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopyException( _Inout_ void*, _In_ const void*, _In_ const void*) noexcept; diff --git a/stl/inc/experimental/generator b/stl/inc/experimental/generator index af54662c112..60e2a896de7 100644 --- a/stl/inc/experimental/generator +++ b/stl/inc/experimental/generator @@ -38,10 +38,11 @@ namespace experimental { struct generator { struct promise_type { _Ty const* _CurrentValue; +#if 1 // TRANSITION, VSO-1172852 #ifdef _CPPUNWIND - // TRANSITION, VSO-967814 exception_ptr _Eptr; #endif // _CPPUNWIND +#endif // TRANSITION, VSO-1172852 auto get_return_object() { return generator{*this}; @@ -55,12 +56,21 @@ namespace experimental { return {}; } -#ifdef _CPPUNWIND +#if defined(_CPPUNWIND) || defined(__cpp_impl_coroutine) void unhandled_exception() noexcept { +#if 1 // TRANSITION, VSO-1172852 +#ifdef _CPPUNWIND _Eptr = _STD current_exception(); - } +#else // ^^^ _CPPUNWIND / !_CPPUNWIND vvv + abort(); #endif // _CPPUNWIND +#else // ^^^ workaround / no workaround vvv + throw; +#endif // TRANSITION, VSO-1172852 + } +#endif // defined(_CPPUNWIND) || defined(__cpp_impl_coroutine) +#if 1 // TRANSITION, VSO-1172852 void _Rethrow_if_exception() { #ifdef _CPPUNWIND if (_Eptr) { @@ -68,6 +78,7 @@ namespace experimental { } #endif // _CPPUNWIND } +#endif // TRANSITION, VSO-1172852 auto yield_value(_Ty const& _Value) { _CurrentValue = _STD addressof(_Value); @@ -117,7 +128,11 @@ namespace experimental { iterator& operator++() { _Coro.resume(); if (_Coro.done()) { +#if 1 // TRANSITION, VSO-1172852 _STD exchange(_Coro, {}).promise()._Rethrow_if_exception(); +#else // ^^^ workaround / no workaround vvv + _Coro = nullptr; +#endif // TRANSITION, VSO-1172852 } return *this; @@ -150,7 +165,9 @@ namespace experimental { if (_Coro) { _Coro.resume(); if (_Coro.done()) { +#if 1 // TRANSITION, VSO-1172852 _Coro.promise()._Rethrow_if_exception(); +#endif // TRANSITION, VSO-1172852 return {nullptr}; } } @@ -164,10 +181,8 @@ namespace experimental { explicit generator(promise_type& _Prom) : _Coro(coroutine_handle::from_promise(_Prom)) {} - generator() = default; - + generator() = default; generator(generator const&) = delete; - generator& operator=(generator const&) = delete; generator(generator&& _Right) : _Coro(_Right._Coro) { diff --git a/stl/inc/forward_list b/stl/inc/forward_list index 24227c66c43..59912a1d33c 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -40,30 +40,30 @@ public: this->_Adopt(_Plist); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return _Ptr->_Myval; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Flist_unchecked_const_iterator& operator++() { + _Flist_unchecked_const_iterator& operator++() noexcept { _Ptr = _Ptr->_Next; return *this; } - _Flist_unchecked_const_iterator operator++(int) { + _Flist_unchecked_const_iterator operator++(int) noexcept { _Flist_unchecked_const_iterator _Tmp = *this; _Ptr = _Ptr->_Next; return _Tmp; } - _NODISCARD bool operator==(const _Flist_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Flist_unchecked_const_iterator& _Right) const noexcept { return _Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _Flist_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Flist_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -93,20 +93,20 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Flist_unchecked_iterator& operator++() { + _Flist_unchecked_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Flist_unchecked_iterator operator++(int) { + _Flist_unchecked_iterator operator++(int) noexcept { _Flist_unchecked_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; @@ -128,7 +128,7 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 const auto _Mycont = static_cast(this->_Getcont()); _STL_ASSERT(_Mycont, "cannot dereference value-initialized forward_list iterator"); @@ -138,7 +138,7 @@ public: return this->_Ptr->_Myval; } - _Flist_const_iterator& operator++() { + _Flist_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(this->_Getcont(), "forward_list iterator not incrementable"); #endif // _ITERATOR_DEBUG_LEVEL == 2 @@ -147,13 +147,13 @@ public: return *this; } - _Flist_const_iterator operator++(int) { + _Flist_const_iterator operator++(int) noexcept { _Flist_const_iterator _Tmp = *this; this->_Ptr = this->_Ptr->_Next; return _Tmp; } - _NODISCARD bool operator==(const _Flist_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Flist_const_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "forward_list iterators incompatible"); #endif // _ITERATOR_DEBUG_LEVEL == 2 @@ -161,12 +161,12 @@ public: return this->_Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _Flist_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Flist_const_iterator& _Right) const noexcept { return !(*this == _Right); } #if _ITERATOR_DEBUG_LEVEL == 2 - friend void _Verify_range(const _Flist_const_iterator& _First, const _Flist_const_iterator& _Last) { + friend void _Verify_range(const _Flist_const_iterator& _First, const _Flist_const_iterator& _Last) noexcept { _STL_VERIFY( _First._Getcont() == _Last._Getcont(), "forward_list iterators in range are from different containers"); } @@ -178,7 +178,7 @@ public: return _Flist_unchecked_const_iterator<_Mylist>(this->_Ptr, static_cast(this->_Getcont())); } - void _Seek_to(const _Flist_unchecked_const_iterator<_Mylist> _It) { + void _Seek_to(const _Flist_unchecked_const_iterator<_Mylist> _It) noexcept { this->_Ptr = _It._Ptr; } }; @@ -198,20 +198,20 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Flist_iterator& operator++() { + _Flist_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Flist_iterator operator++(int) { + _Flist_iterator operator++(int) noexcept { _Flist_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; diff --git a/stl/inc/istream b/stl/inc/istream index d70df7689c4..c9c10b07cf4 100644 --- a/stl/inc/istream +++ b/stl/inc/istream @@ -876,9 +876,7 @@ template struct _Can_stream_in<_Istr, _Ty, void_t() >> _STD declval<_Ty>())>> : true_type {}; template >, is_base_of, _Can_stream_in<_Istr, _Ty>>, - int> = 0> + enable_if_t, _Can_stream_in<_Istr, _Ty>>, int> = 0> _Istr&& operator>>(_Istr&& _Is, _Ty&& _Val) { // extract from rvalue stream _Is >> _STD forward<_Ty>(_Val); return _STD move(_Is); diff --git a/stl/inc/iterator b/stl/inc/iterator index c2927f0d728..19d67597d39 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -770,11 +770,11 @@ public: _NODISCARD constexpr counted_iterator<_Unwrapped_t> _Unwrapped() const& requires _Unwrappable_v { - return static_cast>>(_Current._Unwrapped()); + return counted_iterator<_Unwrapped_t>{_Current._Unwrapped(), _Length}; } - _NODISCARD constexpr counted_iterator<_Unwrapped_t<_Iter>> _Unwrapped() && requires _Unwrappable_v { - return static_cast>>(_STD move(_Current)._Unwrapped()); + _NODISCARD constexpr counted_iterator<_Unwrapped_t<_Iter>> _Unwrapped() && requires _Unwrappable_v<_Iter> { + return counted_iterator<_Unwrapped_t<_Iter>>{_STD move(_Current)._Unwrapped(), _Length}; } static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<_Iter>; diff --git a/stl/inc/list b/stl/inc/list index a223036db12..269cb3ed122 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -40,41 +40,41 @@ public: this->_Adopt(_Plist); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return _Ptr->_Myval; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _List_unchecked_const_iterator& operator++() { + _List_unchecked_const_iterator& operator++() noexcept { _Ptr = _Ptr->_Next; return *this; } - _List_unchecked_const_iterator operator++(int) { + _List_unchecked_const_iterator operator++(int) noexcept { _List_unchecked_const_iterator _Tmp = *this; _Ptr = _Ptr->_Next; return _Tmp; } - _List_unchecked_const_iterator& operator--() { + _List_unchecked_const_iterator& operator--() noexcept { _Ptr = _Ptr->_Prev; return *this; } - _List_unchecked_const_iterator operator--(int) { + _List_unchecked_const_iterator operator--(int) noexcept { _List_unchecked_const_iterator _Tmp = *this; _Ptr = _Ptr->_Prev; return _Tmp; } - _NODISCARD bool operator==(const _List_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator==(const _List_unchecked_const_iterator& _Right) const noexcept { return _Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _List_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _List_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -96,31 +96,31 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _List_unchecked_iterator& operator++() { + _List_unchecked_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _List_unchecked_iterator operator++(int) { + _List_unchecked_iterator operator++(int) noexcept { _List_unchecked_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _List_unchecked_iterator& operator--() { + _List_unchecked_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _List_unchecked_iterator operator--(int) { + _List_unchecked_iterator operator--(int) noexcept { _List_unchecked_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; @@ -142,7 +142,7 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 const auto _Mycont = static_cast(this->_Getcont()); _STL_ASSERT(_Mycont, "cannot dereference value-initialized list iterator"); @@ -152,11 +152,11 @@ public: return this->_Ptr->_Myval; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _List_const_iterator& operator++() { + _List_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 const auto _Mycont = static_cast(this->_Getcont()); _STL_ASSERT(_Mycont, "cannot increment value-initialized list iterator"); @@ -167,13 +167,13 @@ public: return *this; } - _List_const_iterator operator++(int) { + _List_const_iterator operator++(int) noexcept { _List_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _List_const_iterator& operator--() { + _List_const_iterator& operator--() noexcept { const auto _New_ptr = this->_Ptr->_Prev; #if _ITERATOR_DEBUG_LEVEL == 2 const auto _Mycont = static_cast(this->_Getcont()); @@ -185,13 +185,13 @@ public: return *this; } - _List_const_iterator operator--(int) { + _List_const_iterator operator--(int) noexcept { _List_const_iterator _Tmp = *this; --*this; return _Tmp; } - _NODISCARD bool operator==(const _List_const_iterator& _Right) const { + _NODISCARD bool operator==(const _List_const_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "list iterators incompatible"); #endif // _ITERATOR_DEBUG_LEVEL == 2 @@ -199,23 +199,23 @@ public: return this->_Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _List_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _List_const_iterator& _Right) const noexcept { return !(*this == _Right); } #if _ITERATOR_DEBUG_LEVEL == 2 - friend void _Verify_range(const _List_const_iterator& _First, const _List_const_iterator& _Last) { + friend void _Verify_range(const _List_const_iterator& _First, const _List_const_iterator& _Last) noexcept { _STL_VERIFY(_First._Getcont() == _Last._Getcont(), "list iterators in range are from different containers"); } #endif // _ITERATOR_DEBUG_LEVEL == 2 using _Prevent_inheriting_unwrap = _List_const_iterator; - _NODISCARD _List_unchecked_const_iterator<_Mylist> _Unwrapped() const { + _NODISCARD _List_unchecked_const_iterator<_Mylist> _Unwrapped() const noexcept { return _List_unchecked_const_iterator<_Mylist>(this->_Ptr, static_cast(this->_Getcont())); } - void _Seek_to(const _List_unchecked_const_iterator<_Mylist> _It) { + void _Seek_to(const _List_unchecked_const_iterator<_Mylist> _It) noexcept { this->_Ptr = _It._Ptr; } }; @@ -235,31 +235,31 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _List_iterator& operator++() { + _List_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _List_iterator operator++(int) { + _List_iterator operator++(int) noexcept { _List_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _List_iterator& operator--() { + _List_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _List_iterator operator--(int) { + _List_iterator operator--(int) noexcept { _List_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; @@ -267,7 +267,7 @@ public: using _Prevent_inheriting_unwrap = _List_iterator; - _NODISCARD _List_unchecked_iterator<_Mylist> _Unwrapped() const { + _NODISCARD _List_unchecked_iterator<_Mylist> _Unwrapped() const noexcept { return _List_unchecked_iterator<_Mylist>(this->_Ptr, static_cast(this->_Getcont())); } }; diff --git a/stl/inc/memory b/stl/inc/memory index 3b77c4313b3..69eed6da175 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -142,7 +142,8 @@ namespace ranges { using _Not_quite_object::_Not_quite_object; // clang-format off - template _Se1, _No_throw_forward_iterator _It2, _No_throw_sentinel_for<_It2> _Se2> + template _Se1, _No_throw_forward_iterator _It2, + _No_throw_sentinel_for<_It2> _Se2> requires constructible_from, iter_rvalue_reference_t<_It1>> uninitialized_move_result<_It1, _It2> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2) const { // clang-format on diff --git a/stl/inc/optional b/stl/inc/optional index 968f45f6854..e852cda7b38 100644 --- a/stl/inc/optional +++ b/stl/inc/optional @@ -53,13 +53,6 @@ protected: _THROW(bad_optional_access{}); } -struct _Nontrivial_dummy_type { - constexpr _Nontrivial_dummy_type() noexcept { - // This default constructor is user-provided to avoid zero-initialization when objects are value-initialized. - } -}; -_STL_INTERNAL_STATIC_ASSERT(!is_trivially_default_constructible_v<_Nontrivial_dummy_type>); - template > struct _Optional_destruct_base { // either contains a value of _Ty or is empty (trivial destructor) union { diff --git a/stl/inc/ostream b/stl/inc/ostream index 95ad3889a71..671f8d0e0bd 100644 --- a/stl/inc/ostream +++ b/stl/inc/ostream @@ -966,9 +966,7 @@ struct _Can_stream_out<_Ostr, _Ty, void_t() << _ST }; template >, is_base_of, _Can_stream_out<_Ostr, _Ty>>, - int> = 0> + enable_if_t, _Can_stream_out<_Ostr, _Ty>>, int> = 0> _Ostr&& operator<<(_Ostr&& _Os, const _Ty& _Val) { // insert to rvalue stream _Os << _Val; return _STD move(_Os); diff --git a/stl/inc/ranges b/stl/inc/ranges index 3024333376c..5964866450e 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -12,6 +12,9 @@ #pragma message("The contents of are available only with C++20 concepts support.") #else // ^^^ !defined(__cpp_lib_concepts) / defined(__cpp_lib_concepts) vvv #include +#if 1 // TRANSITION, VSO-1174090 +#include +#endif // TRANSITION, VSO-1174090 #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) @@ -22,15 +25,471 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN namespace ranges { - // Much machinery defined in + // MUCH machinery defined in // clang-format off // CONCEPT ranges::viewable_range template concept viewable_range = range<_Rng> && (borrowed_range<_Rng> || view>); + + template + concept _Copy_constructible_object = copy_constructible<_Ty> && is_object_v<_Ty>; + // clang-format on + + // CLASS TEMPLATE ranges::_Semiregular_box +#if 0 // TRANSITION, VSO-1174090 + template <_Copy_constructible_object _Ty> + class _Semiregular_box { + public: + constexpr _Semiregular_box() noexcept : _Dummy{}, _Engaged{false} {} + constexpr _Semiregular_box() noexcept( + is_nothrow_default_constructible_v<_Ty>) requires default_initializable<_Ty> + : _Val(), _Engaged{true} {} + + template + constexpr _Semiregular_box(in_place_t, _Types&&... _Args) noexcept( + is_nothrow_constructible_v<_Ty, _Types...>) // strengthened + : _Val(_STD forward<_Types>(_Args)...), _Engaged{true} {} + + ~_Semiregular_box() requires is_trivially_destructible_v<_Ty> = default; + + ~_Semiregular_box() { + if (_Engaged) { + _Val.~_Ty(); + } + } + + _Semiregular_box(const _Semiregular_box&) requires is_trivially_copy_constructible_v<_Ty> = default; + _Semiregular_box(const _Semiregular_box& _That) : _Engaged{_That._Engaged} { + if (_That._Engaged) { + _Construct_in_place(_Val, _That._Val); + } + } + + _Semiregular_box(_Semiregular_box&&) requires is_trivially_move_constructible_v<_Ty> = default; + _Semiregular_box(_Semiregular_box&& _That) : _Engaged{_That._Engaged} { + if (_That._Engaged) { + _Construct_in_place(_Val, _STD move(_That._Val)); + } + } + + // clang-format off + _Semiregular_box& operator=(const _Semiregular_box&) noexcept + requires copyable<_Ty> && is_trivially_copy_assignable_v<_Ty> = default; + // clang-format on + + _Semiregular_box& operator=(const _Semiregular_box& _That) noexcept(is_nothrow_copy_constructible_v<_Ty>&& + is_nothrow_copy_assignable_v<_Ty>) /* strengthened */ requires copyable<_Ty> { + if (_Engaged) { + if (_That._Engaged) { + _Val = _That._Val; + } else { + _Val.~_Ty(); + _Engaged = false; + } + } else { + if (_That._Engaged) { + _Construct_in_place(_Val, _That._Val); + _Engaged = true; + } else { + // nothing to do + } + } + + return *this; + } + + _Semiregular_box& operator=(const _Semiregular_box& _That) noexcept(is_nothrow_copy_constructible_v<_Ty>) { + if (_STD addressof(_That) != this) { + if (_Engaged) { + _Val.~_Ty(); + _Engaged = false; + } + + if (_That._Engaged) { + _Construct_in_place(_Val, _That._Val); + _Engaged = true; + } + } + + return *this; + } + + // clang-format off + _Semiregular_box& operator=(_Semiregular_box&&) noexcept + requires movable<_Ty> && is_trivially_move_assignable_v<_Ty> = default; + // clang-format on + + _Semiregular_box& operator=(_Semiregular_box&& _That) noexcept(is_nothrow_move_constructible_v<_Ty>&& + is_nothrow_move_assignable_v<_Ty>) /* strengthened */ requires movable<_Ty> { + if (_Engaged) { + if (_That._Engaged) { + _Val = _STD move(_That._Val); + } else { + _Val.~_Ty(); + _Engaged = false; + } + } else { + if (_That._Engaged) { + _Construct_in_place(_Val, _STD move(_That._Val)); + _Engaged = true; + } else { + // nothing to do + } + } + + return *this; + } + + _Semiregular_box& operator=(_Semiregular_box&& _That) noexcept(is_nothrow_move_constructible_v<_Ty>) { + if (_Engaged) { + _Val.~_Ty(); + _Engaged = false; + } + + if (_That._Engaged) { + _Construct_in_place(_Val, _STD move(_That._Val)); + _Engaged = true; + } + + return *this; + } + + constexpr explicit operator bool() const noexcept { + return _Engaged; + } + + _NODISCARD constexpr _Ty& operator*() noexcept { + _STL_INTERNAL_CHECK(_Engaged); + return _Val; + } + _NODISCARD constexpr const _Ty& operator*() const noexcept { + _STL_INTERNAL_CHECK(_Engaged); + return _Val; + } + + private: + union { + _Nontrivial_dummy_type _Dummy; + _Ty _Val; + }; + bool _Engaged; + }; + + // clang-format off + template <_Copy_constructible_object _Ty> + requires default_initializable<_Ty> + && (copyable<_Ty> + || (is_nothrow_copy_constructible_v<_Ty> + && (movable<_Ty> || is_nothrow_move_constructible_v<_Ty>))) + class _Semiregular_box<_Ty> { + // clang-format on + public: + _Semiregular_box() = default; + + template + constexpr _Semiregular_box(in_place_t, _Types&&... _Args) noexcept( + is_nothrow_constructible_v<_Ty, _Types...>) // strengthened + : _Val(_STD forward<_Types>(_Args)...) {} + + _Semiregular_box(const _Semiregular_box&) = default; + _Semiregular_box(_Semiregular_box&&) = default; + _Semiregular_box& operator=(const _Semiregular_box&) requires copyable<_Ty> = default; + _Semiregular_box& operator=(_Semiregular_box&&) requires movable<_Ty> = default; + + _Semiregular_box& operator=(const _Semiregular_box& _That) noexcept { + if (_STD addressof(_That) != this) { + _Val.~_Ty(); + _Construct_in_place(_Val, _That._Val); + } + + return *this; + } + + _Semiregular_box& operator=(_Semiregular_box&& _That) noexcept { + if (_STD addressof(_That) != this) { + _Val.~_Ty(); + _Construct_in_place(_Val, _STD move(_That._Val)); + } + + return *this; + } + + constexpr explicit operator bool() const noexcept { + return true; + } + + _NODISCARD constexpr _Ty& operator*() noexcept { + return _Val; + } + _NODISCARD constexpr const _Ty& operator*() const noexcept { + return _Val; + } + + private: + /* [[no_unique_address]] */ _Ty _Val = _Ty(); + }; +#else // ^^^ no workaround / workaround vvv + template + class _Semiregular_box_copy : public optional<_Ty> { + public: + using optional<_Ty>::optional; + + _Semiregular_box_copy() = default; + _Semiregular_box_copy(const _Semiregular_box_copy&) = default; + _Semiregular_box_copy(_Semiregular_box_copy&&) = default; + _Semiregular_box_copy& operator=(_Semiregular_box_copy&&) = default; + + _Semiregular_box_copy& operator=(const _Semiregular_box_copy& _That) noexcept( + is_nothrow_copy_constructible_v<_Ty>) { + if (_STD addressof(_That) != this) { + optional<_Ty>::reset(); + if (_That) { + optional<_Ty>::emplace(*_That); + } + } + + return *this; + } + }; + + template + using _Choose_semiregular_box_copy = + conditional_t, optional<_Ty>, _Semiregular_box_copy<_Ty>>; + + template + class _Semiregular_box_move : public _Choose_semiregular_box_copy<_Ty> { + public: + using _Choose_semiregular_box_copy<_Ty>::_Choose_semiregular_box_copy; + + _Semiregular_box_move() = default; + _Semiregular_box_move(const _Semiregular_box_move&) = default; + _Semiregular_box_move(_Semiregular_box_move&&) = default; + _Semiregular_box_move& operator=(const _Semiregular_box_move&) = default; + + _Semiregular_box_move& operator=(_Semiregular_box_move&& _That) noexcept(is_nothrow_move_constructible_v<_Ty>) { + if (_STD addressof(_That) != this) { + optional<_Ty>::reset(); + if (_That) { + optional<_Ty>::emplace(_STD move(*_That)); + } + } + + return *this; + } + }; + + template + using _Choose_semiregular_box_move = + conditional_t, _Choose_semiregular_box_copy<_Ty>, _Semiregular_box_move<_Ty>>; + + template <_Copy_constructible_object _Ty> + class _Semiregular_box : public _Choose_semiregular_box_move<_Ty> { + public: + constexpr _Semiregular_box() noexcept {} + constexpr _Semiregular_box() noexcept( + is_nothrow_default_constructible_v<_Ty>) requires default_initializable<_Ty> + : _Choose_semiregular_box_move<_Ty>{in_place} {} + + template + constexpr _Semiregular_box(in_place_t, _Types&&... _Args) noexcept( + is_nothrow_constructible_v<_Ty, _Types...>) // strengthened + : _Choose_semiregular_box_move<_Ty>{in_place, _STD forward<_Types>(_Args)...} {} + }; + + // clang-format off + template <_Copy_constructible_object _Ty> + requires default_initializable<_Ty> && copyable<_Ty> + class _Semiregular_box<_Ty> { + // clang-format on + public: + _Semiregular_box() = default; + + template + constexpr _Semiregular_box(in_place_t, _Types&&... _Args) noexcept( + is_nothrow_constructible_v<_Ty, _Types...>) // strengthened + : _Val(_STD forward<_Types>(_Args)...) {} + + constexpr explicit operator bool() const noexcept { + return true; + } + + _NODISCARD constexpr _Ty& operator*() noexcept { + return _Val; + } + _NODISCARD constexpr const _Ty& operator*() const noexcept { + return _Val; + } + + private: + /* [[no_unique_address]] */ _Ty _Val = _Ty(); + }; +#endif // TRANSITION, VSO-1174090 + + // CLASS TEMPLATE ranges::empty_view + // clang-format off + template + requires is_object_v<_Ty> + class empty_view : public view_interface> { + // clang-format on + public: + _NODISCARD static constexpr _Ty* begin() noexcept { + return nullptr; + } + + _NODISCARD static constexpr _Ty* end() noexcept { + return nullptr; + } + + _NODISCARD static constexpr _Ty* data() noexcept { + return nullptr; + } + + _NODISCARD static constexpr size_t size() noexcept { + return 0; + } + + _NODISCARD static constexpr bool empty() noexcept { + return true; + } + }; + + namespace views { + // VARIABLE TEMPLATE views::empty + template + inline constexpr empty_view<_Ty> empty; + } // namespace views + + // CLASS TEMPLATE ranges::single_view + // clang-format off + template + requires is_object_v<_Ty> + class single_view : public view_interface> { + // clang-format on + public: + single_view() = default; + constexpr explicit single_view(const _Ty& _Val_) noexcept(is_nothrow_copy_constructible_v<_Ty>) // strengthened + : _Val{in_place, _Val_} {} + constexpr explicit single_view(_Ty&& _Val_) noexcept(is_nothrow_move_constructible_v<_Ty>) // strengthened + : _Val{in_place, _STD move(_Val_)} {} + + // clang-format off + template + requires constructible_from<_Ty, _Types...> + constexpr explicit single_view(in_place_t, _Types&&... _Args) noexcept( // explicit per LWG-3428 + is_nothrow_constructible_v<_Ty, _Types...>) // strengthened + // clang-format on + : _Val{in_place, _STD forward<_Types>(_Args)...} {} + + _NODISCARD constexpr _Ty* begin() noexcept { + return data(); + } + _NODISCARD constexpr const _Ty* begin() const noexcept { + return data(); + } + + _NODISCARD constexpr _Ty* end() noexcept { + return data() + 1; + } + _NODISCARD constexpr const _Ty* end() const noexcept { + return data() + 1; + } + + _NODISCARD static constexpr size_t size() noexcept { + return 1; + } + + _NODISCARD constexpr _Ty* data() noexcept { + return _STD addressof(*_Val); + } + _NODISCARD constexpr const _Ty* data() const noexcept { + return _STD addressof(*_Val); + } + + private: + /* [[no_unique_address]] */ _Semiregular_box<_Ty> _Val{}; + }; + + namespace views { + // VARIABLE views::single + struct _Single_fn { + // clang-format off + template + _NODISCARD constexpr auto operator()(_Ty&& _Val) const noexcept( + noexcept(single_view{static_cast<_Ty&&>(_Val)})) requires requires { + single_view{static_cast<_Ty&&>(_Val)}; + } { + return single_view{static_cast<_Ty&&>(_Val)}; + } + // clang-format on + }; + + inline constexpr _Single_fn single; + } // namespace views + + // CLASS TEMPLATE ranges::ref_view + // clang-format off + template + requires is_object_v<_Rng> + class ref_view : public view_interface> { + // clang-format on + private: + _Rng* _Range = nullptr; + + static void _Rvalue_poison(_Rng&); + static void _Rvalue_poison(_Rng&&) = delete; + + public: + constexpr ref_view() noexcept = default; + + // clang-format off + template <_Not_same_as _OtherRng> + constexpr ref_view(_OtherRng&& _Other) noexcept( + noexcept(static_cast<_Rng&>(_STD forward<_OtherRng>(_Other)))) // strengthened + requires convertible_to<_OtherRng, _Rng&> && requires { + _Rvalue_poison(static_cast<_OtherRng&&>(_Other)); + } : _Range{_STD addressof(static_cast<_Rng&>(_STD forward<_OtherRng>(_Other)))} {} + // clang-format on + + _NODISCARD constexpr _Rng& base() const noexcept /* strengthened */ { + return *_Range; + } + + _NODISCARD constexpr iterator_t<_Rng> begin() const + noexcept(noexcept(_RANGES begin(*_Range))) /* strengthened */ { + return _RANGES begin(*_Range); + } + + _NODISCARD constexpr sentinel_t<_Rng> end() const noexcept(noexcept(_RANGES end(*_Range))) /* strengthened */ { + return _RANGES end(*_Range); + } + + _NODISCARD constexpr bool empty() const noexcept(noexcept(_RANGES empty(*_Range))) /* strengthened */ + requires _Can_empty<_Rng> { + return _RANGES empty(*_Range); + } + + _NODISCARD constexpr auto size() const noexcept(noexcept(_RANGES size(*_Range))) /* strengthened */ + requires sized_range<_Rng> { + return _RANGES size(*_Range); + } + + _NODISCARD constexpr auto data() const noexcept(noexcept(_RANGES data(*_Range))) /* strengthened */ + requires contiguous_range<_Rng> { + return _RANGES data(*_Range); + } + }; + + template + ref_view(_Rng&) -> ref_view<_Rng>; + + template + inline constexpr bool enable_borrowed_range> = true; } // namespace ranges +namespace views = ranges::views; + _STD_END #pragma pop_macro("new") diff --git a/stl/inc/valarray b/stl/inc/valarray index 4c50bff4795..087a5f37bb1 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -57,20 +57,6 @@ _Ty* _Allocate_for_op_delete(size_t _Count) { using _Boolarray = valarray; using _Sizarray = valarray; -// MACROS FOR valarray -#define _VALOP(TYPE, LENGTH, RHS) /* assign RHS(_Idx) to new valarray */ \ - valarray _Ans(LENGTH); \ - for (size_t _Idx = 0; _Idx < _Ans.size(); ++_Idx) { \ - _Ans[_Idx] = RHS; \ - } \ - return _Ans - -#define _VALGOP(RHS) /* apply RHS(_Idx) to valarray */ \ - for (size_t _Idx = 0; _Idx < size(); ++_Idx) { \ - _Myptr[_Idx] RHS; \ - } \ - return *this - // CLASS TEMPLATE valarray template class valarray { // store array with various indexing options @@ -173,7 +159,11 @@ public: } valarray& operator=(const _Ty& _Val) { - _VALGOP(= _Val); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] = _Val; + } + return *this; } void resize(size_t _Newsize) { // determine new length, filling with _Ty() elements @@ -195,99 +185,199 @@ public: valarray& operator=(const indirect_array<_Ty>& _Indarr); // defined below _NODISCARD valarray operator+() const { - _VALOP(_Ty, size(), +_Myptr[_Idx]); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = +_Myptr[_Idx]; + } + return _Ans; } _NODISCARD valarray operator-() const { - _VALOP(_Ty, size(), -_Myptr[_Idx]); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = -_Myptr[_Idx]; + } + return _Ans; } _NODISCARD valarray operator~() const { - _VALOP(_Ty, size(), ~_Myptr[_Idx]); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = ~_Myptr[_Idx]; + } + return _Ans; } _NODISCARD _Boolarray operator!() const { - _VALOP(bool, size(), !_Myptr[_Idx]); + const size_t _Size = size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = !_Myptr[_Idx]; + } + return _Ans; } valarray& operator*=(const _Ty& _Right) { - _VALGOP(*= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] *= _Right; + } + return *this; } valarray& operator/=(const _Ty& _Right) { - _VALGOP(/= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] /= _Right; + } + return *this; } valarray& operator%=(const _Ty& _Right) { - _VALGOP(%= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] %= _Right; + } + return *this; } valarray& operator+=(const _Ty& _Right) { - _VALGOP(+= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] += _Right; + } + return *this; } valarray& operator-=(const _Ty& _Right) { - _VALGOP(-= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] -= _Right; + } + return *this; } valarray& operator^=(const _Ty& _Right) { - _VALGOP(^= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] ^= _Right; + } + return *this; } valarray& operator&=(const _Ty& _Right) { - _VALGOP(&= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] &= _Right; + } + return *this; } valarray& operator|=(const _Ty& _Right) { - _VALGOP(|= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] |= _Right; + } + return *this; } valarray& operator<<=(const _Ty& _Right) { - _VALGOP(<<= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] <<= _Right; + } + return *this; } valarray& operator>>=(const _Ty& _Right) { - _VALGOP(>>= _Right); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] >>= _Right; + } + return *this; } valarray& operator*=(const valarray& _Right) { - _VALGOP(*= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] *= _Right[_Idx]; + } + return *this; } valarray& operator/=(const valarray& _Right) { - _VALGOP(/= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] /= _Right[_Idx]; + } + return *this; } valarray& operator%=(const valarray& _Right) { - _VALGOP(%= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] %= _Right[_Idx]; + } + return *this; } valarray& operator+=(const valarray& _Right) { - _VALGOP(+= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] += _Right[_Idx]; + } + return *this; } valarray& operator-=(const valarray& _Right) { - _VALGOP(-= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] -= _Right[_Idx]; + } + return *this; } valarray& operator^=(const valarray& _Right) { - _VALGOP(^= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] ^= _Right[_Idx]; + } + return *this; } valarray& operator|=(const valarray& _Right) { - _VALGOP(|= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] |= _Right[_Idx]; + } + return *this; } valarray& operator&=(const valarray& _Right) { - _VALGOP(&= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] &= _Right[_Idx]; + } + return *this; } valarray& operator<<=(const valarray& _Right) { - _VALGOP(<<= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] <<= _Right[_Idx]; + } + return *this; } valarray& operator>>=(const valarray& _Right) { - _VALGOP(>>= _Right[_Idx]); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] >>= _Right[_Idx]; + } + return *this; } _NODISCARD size_t size() const noexcept /* strengthened */ { @@ -319,8 +409,9 @@ public: _NODISCARD indirect_array<_Ty> operator[](const _Sizarray& _Indarr); // defined below _NODISCARD _Ty sum() const { - _Ty _Sum = _Myptr[0]; - for (size_t _Idx = 1; _Idx < size(); ++_Idx) { + const size_t _Size = size(); + _Ty _Sum = _Myptr[0]; + for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { _Sum += _Myptr[_Idx]; } @@ -328,8 +419,9 @@ public: } _NODISCARD _Ty(min)() const { - _Ty _Min = _Myptr[0]; - for (size_t _Idx = 1; _Idx < size(); ++_Idx) { + const size_t _Size = size(); + _Ty _Min = _Myptr[0]; + for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { if (_Myptr[_Idx] < _Min) { _Min = _Myptr[_Idx]; } @@ -339,8 +431,9 @@ public: } _NODISCARD _Ty(max)() const { - _Ty _Max = _Myptr[0]; - for (size_t _Idx = 1; _Idx < size(); ++_Idx) { + const size_t _Size = size(); + _Ty _Max = _Myptr[0]; + for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { if (_Max < _Myptr[_Idx]) { _Max = _Myptr[_Idx]; } @@ -350,38 +443,66 @@ public: } _NODISCARD valarray shift(int _Count) const { - __PURE_APPDOMAIN_GLOBAL static _Ty _Dflt; - _VALOP(_Ty, size(), - (0 < _Count && size() - _Idx <= static_cast(_Count)) - || (_Count < 0 && _Idx < static_cast(-_Count)) - ? _Dflt - : _Myptr[_Idx + _Count]); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + size_t _Min = 0; + size_t _Max = _Size; + if (_Count < 0) { + const size_t _Skip = static_cast(-_Count); + _Min += _Skip; + } else { + const size_t _Skip = static_cast(_Count); + if (_Skip < _Size) { + _Max -= _Skip; + } else { + _Max = 0; + } + } + for (size_t _Idx = _Min; _Idx < _Max; ++_Idx) { + _Ans[_Idx] = _Myptr[_Idx + _Count]; + } + return _Ans; } _NODISCARD valarray cshift(int _Count) const { - if (size() != 0) { + const size_t _Size = size(); + if (_Size != 0) { if (_Count < 0) { // right shift - if (size() < size_t{0} - _Count) { - _Count = static_cast(size() - (size_t{0} - _Count - size()) % size()); + if (_Size < size_t{0} - _Count) { + _Count = static_cast(_Size - (size_t{0} - _Count - _Size) % _Size); } else { - _Count = static_cast(size() + _Count); + _Count = static_cast(_Size + _Count); } - } else if (size() <= static_cast(_Count)) { - _Count %= size(); + } else if (_Size <= static_cast(_Count)) { + _Count %= _Size; } } - _VALOP(_Ty, size(), - size() - _Idx <= static_cast(_Count) ? _Myptr[_Idx - size() + _Count] : _Myptr[_Idx + _Count]); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = + _Size - _Idx <= static_cast(_Count) ? _Myptr[_Idx - _Size + _Count] : _Myptr[_Idx + _Count]; + } + return _Ans; } _NODISCARD valarray apply(_Ty _Func(_Ty)) const { - _VALOP(_Ty, size(), _Func(_Myptr[_Idx])); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Func(_Myptr[_Idx]); + } + return _Ans; } _NODISCARD valarray apply(_Ty _Func(const _Ty&)) const { // return valarray transformed by _Func, nonmutable argument - _VALOP(_Ty, size(), _Func(_Myptr[_Idx])); + const size_t _Size = size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Func(_Myptr[_Idx]); + } + return _Ans; } private: @@ -430,8 +551,9 @@ private: } void _Assign(size_t _Newsize, const _Ty* _Ptr) { - if (size() == _Newsize) { - for (size_t _Idx = 0; _Idx < size(); ++_Idx) { + const size_t _Size = size(); + if (_Size == _Newsize) { + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { _Myptr[_Idx] = _Ptr[_Idx]; } } else { // resize and copy @@ -476,373 +598,743 @@ _NODISCARD const _Ty* end(const valarray<_Ty>& _Array) { template _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] * _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator*(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left * _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left * _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator/(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] / _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator/(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left / _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left / _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator%(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] % _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator%(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left % _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left % _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator+(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] + _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator+(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left + _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left + _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator-(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] - _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator-(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left - _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left - _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator^(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] ^ _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator^(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left ^ _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left ^ _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator&(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] & _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator&(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left & _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left & _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator|(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] | _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator|(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left | _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left | _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] << _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator<<(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left << _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left << _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] >> _Right; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator>>(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), _Left >> _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left >> _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator&&(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] && _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] && _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator&&(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left&& _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left && _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator||(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] || _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] || _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator||(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left || _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left || _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] * _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator/(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] / _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator%(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] % _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator+(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] + _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator-(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] - _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator^(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] ^ _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] & _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator|(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] | _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] << _Right[_Idx]; + } + return _Ans; } template _NODISCARD valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] >> _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator&&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] && _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] && _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator||(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] || _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] || _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator==(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] == _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] == _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator==(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left == _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left == _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator==(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] == _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] == _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator!=(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] != _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] != _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator!=(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left != _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left != _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator!=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] != _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] != _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator<(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] < _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] < _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator<(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left < _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left < _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] < _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] < _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator>(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] > _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] > _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator>(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left > _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left > _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] > _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] > _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator<=(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] <= _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] <= _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator<=(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left <= _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left <= _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator<=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] <= _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] <= _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator>=(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] >= _Right); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] >= _Right; + } + return _Ans; } template _NODISCARD _Boolarray operator>=(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Right.size(), _Left >= _Right[_Idx]); + const size_t _Size = _Right.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left >= _Right[_Idx]; + } + return _Ans; } template _NODISCARD _Boolarray operator>=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(bool, _Left.size(), _Left[_Idx] >= _Right[_Idx]); + const size_t _Size = _Left.size(); + valarray _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = _Left[_Idx] >= _Right[_Idx]; + } + return _Ans; } // [valarray.transcend] Transcendentals template _NODISCARD valarray<_Ty> abs(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), abs(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = abs(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> acos(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), acos(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = acos(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> asin(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), asin(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = asin(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> atan(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), atan(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = atan(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> atan2(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), atan2(_Left[_Idx], _Right[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = atan2(_Left[_Idx], _Right[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> atan2(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), atan2(_Left[_Idx], _Right)); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = atan2(_Left[_Idx], _Right); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> atan2(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), atan2(_Left, _Right[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = atan2(_Left, _Right[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> cos(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), cos(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = cos(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> cosh(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), cosh(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = cosh(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> exp(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), exp(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = exp(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> log(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), log(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = log(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> log10(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), log10(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = log10(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> pow(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Left.size(), pow(_Left[_Idx], _Right[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = pow(_Left[_Idx], _Right[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> pow(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { - _VALOP(_Ty, _Left.size(), pow(_Left[_Idx], _Right)); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = pow(_Left[_Idx], _Right); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> pow(const typename valarray<_Ty>::value_type& _Left, const valarray<_Ty>& _Right) { - _VALOP(_Ty, _Right.size(), pow(_Left, _Right[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Right.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = pow(_Left, _Right[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> sin(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), sin(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = sin(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> sinh(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), sinh(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = sinh(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> sqrt(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), sqrt(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = sqrt(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> tan(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), tan(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = tan(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } template _NODISCARD valarray<_Ty> tanh(const valarray<_Ty>& _Left) { - _VALOP(_Ty, _Left.size(), tanh(_Left[_Idx])); // using ADL, N4835 [valarray.transcend]/1 + const size_t _Size = _Left.size(); + valarray<_Ty> _Ans(_Size); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Ans[_Idx] = tanh(_Left[_Idx]); // using ADL, N4835 [valarray.transcend]/1 + } + return _Ans; } // CLASS slice @@ -871,13 +1363,6 @@ protected: size_t _Stride = 0; // the distance between elements }; -// MACROS FOR slice_array -#define _SLOP(RHS) /* apply RHS(_Idx) to slice_array */ \ - size_t _Off = _Start; \ - for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { \ - _Myptr[_Off] RHS; \ - } - // CLASS TEMPLATE slice_array template class slice_array : public slice { // define a slice of a valarray @@ -885,51 +1370,87 @@ public: using value_type = _Ty; void operator=(const valarray<_Ty>& _Right) const { - _SLOP(= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] = _Right[_Idx]; + } } void operator=(const _Ty& _Right) const { - _SLOP(= _Right); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] = _Right; + } } void operator*=(const valarray<_Ty>& _Right) const { - _SLOP(*= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] *= _Right[_Idx]; + } } void operator/=(const valarray<_Ty>& _Right) const { - _SLOP(/= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] /= _Right[_Idx]; + } } void operator%=(const valarray<_Ty>& _Right) const { - _SLOP(%= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] %= _Right[_Idx]; + } } void operator+=(const valarray<_Ty>& _Right) const { - _SLOP(+= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] += _Right[_Idx]; + } } void operator-=(const valarray<_Ty>& _Right) const { - _SLOP(-= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] -= _Right[_Idx]; + } } void operator^=(const valarray<_Ty>& _Right) const { - _SLOP(^= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] ^= _Right[_Idx]; + } } void operator&=(const valarray<_Ty>& _Right) const { - _SLOP(&= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] &= _Right[_Idx]; + } } void operator|=(const valarray<_Ty>& _Right) const { - _SLOP(|= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] |= _Right[_Idx]; + } } void operator<<=(const valarray<_Ty>& _Right) const { - _SLOP(<<= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] <<= _Right[_Idx]; + } } void operator>>=(const valarray<_Ty>& _Right) const { - _SLOP(>>= _Right[_Idx]); + size_t _Off = _Start; + for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) { + _Myptr[_Off] >>= _Right[_Idx]; + } } _Ty& _Data(size_t _Idx) const { @@ -982,9 +1503,10 @@ public: } size_t _Off(_Sizarray& _Indexarr) const { - size_t _Idx, _Ans = _Start; - - for (_Idx = 0; _Idx < _Indexarr.size(); ++_Idx) { + size_t _Idx; + size_t _Ans = _Start; + const size_t _Size = _Indexarr.size(); + for (_Idx = 0; _Idx < _Size; ++_Idx) { _Ans += _Indexarr[_Idx] * _Stride[_Idx]; // compute offset } @@ -1000,12 +1522,13 @@ public: } _NODISCARD size_t _Totlen() const { - if (_Len.size() == 0) { + const size_t _Size = _Len.size(); + if (_Size == 0) { return 0; } size_t _Count = _Len[0]; - for (size_t _Idx = 1; _Idx < _Len.size(); ++_Idx) { + for (size_t _Idx = 1; _Idx < _Size; ++_Idx) { _Count *= _Len[_Idx]; } @@ -1018,14 +1541,6 @@ private: _Sizarray _Stride; // array of distances between elements }; -// MACROS FOR gslice_array -#define _GSLOP(RHS) /* apply RHS(_Idx) to gslice_array */ \ - _Sizarray _Indexarray(size_t{0}, _Nslice()); \ - size_t _Size = _Totlen(); \ - for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { \ - _Myptr[_Off(_Indexarray)] RHS; \ - } - // CLASS TEMPLATE gslice_array template class gslice_array : public gslice { // define a generalized slice of a valarray @@ -1033,51 +1548,99 @@ public: using value_type = _Ty; void operator=(const valarray<_Ty>& _Right) const { - _GSLOP(= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] = _Right[_Idx]; + } } void operator=(const _Ty& _Right) const { - _GSLOP(= _Right); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] = _Right; + } } void operator*=(const valarray<_Ty>& _Right) const { // multiply generalized slice by valarray - _GSLOP(*= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] *= _Right[_Idx]; + } } void operator/=(const valarray<_Ty>& _Right) const { // divide generalized slice by valarray - _GSLOP(/= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] /= _Right[_Idx]; + } } void operator%=(const valarray<_Ty>& _Right) const { // remainder generalized slice by valarray - _GSLOP(%= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] %= _Right[_Idx]; + } } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to generalized slice - _GSLOP(+= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] += _Right[_Idx]; + } } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from generalized slice - _GSLOP(-= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] -= _Right[_Idx]; + } } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into generalized slice - _GSLOP(^= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] ^= _Right[_Idx]; + } } void operator&=(const valarray<_Ty>& _Right) const { // AND valarray into generalized slice - _GSLOP(&= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] &= _Right[_Idx]; + } } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into generalized slice - _GSLOP(|= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] |= _Right[_Idx]; + } } void operator<<=(const valarray<_Ty>& _Right) const { // left shift generalized slice by valarray - _GSLOP(<<= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] <<= _Right[_Idx]; + } } void operator>>=(const valarray<_Ty>& _Right) const { // right shift generalized slice by valarray - _GSLOP(>>= _Right[_Idx]); + _Sizarray _Indexarray(size_t{0}, _Nslice()); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Off(_Indexarray)] >>= _Right[_Idx]; + } } _NODISCARD _Ty& _Data(size_t _Idx) const { @@ -1106,16 +1669,6 @@ private: _Ty* _Myptr; // pointer to valarray contents }; -// MACROS FOR mask_array -#define _MOP(RHS) /* apply RHS(_Idx) to mask_array */ \ - size_t _Off = 0; \ - size_t _Size = _Totlen(); \ - for (size_t _Idx = 0; _Idx < _Size; ++_Off) { \ - if (_Mask(_Off)) { \ - _Myptr[_Off] RHS, ++_Idx; \ - } \ - } - // CLASS TEMPLATE mask_array template class mask_array { // define a subset of a valarray with an array of mask bits @@ -1123,51 +1676,87 @@ public: using value_type = _Ty; void operator=(const valarray<_Ty>& _Right) const { - _MOP(= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] = _Right[_Idx]; + } } void operator=(const _Ty& _Right) const { - _MOP(= _Right); + const size_t _Size = _Mybool.size(); + for (size_t _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off)) { + _Myptr[_Off] = _Right; + } } void operator*=(const valarray<_Ty>& _Right) const { // multiply masked array by valarray - _MOP(*= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] *= _Right[_Idx]; + } } void operator/=(const valarray<_Ty>& _Right) const { // divide masked array by valarray - _MOP(/= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] /= _Right[_Idx]; + } } void operator%=(const valarray<_Ty>& _Right) const { // remainder masked array by valarray - _MOP(%= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] %= _Right[_Idx]; + } } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to masked array - _MOP(+= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] += _Right[_Idx]; + } } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from masked array - _MOP(-= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] -= _Right[_Idx]; + } } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into masked array - _MOP(^= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] ^= _Right[_Idx]; + } } void operator&=(const valarray<_Ty>& _Right) const { // OR valarray into masked array - _MOP(&= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] &= _Right[_Idx]; + } } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into masked array - _MOP(|= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] |= _Right[_Idx]; + } } void operator<<=(const valarray<_Ty>& _Right) const { // left shift masked array by valarray - _MOP(<<= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] <<= _Right[_Idx]; + } } void operator>>=(const valarray<_Ty>& _Right) const { // right shift masked array by valarray - _MOP(>>= _Right[_Idx]); + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0, _Off = _Start_off(); _Off < _Size; _Off = _Next_off(_Off), ++_Idx) { + _Myptr[_Off] >>= _Right[_Idx]; + } } _NODISCARD _Ty& _Data(size_t _Idx) const { @@ -1196,8 +1785,9 @@ public: } _NODISCARD size_t _Totlen() const { - size_t _Count = 0; - for (size_t _Idx = 0; _Idx < _Mybool.size(); ++_Idx) { + size_t _Count = 0; + const size_t _Size = _Mybool.size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { if (_Mybool[_Idx]) { ++_Count; } @@ -1229,13 +1819,6 @@ private: _Ty* _Myptr; // pointer to valarray contents }; -// MACROS FOR indirect_array -#define _IOP(RHS) /* apply RHS(_Idx) to indirect_array */ \ - size_t _Size = _Totlen(); \ - for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { \ - _Myptr[_Indir(_Idx)] RHS; \ - } - // CLASS TEMPLATE indirect_array template class indirect_array { // define a subset of a valarray with an array of indexes @@ -1243,51 +1826,87 @@ public: using value_type = _Ty; void operator=(const valarray<_Ty>& _Right) const { - _IOP(= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] = _Right[_Idx]; + } } void operator=(const _Ty& _Right) const { - _IOP(= _Right); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] = _Right; + } } void operator*=(const valarray<_Ty>& _Right) const { // multiply indirect array by valarray - _IOP(*= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] *= _Right[_Idx]; + } } void operator/=(const valarray<_Ty>& _Right) const { // divide indirect array by valarray - _IOP(/= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] /= _Right[_Idx]; + } } void operator%=(const valarray<_Ty>& _Right) const { // remainder indirect array by valarray - _IOP(%= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] %= _Right[_Idx]; + } } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to indirect array - _IOP(+= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] += _Right[_Idx]; + } } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from indirect array - _IOP(-= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] -= _Right[_Idx]; + } } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into indirect array - _IOP(^= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] ^= _Right[_Idx]; + } } void operator&=(const valarray<_Ty>& _Right) const { // AND valarray into indirect array - _IOP(&= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] &= _Right[_Idx]; + } } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into indirect array - _IOP(|= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] |= _Right[_Idx]; + } } void operator<<=(const valarray<_Ty>& _Right) const { // left shift indirect array by valarray - _IOP(<<= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] <<= _Right[_Idx]; + } } void operator>>=(const valarray<_Ty>& _Right) const { // right shift indirect array by valarray - _IOP(>>= _Right[_Idx]); + const size_t _Size = _Totlen(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Indir(_Idx)] >>= _Right[_Idx]; + } } _NODISCARD _Ty& _Data(size_t _Idx) const { @@ -1345,7 +1964,11 @@ valarray<_Ty>& valarray<_Ty>::operator=(const gslice_array<_Ty>& _Gslicearr) { _Tidy_deallocate(); _Grow(_Gslicearr._Totlen()); _Sizarray _Indexarray(size_t{0}, _Gslicearr._Nslice()); - _VALGOP(= _Gslicearr._Data(_Gslicearr._Off(_Indexarray))); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] = _Gslicearr._Data(_Gslicearr._Off(_Indexarray)); + } + return *this; } template @@ -1364,7 +1987,8 @@ valarray<_Ty>& valarray<_Ty>::operator=(const mask_array<_Ty>& _Maskarr) { _Grow(_Maskarr._Totlen()); size_t _Count = 0; - for (size_t _Idx = 0; _Idx < size(); ++_Count) { + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Count) { if (_Maskarr._Mask(_Count)) { _Myptr[_Idx++] = _Maskarr._Data(_Count); } @@ -1387,7 +2011,11 @@ template valarray<_Ty>& valarray<_Ty>::operator=(const indirect_array<_Ty>& _Indarr) { _Tidy_deallocate(); _Grow(_Indarr._Totlen()); - _VALGOP(= _Indarr._Data(_Indarr._Indir(_Idx))); + const size_t _Size = size(); + for (size_t _Idx = 0; _Idx < _Size; ++_Idx) { + _Myptr[_Idx] = _Indarr._Data(_Indarr._Indir(_Idx)); + } + return *this; } template diff --git a/stl/inc/vector b/stl/inc/vector index 5a18de75a39..0fe4e0079ab 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -43,7 +43,7 @@ public: this->_Adopt(_Pvector); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Ptr, "can't dereference value-initialized vector iterator"); @@ -54,7 +54,7 @@ public: return *_Ptr; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Ptr, "can't dereference value-initialized vector iterator"); @@ -65,7 +65,7 @@ public: return _Ptr; } - _Vector_const_iterator& operator++() { + _Vector_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Ptr, "can't increment value-initialized vector iterator"); @@ -76,13 +76,13 @@ public: return *this; } - _Vector_const_iterator operator++(int) { + _Vector_const_iterator operator++(int) noexcept { _Vector_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _Vector_const_iterator& operator--() { + _Vector_const_iterator& operator--() noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_cast(this->_Getcont()); _STL_VERIFY(_Ptr, "can't decrement value-initialized vector iterator"); @@ -93,13 +93,13 @@ public: return *this; } - _Vector_const_iterator operator--(int) { + _Vector_const_iterator operator--(int) noexcept { _Vector_const_iterator _Tmp = *this; --*this; return _Tmp; } - void _Verify_offset(const difference_type _Off) const { + void _Verify_offset(const difference_type _Off) const noexcept { #if _ITERATOR_DEBUG_LEVEL == 0 (void) _Off; #else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv @@ -115,62 +115,62 @@ public: #endif // _ITERATOR_DEBUG_LEVEL == 0 } - _Vector_const_iterator& operator+=(const difference_type _Off) { + _Vector_const_iterator& operator+=(const difference_type _Off) noexcept { _Verify_offset(_Off); _Ptr += _Off; return *this; } - _NODISCARD _Vector_const_iterator operator+(const difference_type _Off) const { + _NODISCARD _Vector_const_iterator operator+(const difference_type _Off) const noexcept { _Vector_const_iterator _Tmp = *this; return _Tmp += _Off; } - _Vector_const_iterator& operator-=(const difference_type _Off) { + _Vector_const_iterator& operator-=(const difference_type _Off) noexcept { return *this += -_Off; } - _NODISCARD _Vector_const_iterator operator-(const difference_type _Off) const { + _NODISCARD _Vector_const_iterator operator-(const difference_type _Off) const noexcept { _Vector_const_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _Vector_const_iterator& _Right) const { + _NODISCARD difference_type operator-(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr - _Right._Ptr; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } - _NODISCARD bool operator==(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD bool operator<(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator<(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr < _Right._Ptr; } - _NODISCARD bool operator>(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator>(const _Vector_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD bool operator<=(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator<=(const _Vector_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD bool operator>=(const _Vector_const_iterator& _Right) const { + _NODISCARD bool operator>=(const _Vector_const_iterator& _Right) const noexcept { return !(*this < _Right); } - void _Compat(const _Vector_const_iterator& _Right) const { // test for compatible iterator pair + void _Compat(const _Vector_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 (void) _Right; #else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv @@ -179,7 +179,7 @@ public: } #if _ITERATOR_DEBUG_LEVEL != 0 - friend void _Verify_range(const _Vector_const_iterator& _First, const _Vector_const_iterator& _Last) { + friend void _Verify_range(const _Vector_const_iterator& _First, const _Vector_const_iterator& _Last) noexcept { _STL_VERIFY(_First._Getcont() == _Last._Getcont(), "vector iterators in range are from different containers"); _STL_VERIFY(_First._Ptr <= _Last._Ptr, "vector iterator range transposed"); } @@ -187,11 +187,11 @@ public: using _Prevent_inheriting_unwrap = _Vector_const_iterator; - _NODISCARD const value_type* _Unwrapped() const { + _NODISCARD const value_type* _Unwrapped() const noexcept { return _Unfancy(_Ptr); } - void _Seek_to(const value_type* _It) { + void _Seek_to(const value_type* _It) noexcept { _Ptr = _Refancy<_Tptr>(const_cast(_It)); } @@ -200,7 +200,7 @@ public: template _NODISCARD _Vector_const_iterator<_Myvec> operator+( - typename _Vector_const_iterator<_Myvec>::difference_type _Off, _Vector_const_iterator<_Myvec> _Next) { + typename _Vector_const_iterator<_Myvec>::difference_type _Off, _Vector_const_iterator<_Myvec> _Next) noexcept { return _Next += _Off; } @@ -248,72 +248,72 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return _Const_cast(_Mybase::operator->()); } - _Vector_iterator& operator++() { + _Vector_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Vector_iterator operator++(int) { + _Vector_iterator operator++(int) noexcept { _Vector_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Vector_iterator& operator--() { + _Vector_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Vector_iterator operator--(int) { + _Vector_iterator operator--(int) noexcept { _Vector_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; } - _Vector_iterator& operator+=(const difference_type _Off) { + _Vector_iterator& operator+=(const difference_type _Off) noexcept { _Mybase::operator+=(_Off); return *this; } - _NODISCARD _Vector_iterator operator+(const difference_type _Off) const { + _NODISCARD _Vector_iterator operator+(const difference_type _Off) const noexcept { _Vector_iterator _Tmp = *this; return _Tmp += _Off; } - _Vector_iterator& operator-=(const difference_type _Off) { + _Vector_iterator& operator-=(const difference_type _Off) noexcept { _Mybase::operator-=(_Off); return *this; } using _Mybase::operator-; - _NODISCARD _Vector_iterator operator-(const difference_type _Off) const { + _NODISCARD _Vector_iterator operator-(const difference_type _Off) const noexcept { _Vector_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return const_cast(_Mybase::operator[](_Off)); } using _Prevent_inheriting_unwrap = _Vector_iterator; - _NODISCARD value_type* _Unwrapped() const { + _NODISCARD value_type* _Unwrapped() const noexcept { return _Unfancy(this->_Ptr); } }; template _NODISCARD _Vector_iterator<_Myvec> operator+( - typename _Vector_iterator<_Myvec>::difference_type _Off, _Vector_iterator<_Myvec> _Next) { + typename _Vector_iterator<_Myvec>::difference_type _Off, _Vector_iterator<_Myvec> _Next) noexcept { return _Next += _Off; } @@ -399,12 +399,12 @@ public: // FUNCTION TEMPLATE _Unfancy_maybe_null template -auto _Unfancy_maybe_null(_Ptrty _Ptr) { // converts from a (potentially null) fancy pointer to a plain pointer +auto _Unfancy_maybe_null(_Ptrty _Ptr) noexcept { // converts from a (potentially null) fancy pointer to a plain pointer return _Ptr ? _STD addressof(*_Ptr) : nullptr; } template -_Ty* _Unfancy_maybe_null(_Ty* _Ptr) { // do nothing for plain pointers +_Ty* _Unfancy_maybe_null(_Ty* _Ptr) noexcept { // do nothing for plain pointers return _Ptr; } @@ -1615,9 +1615,10 @@ private: size_type _Calculate_growth(const size_type _Newsize) const { // given _Oldcapacity and _Newsize, calculate geometric growth const size_type _Oldcapacity = capacity(); + const auto _Max = max_size(); - if (_Oldcapacity > max_size() - _Oldcapacity / 2) { - return _Newsize; // geometric growth would overflow + if (_Oldcapacity > _Max - _Oldcapacity / 2) { + return _Max; // geometric growth would overflow } const size_type _Geometric = _Oldcapacity + _Oldcapacity / 2; @@ -1818,14 +1819,14 @@ public: this->_Adopt(_Mypvbool); } - void _Advance(_Size_type _Off) { + void _Advance(_Size_type _Off) noexcept { _Myoff += _Off; _Myptr += _Myoff / _VBITS; _Myoff %= _VBITS; } #if _ITERATOR_DEBUG_LEVEL != 0 - _Difference_type _Total_off(const _Mycont* _Cont) const { + _Difference_type _Total_off(const _Mycont* _Cont) const noexcept { return static_cast<_Difference_type>(_VBITS * (_Myptr - _Cont->_Myvec.data()) + _Myoff); } #endif // _ITERATOR_DEBUG_LEVEL != 0 @@ -1872,7 +1873,7 @@ public: return (*_Getptr() & _Mask()) != 0; } - const _Vbase* _Getptr() const { + const _Vbase* _Getptr() const noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Cont = static_cast(this->_Getcont()); _STL_VERIFY(_Cont, "cannot dereference value-initialized vector iterator"); @@ -1890,7 +1891,7 @@ public: } protected: - _Vbase _Mask() const { + _Vbase _Mask() const noexcept { return static_cast<_Vbase>(1) << this->_Myoff; } }; @@ -1918,7 +1919,7 @@ public: _Vb_const_iterator(const _Vbase* _Ptr, const _Container_base* _Mypvbool) noexcept : _Mybase(_Ptr, 0, _Mypvbool) {} - _NODISCARD const_reference operator*() const { + _NODISCARD const_reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Cont = static_cast(this->_Getcont()); _STL_VERIFY(_Cont, "cannot dereference value-initialized vector iterator"); @@ -1929,29 +1930,29 @@ public: return _Reft(*this); } - _Vb_const_iterator& operator++() { + _Vb_const_iterator& operator++() noexcept { _Inc(); return *this; } - _Vb_const_iterator operator++(int) { + _Vb_const_iterator operator++(int) noexcept { _Vb_const_iterator _Tmp = *this; _Inc(); return _Tmp; } - _Vb_const_iterator& operator--() { + _Vb_const_iterator& operator--() noexcept { _Dec(); return *this; } - _Vb_const_iterator operator--(int) { + _Vb_const_iterator operator--(int) noexcept { _Vb_const_iterator _Tmp = *this; _Dec(); return _Tmp; } - _Vb_const_iterator& operator+=(const difference_type _Off) { + _Vb_const_iterator& operator+=(const difference_type _Off) noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 if (_Off != 0) { const auto _Cont = static_cast(this->_Getcont()); @@ -1978,57 +1979,57 @@ public: return *this; } - _NODISCARD _Vb_const_iterator operator+(const difference_type _Off) const { + _NODISCARD _Vb_const_iterator operator+(const difference_type _Off) const noexcept { _Vb_const_iterator _Tmp = *this; return _Tmp += _Off; } - _Vb_const_iterator& operator-=(const difference_type _Off) { + _Vb_const_iterator& operator-=(const difference_type _Off) noexcept { return *this += -_Off; } - _NODISCARD _Vb_const_iterator operator-(const difference_type _Off) const { + _NODISCARD _Vb_const_iterator operator-(const difference_type _Off) const noexcept { _Vb_const_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _Vb_const_iterator& _Right) const { + _NODISCARD difference_type operator-(const _Vb_const_iterator& _Right) const noexcept { _Compat(_Right); return static_cast(_VBITS * (this->_Myptr - _Right._Myptr)) + static_cast(this->_Myoff) - static_cast(_Right._Myoff); } - _NODISCARD const_reference operator[](const difference_type _Off) const { + _NODISCARD const_reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } - _NODISCARD bool operator==(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Vb_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myptr == _Right._Myptr && this->_Myoff == _Right._Myoff; } - _NODISCARD bool operator!=(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Vb_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD bool operator<(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator<(const _Vb_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myptr < _Right._Myptr || (this->_Myptr == _Right._Myptr && this->_Myoff < _Right._Myoff); } - _NODISCARD bool operator>(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator>(const _Vb_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD bool operator<=(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator<=(const _Vb_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD bool operator>=(const _Vb_const_iterator& _Right) const { + _NODISCARD bool operator>=(const _Vb_const_iterator& _Right) const noexcept { return !(*this < _Right); } - void _Compat(const _Vb_const_iterator& _Right) const { // test for compatible iterator pair + void _Compat(const _Vb_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 (void) _Right; #else // _ITERATOR_DEBUG_LEVEL == 0 @@ -2039,13 +2040,13 @@ public: #if _ITERATOR_DEBUG_LEVEL != 0 using _Prevent_inheriting_unwrap = _Vb_const_iterator; - friend void _Verify_range(const _Vb_const_iterator& _First, const _Vb_const_iterator& _Last) { + friend void _Verify_range(const _Vb_const_iterator& _First, const _Vb_const_iterator& _Last) noexcept { // note _Compat check inside <= _STL_VERIFY(_First <= _Last, "vector iterator range transposed"); } #endif // _ITERATOR_DEBUG_LEVEL != 0 - void _Dec() { // decrement bit position + void _Dec() noexcept { // decrement bit position #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Cont = static_cast(this->_Getcont()); _STL_VERIFY(_Cont, "cannot decrement value-initialized vector iterator"); @@ -2060,7 +2061,7 @@ public: } } - void _Inc() { // increment bit position + void _Inc() noexcept { // increment bit position #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Cont = static_cast(this->_Getcont()); _STL_VERIFY(_Cont, "cannot increment value-initialized vector iterator"); @@ -2079,7 +2080,8 @@ public: template _NODISCARD _Vb_const_iterator<_Alvbase_wrapped> operator+( - typename _Vb_const_iterator<_Alvbase_wrapped>::difference_type _Off, _Vb_const_iterator<_Alvbase_wrapped> _Right) { + typename _Vb_const_iterator<_Alvbase_wrapped>::difference_type _Off, + _Vb_const_iterator<_Alvbase_wrapped> _Right) noexcept { return _Right += _Off; } @@ -2102,7 +2104,7 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Cont = static_cast(this->_Getcont()); _STL_VERIFY(_Cont, "cannot dereference value-initialized vector iterator"); @@ -2113,51 +2115,51 @@ public: return _Reft(*this); } - _Vb_iterator& operator++() { + _Vb_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Vb_iterator operator++(int) { + _Vb_iterator operator++(int) noexcept { _Vb_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Vb_iterator& operator--() { + _Vb_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Vb_iterator operator--(int) { + _Vb_iterator operator--(int) noexcept { _Vb_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; } - _Vb_iterator& operator+=(const difference_type _Off) { + _Vb_iterator& operator+=(const difference_type _Off) noexcept { _Mybase::operator+=(_Off); return *this; } - _NODISCARD _Vb_iterator operator+(const difference_type _Off) const { + _NODISCARD _Vb_iterator operator+(const difference_type _Off) const noexcept { _Vb_iterator _Tmp = *this; return _Tmp += _Off; } - _Vb_iterator& operator-=(const difference_type _Off) { + _Vb_iterator& operator-=(const difference_type _Off) noexcept { _Mybase::operator-=(_Off); return *this; } using _Mybase::operator-; - _NODISCARD _Vb_iterator operator-(const difference_type _Off) const { + _NODISCARD _Vb_iterator operator-(const difference_type _Off) const noexcept { _Vb_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } @@ -2166,7 +2168,7 @@ public: template _NODISCARD _Vb_iterator<_Alvbase_wrapped> operator+( - typename _Vb_iterator<_Alvbase_wrapped>::difference_type _Off, _Vb_iterator<_Alvbase_wrapped> _Right) { + typename _Vb_iterator<_Alvbase_wrapped>::difference_type _Off, _Vb_iterator<_Alvbase_wrapped> _Right) noexcept { return _Right += _Off; } @@ -2238,7 +2240,7 @@ public: return _Myvec._Getal(); } - static size_type _Nw(size_type _Count) { + static size_type _Nw(size_type _Count) noexcept { return (_Count + _VBITS - 1) / _VBITS; } diff --git a/stl/inc/xatomic.h b/stl/inc/xatomic.h index 467469cda4d..4a96fef4303 100644 --- a/stl/inc/xatomic.h +++ b/stl/inc/xatomic.h @@ -11,9 +11,9 @@ #include #include -#if defined(_WIN64) && (_MSC_FULL_VER < 192829203) // TRANSITION +#if defined(_WIN64) && (_MSC_FULL_VER <= 192829213) // TRANSITION #include // Visual Studio 2019 to define 128-bit CAS in -#endif // defined(_WIN64) && (_MSC_FULL_VER < 192829203), TRANSITION +#endif // defined(_WIN64) && (_MSC_FULL_VER <= 192829213), TRANSITION #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) diff --git a/stl/inc/xfilesystem_abi.h b/stl/inc/xfilesystem_abi.h index 2e3fcddde59..7991c1d522e 100644 --- a/stl/inc/xfilesystem_abi.h +++ b/stl/inc/xfilesystem_abi.h @@ -239,8 +239,9 @@ _NODISCARD __std_win_error __stdcall __std_fs_open_handle(_Out_ __std_fs_file_ha void __stdcall __std_fs_close_handle(__std_fs_file_handle _Handle) noexcept; -_NODISCARD __std_win_error __stdcall __std_fs_get_file_attributes_by_handle( - _In_ __std_fs_file_handle _Handle, _Out_ unsigned long* _File_attributes) noexcept; +_NODISCARD _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_file_attributes_by_handle( + _In_ __std_fs_file_handle _Handle, _Out_ unsigned long* _File_attributes) noexcept; _NODISCARD __std_ulong_and_error __stdcall __std_fs_get_final_path_name_by_handle(_In_ __std_fs_file_handle _Handle, _Out_writes_z_(_Target_size) wchar_t* _Target, _In_ unsigned long _Target_size, @@ -259,9 +260,9 @@ _NODISCARD __std_win_error __stdcall __std_fs_directory_iterator_open(_In_z_ con void __stdcall __std_fs_directory_iterator_close(_In_ __std_fs_dir_handle _Handle) noexcept; -_NODISCARD __std_win_error __stdcall __std_fs_get_stats(_In_z_ const wchar_t* _Path, _Out_ __std_fs_stats* _Stats, - _In_ __std_fs_stats_flags _Flags, - _In_ __std_fs_file_attr _Symlink_attribute_hint = __std_fs_file_attr::_Invalid) noexcept; +_NODISCARD _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_stats(_In_z_ const wchar_t* _Path, __std_fs_stats* _Stats, _In_ __std_fs_stats_flags _Flags, + _In_ __std_fs_file_attr _Symlink_attribute_hint = __std_fs_file_attr::_Invalid) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_directory_iterator_advance( _In_ __std_fs_dir_handle _Handle, _Out_ __std_fs_find_data* _Results) noexcept; @@ -280,8 +281,8 @@ _NODISCARD __std_fs_convert_result __stdcall __std_fs_convert_wide_to_narrow_rep _In_ __std_code_page _Code_page, _In_reads_(_Input_len) const wchar_t* _Input_str, _In_ int _Input_len, _Out_writes_opt_(_Output_len) char* _Output_str, _In_ int _Output_len) noexcept; -_NODISCARD __std_win_error __stdcall __std_fs_get_file_id( - _Out_ __std_fs_file_id* _Id, _In_z_ const wchar_t* _Path) noexcept; +_NODISCARD _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_file_id(_Out_ __std_fs_file_id* _Id, _In_z_ const wchar_t* _Path) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_set_last_write_time( _In_ long long _Last_write_filetime, _In_z_ const wchar_t* _Path) noexcept; @@ -289,11 +290,12 @@ _NODISCARD __std_win_error __stdcall __std_fs_set_last_write_time( _NODISCARD __std_win_error __stdcall __std_fs_change_permissions( _In_z_ const wchar_t* _Path, _In_ bool _Follow_symlinks, _In_ bool _Readonly) noexcept; -_NODISCARD __std_ulong_and_error __stdcall __std_fs_get_temp_path( - _Out_writes_z_(__std_fs_temp_path_max) wchar_t* _Target) noexcept; +_NODISCARD _Success_(return._Error == __std_win_error::_Success) __std_ulong_and_error + __stdcall __std_fs_get_temp_path(_Out_writes_z_(__std_fs_temp_path_max) wchar_t* _Target) noexcept; -_NODISCARD __std_ulong_and_error __stdcall __std_fs_get_current_path( - _In_ unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* _Target) noexcept; +_NODISCARD _Success_(return._Error == __std_win_error::_Success) __std_ulong_and_error + __stdcall __std_fs_get_current_path( + _In_ unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_set_current_path(_In_z_ const wchar_t* _Target) noexcept; @@ -309,8 +311,9 @@ _NODISCARD __std_win_error __stdcall __std_fs_create_symbolic_link( _NODISCARD __std_win_error __stdcall __std_fs_read_reparse_data_buffer(_In_ __std_fs_file_handle _Handle, _Out_writes_bytes_(_Buffer_size) void* _Buffer, _In_ unsigned long _Buffer_size) noexcept; -_NODISCARD __std_win_error __stdcall __std_fs_read_name_from_reparse_data_buffer( - _In_ __std_fs_reparse_data_buffer* _Handle, _Out_ wchar_t** _Offset, _Out_ unsigned short* _Length) noexcept; +_NODISCARD _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_read_name_from_reparse_data_buffer( + _In_ __std_fs_reparse_data_buffer* _Handle, _Out_ wchar_t** _Offset, _Out_ unsigned short* _Length) noexcept; struct __std_fs_create_directory_result { bool _Created; diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 5877d9aecb8..3f2a2a488de 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -461,49 +461,6 @@ const _Facet& __CRTDECL use_facet(const locale& _Loc) { // get facet reference f _END_LOCK() } // end of use_facet body -// FUNCTION TEMPLATE _Getloctxt -template -int __CRTDECL _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields, const _Elem* _Ptr) { - // find field at _Ptr that matches longest in [_First, _Last) - for (size_t _Off = 0; _Ptr[_Off] != _Elem{}; ++_Off) { - if (_Ptr[_Off] == _Ptr[0]) { - ++_Numfields; // add fields with leading mark to initial count - } - } - - string _Str(_Numfields, '\0'); // one column counter for each field - - int _Ans = -2; // no candidates so far - for (size_t _Column = 1;; ++_Column, (void) ++_First, _Ans = -1) { // test each element against all viable fields - bool _Prefix = false; // seen at least one valid prefix - size_t _Off = 0; // offset into fields - size_t _Field = 0; // current field number - - for (; _Field < _Numfields; ++_Field) { // test element at _Column in field _Field - while (_Ptr[_Off] != _Elem{} && _Ptr[_Off] != _Ptr[0]) { // find beginning of field - ++_Off; - } - - if (_Str[_Field] != '\0') { - _Off += _Str[_Field]; // skip tested columns in field - } else if (_Ptr[_Off += _Column] == _Ptr[0] - || _Ptr[_Off] == _Elem{}) { // matched all of field, save as possible answer - _Str[_Field] = static_cast(_Column < 127 ? _Column : 127); // save skip count if small enough - _Ans = static_cast(_Field); // save answer - } else if (_First == _Last || _Ptr[_Off] != *_First) { - _Str[_Field] = static_cast(_Column < 127 ? _Column : 127); // no match, just save skip count - } else { - _Prefix = true; // still a valid prefix - } - } - - if (!_Prefix || _First == _Last) { - break; // no pending prefixes or no input, give up - } - } - return _Ans; // return field number or negative value on failure -} - // FUNCTION TEMPLATE _Maklocbyte template char __CRTDECL _Maklocbyte(_Elem _Char, const _Locinfo::_Cvtvec&) { @@ -3263,6 +3220,50 @@ protected: virtual __CLR_OR_THIS_CALL ~ctype_byname() noexcept {} }; +// FUNCTION TEMPLATE _Getloctxt +template +int __CRTDECL _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields, const _Elem* _Ptr) { + // find field at _Ptr that matches longest in [_First, _Last) + for (size_t _Off = 0; _Ptr[_Off] != _Elem{}; ++_Off) { + if (_Ptr[_Off] == _Ptr[0]) { + ++_Numfields; // add fields with leading mark to initial count + } + } + + string _Str(_Numfields, '\0'); // one column counter for each field + const ctype<_Elem>& _CType = _STD use_facet>(locale{}); + + int _Ans = -2; // no candidates so far + for (size_t _Column = 1;; ++_Column, (void) ++_First, _Ans = -1) { // test each element against all viable fields + bool _Prefix = false; // seen at least one valid prefix + size_t _Off = 0; // offset into fields + size_t _Field = 0; // current field number + + for (; _Field < _Numfields; ++_Field) { // test element at _Column in field _Field + while (_Ptr[_Off] != _Elem{} && _Ptr[_Off] != _Ptr[0]) { // find beginning of field + ++_Off; + } + + if (_Str[_Field] != '\0') { + _Off += _Str[_Field]; // skip tested columns in field + } else if (_Ptr[_Off += _Column] == _Ptr[0] + || _Ptr[_Off] == _Elem{}) { // matched all of field, save as possible answer + _Str[_Field] = static_cast(_Column < 127 ? _Column : 127); // save skip count if small enough + _Ans = static_cast(_Field); // save answer + } else if (_First == _Last || _CType.tolower(_Ptr[_Off]) != _CType.tolower(static_cast<_Elem>(*_First))) { + _Str[_Field] = static_cast(_Column < 127 ? _Column : 127); // no match, just save skip count + } else { + _Prefix = true; // still a valid prefix + } + } + + if (!_Prefix || _First == _Last) { + break; // no pending prefixes or no input, give up + } + } + return _Ans; // return field number or negative value on failure +} + #if defined(_DLL_CPPLIB) #if !defined(_CRTBLD) || defined(__FORCE_INSTANCE) template class _CRTIMP2_PURE_IMPORT codecvt; diff --git a/stl/inc/xlocinfo.h b/stl/inc/xlocinfo.h index b9756b03dd2..5cfba660a07 100644 --- a/stl/inc/xlocinfo.h +++ b/stl/inc/xlocinfo.h @@ -87,7 +87,8 @@ _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Getdateorder(); _Mbrtowc(_Out_opt_ wchar_t*, const char*, size_t, mbstate_t*, const _Cvtvec*); #else // _M_CEE_PURE -_MRTIMP2 int __cdecl _Mbrtowc(_Out_opt_ wchar_t*, const char*, size_t, mbstate_t*, const _Cvtvec*); +_MRTIMP2 _Success_(return >= 0) int __cdecl _Mbrtowc( + _When_(_Max_multibyte != 0, _Out_) wchar_t*, const char*, size_t _Max_multibyte, mbstate_t*, const _Cvtvec*); #endif // _M_CEE_PURE _CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _Stof(const char*, _Out_opt_ _Deref_post_opt_valid_ char**, long); @@ -100,7 +101,8 @@ _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Strxfrm(_Out_writes_(_End1 - _Stri _In_z_ char* _End1, const char*, const char*, const _Collvec*); _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Tolower(int, const _Ctypevec*); _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Toupper(int, const _Ctypevec*); -_CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Wcrtomb(_Out_ char*, wchar_t, mbstate_t*, const _Cvtvec*); +_CRTIMP2_PURE _Success_(return != -1) int __CLRCALL_PURE_OR_CDECL + _Wcrtomb(_Out_ char*, wchar_t, mbstate_t*, const _Cvtvec*); _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Wcscoll( const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const _Collvec*); _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm(_Out_writes_(_End1 - _String1) _Post_readable_size_(return ) diff --git a/stl/inc/xlocmon b/stl/inc/xlocmon index 8b50d0e1ec0..960e74a288f 100644 --- a/stl/inc/xlocmon +++ b/stl/inc/xlocmon @@ -422,7 +422,8 @@ private: _Ppunct_fac = _STD addressof(_STD use_facet<_Mypunct0>(_Iosbase.getloc())); // local } - bool _Bad = false, _Neg = false; + bool _Bad = false; + bool _Neg = false; string_type _Sign; const money_base::pattern _Pattern = _Ppunct_fac->neg_format(); string _Val; diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index e2c887b5f1f..1541b393bae 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1146,6 +1146,45 @@ __PURE_APPDOMAIN_GLOBAL locale::id num_get<_Elem, _InIt>::id; #pragma clang diagnostic pop #endif // __clang__ +// STRUCT TEMPLATE _Hex_float_precision +template +struct _Hex_float_precision; + +template <> +struct _Hex_float_precision { + // the number of hexits needed to represent (DBL_MANT_DIG - 1) bits after the radix point exactly + static constexpr int value = ((DBL_MANT_DIG - 1) + 3) / 4; +}; + +template <> +struct _Hex_float_precision { + // the number of hexits needed to represent (LDBL_MANT_DIG - 1) bits after the radix point exactly + static constexpr int value = ((LDBL_MANT_DIG - 1) + 3) / 4; +}; + +// FUNCTION TEMPLATE _Float_put_desired_precision +template +int _Float_put_desired_precision(const streamsize _Precision, const ios_base::fmtflags _Float_flags) { + const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific); + if (_Is_hex) { + return _Hex_float_precision<_Ty>::value; + } + + if (_Precision > 0) { + return static_cast(_Precision); + } else if (_Precision == 0) { + const bool _Is_default_float = _Float_flags == 0; + if (_Is_default_float) { + return 1; + } else { + return 0; + } + } else { + constexpr int _Default_precision = 6; + return _Default_precision; + } +} + // CLASS TEMPLATE num_put template >> class num_put : public locale::facet { // facet for converting encoded numbers to text @@ -1258,7 +1297,8 @@ protected: #pragma warning(disable : 4774) // format string expected in argument N is not a string literal (/Wall) virtual _OutIt __CLR_OR_THIS_CALL do_put( _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest - char _Buf[2 * _MAX_INT_DIG], _Fmt[6]; + char _Buf[2 * _MAX_INT_DIG]; + char _Fmt[6]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "ld", _Iosbase.flags()), _Val))); @@ -1266,7 +1306,8 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest - char _Buf[2 * _MAX_INT_DIG], _Fmt[6]; + char _Buf[2 * _MAX_INT_DIG]; + char _Fmt[6]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "lu", _Iosbase.flags()), _Val))); @@ -1274,7 +1315,8 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put( _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long long _Val) const { // put formatted long long to _Dest - char _Buf[2 * _MAX_INT_DIG], _Fmt[8]; + char _Buf[2 * _MAX_INT_DIG]; + char _Fmt[8]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "Ld", _Iosbase.flags()), _Val))); @@ -1282,7 +1324,8 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long long _Val) const { // put formatted unsigned long long to _Dest - char _Buf[2 * _MAX_INT_DIG], _Fmt[8]; + char _Buf[2 * _MAX_INT_DIG]; + char _Fmt[8]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "Lu", _Iosbase.flags()), _Val))); @@ -1292,10 +1335,14 @@ protected: _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest string _Buf; char _Fmt[8]; - bool _Isfixed = (_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed; - streamsize _Precision = _Iosbase.precision() <= 0 && !_Isfixed ? 6 : _Iosbase.precision(); // desired precision - size_t _Bufsize = static_cast(_Precision); - if (_Isfixed && 1e10 < _CSTD fabs(_Val)) { // f or F format + const auto _Float_flags = _Iosbase.flags() & ios_base::floatfield; + const bool _Is_fixed = _Float_flags == ios_base::fixed; + const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific); + const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting + const int _Desired_precision = + _Float_put_desired_precision(_Precision, _Float_flags); // desired precision + size_t _Bufsize = static_cast(_Desired_precision); + if (_Is_fixed && 1e10 < _CSTD fabs(_Val)) { // f or F format int _Ptwo; (void) _CSTD frexp(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; @@ -1312,10 +1359,14 @@ protected: _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest string _Buf; char _Fmt[8]; - bool _Isfixed = (_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed; - streamsize _Precision = _Iosbase.precision() <= 0 && !_Isfixed ? 6 : _Iosbase.precision(); // desired precision - size_t _Bufsize = static_cast(_Precision); - if (_Isfixed && 1e10 < _CSTD fabsl(_Val)) { // f or F format + const auto _Float_flags = _Iosbase.flags() & ios_base::floatfield; + const bool _Is_fixed = _Float_flags == ios_base::fixed; + const bool _Is_hex = _Float_flags == (ios_base::fixed | ios_base::scientific); + const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting + const int _Desired_precision = + _Float_put_desired_precision(_Precision, _Float_flags); // desired precision + size_t _Bufsize = static_cast(_Desired_precision); + if (_Is_fixed && 1e10 < _CSTD fabsl(_Val)) { // f or F format int _Ptwo; (void) _CSTD frexpl(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; diff --git a/stl/inc/xloctime b/stl/inc/xloctime index bf342ba6bd9..baf58d94310 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -132,6 +132,11 @@ public: } _First = do_get(_First, _Last, _Iosbase, _State, _Pt, _Specifier, _Modifier); // convert a single field + + if (_State != ios_base::goodbit) { + // Failed to convert the field. Do not proceed to the next fields. Return with failed _State. + break; + } } } @@ -534,7 +539,8 @@ protected: private: ios_base::iostate __CLRCALL_OR_CDECL _Getint(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& _Val, const _Ctype& _Ctype_fac) const { // get integer in range [_Lo, _Hi] from [_First, _Last) - char _Ac[_MAX_INT_DIG], *_Ep; + char _Ac[_MAX_INT_DIG]; + char* _Ep; char* _Ptr = _Ac; char _Ch; diff --git a/stl/inc/xstring b/stl/inc/xstring index 787ba828f27..5cd221c2f72 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1831,7 +1831,7 @@ public: this->_Adopt(_Pstring); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Ptr, "cannot dereference value-initialized string iterator"); const auto _Mycont = static_cast(this->_Getcont()); @@ -1847,11 +1847,11 @@ public: return *_Ptr; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _String_const_iterator& operator++() { + _String_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Ptr, "cannot increment value-initialized string iterator"); const auto _Mycont = static_cast(this->_Getcont()); @@ -1864,13 +1864,13 @@ public: return *this; } - _String_const_iterator operator++(int) { + _String_const_iterator operator++(int) noexcept { _String_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _String_const_iterator& operator--() { + _String_const_iterator& operator--() noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Ptr, "cannot decrement value-initialized string iterator"); const auto _Mycont = static_cast(this->_Getcont()); @@ -1883,7 +1883,7 @@ public: return *this; } - _String_const_iterator operator--(int) { + _String_const_iterator operator--(int) noexcept { _String_const_iterator _Tmp = *this; --*this; return _Tmp; @@ -1916,7 +1916,7 @@ public: #endif // _ITERATOR_DEBUG_LEVEL >= 1 } - _String_const_iterator& operator+=(const difference_type _Off) { + _String_const_iterator& operator+=(const difference_type _Off) noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _Verify_offset(_Off); #endif // _ITERATOR_DEBUG_LEVEL >= 1 @@ -1924,56 +1924,56 @@ public: return *this; } - _NODISCARD _String_const_iterator operator+(const difference_type _Off) const { + _NODISCARD _String_const_iterator operator+(const difference_type _Off) const noexcept { _String_const_iterator _Tmp = *this; return _Tmp += _Off; } - _String_const_iterator& operator-=(const difference_type _Off) { + _String_const_iterator& operator-=(const difference_type _Off) noexcept { return *this += -_Off; } - _NODISCARD _String_const_iterator operator-(const difference_type _Off) const { + _NODISCARD _String_const_iterator operator-(const difference_type _Off) const noexcept { _String_const_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD difference_type operator-(const _String_const_iterator& _Right) const { + _NODISCARD difference_type operator-(const _String_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr - _Right._Ptr; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } - _NODISCARD bool operator==(const _String_const_iterator& _Right) const { + _NODISCARD bool operator==(const _String_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _String_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _String_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD bool operator<(const _String_const_iterator& _Right) const { + _NODISCARD bool operator<(const _String_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr < _Right._Ptr; } - _NODISCARD bool operator>(const _String_const_iterator& _Right) const { + _NODISCARD bool operator>(const _String_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD bool operator<=(const _String_const_iterator& _Right) const { + _NODISCARD bool operator<=(const _String_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD bool operator>=(const _String_const_iterator& _Right) const { + _NODISCARD bool operator>=(const _String_const_iterator& _Right) const noexcept { return !(*this < _Right); } - void _Compat(const _String_const_iterator& _Right) const { // test for compatible iterator pair + void _Compat(const _String_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "string iterators incompatible (e.g." " point to different string instances)"); @@ -1983,7 +1983,7 @@ public: } #if _ITERATOR_DEBUG_LEVEL >= 1 - friend void _Verify_range(const _String_const_iterator& _First, const _String_const_iterator& _Last) { + friend void _Verify_range(const _String_const_iterator& _First, const _String_const_iterator& _Last) noexcept { _STL_VERIFY(_First._Getcont() == _Last._Getcont(), "string iterators in range are from different containers"); _STL_VERIFY(_First._Ptr <= _Last._Ptr, "string iterator range transposed"); } @@ -1991,11 +1991,11 @@ public: using _Prevent_inheriting_unwrap = _String_const_iterator; - _NODISCARD const value_type* _Unwrapped() const { + _NODISCARD const value_type* _Unwrapped() const noexcept { return _Unfancy(_Ptr); } - void _Seek_to(const value_type* _It) { + void _Seek_to(const value_type* _It) noexcept { _Ptr = _Refancy(const_cast(_It)); } @@ -2004,7 +2004,7 @@ public: template _NODISCARD _String_const_iterator<_Mystr> operator+( - typename _String_const_iterator<_Mystr>::difference_type _Off, _String_const_iterator<_Mystr> _Next) { + typename _String_const_iterator<_Mystr>::difference_type _Off, _String_const_iterator<_Mystr> _Next) noexcept { return _Next += _Off; } @@ -2056,72 +2056,72 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _String_iterator& operator++() { + _String_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _String_iterator operator++(int) { + _String_iterator operator++(int) noexcept { _String_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _String_iterator& operator--() { + _String_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _String_iterator operator--(int) { + _String_iterator operator--(int) noexcept { _String_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; } - _String_iterator& operator+=(const difference_type _Off) { + _String_iterator& operator+=(const difference_type _Off) noexcept { _Mybase::operator+=(_Off); return *this; } - _NODISCARD _String_iterator operator+(const difference_type _Off) const { + _NODISCARD _String_iterator operator+(const difference_type _Off) const noexcept { _String_iterator _Tmp = *this; return _Tmp += _Off; } - _String_iterator& operator-=(const difference_type _Off) { + _String_iterator& operator-=(const difference_type _Off) noexcept { _Mybase::operator-=(_Off); return *this; } using _Mybase::operator-; - _NODISCARD _String_iterator operator-(const difference_type _Off) const { + _NODISCARD _String_iterator operator-(const difference_type _Off) const noexcept { _String_iterator _Tmp = *this; return _Tmp -= _Off; } - _NODISCARD reference operator[](const difference_type _Off) const { + _NODISCARD reference operator[](const difference_type _Off) const noexcept { return const_cast(_Mybase::operator[](_Off)); } using _Prevent_inheriting_unwrap = _String_iterator; - _NODISCARD value_type* _Unwrapped() const { + _NODISCARD value_type* _Unwrapped() const noexcept { return const_cast(_Unfancy(this->_Ptr)); } }; template _NODISCARD _String_iterator<_Mystr> operator+( - typename _String_iterator<_Mystr>::difference_type _Off, _String_iterator<_Mystr> _Next) { + typename _String_iterator<_Mystr>::difference_type _Off, _String_iterator<_Mystr> _Next) noexcept { return _Next += _Off; } @@ -2179,7 +2179,7 @@ public: using reference = value_type&; using const_reference = const value_type&; - _String_val() : _Bx(), _Mysize(0), _Myres(0) {} + _String_val() noexcept : _Bx(), _Mysize(0), _Myres(0) {} // length of internal buffer, [1, 16]: static constexpr size_type _BUF_SIZE = 16 / sizeof(value_type) < 1 ? 1 : 16 / sizeof(value_type); @@ -2233,7 +2233,7 @@ public: } union _Bxty { // storage for small buffer or pointer to larger one - _Bxty() {} // user-provided, for fancy pointers + _Bxty() noexcept {} // user-provided, for fancy pointers ~_Bxty() noexcept {} // user-provided, for fancy pointers @@ -3270,8 +3270,8 @@ public: return *this; } - basic_string& erase(const size_type _Off, size_type _Count) { // erase elements [_Off, _Off + _Count) - _Mypair._Myval2._Check_offset(_Off); +private: + basic_string& _Erase_noexcept(const size_type _Off, size_type _Count) noexcept { _Count = _Mypair._Myval2._Clamp_suffix_size(_Off, _Count); const size_type _Old_size = _Mypair._Myval2._Mysize; _Elem* const _My_ptr = _Mypair._Myval2._Myptr(); @@ -3282,12 +3282,18 @@ public: return *this; } +public: + basic_string& erase(const size_type _Off, const size_type _Count) { // erase elements [_Off, _Off + _Count) + _Mypair._Myval2._Check_offset(_Off); + return _Erase_noexcept(_Off, _Count); + } + iterator erase(const const_iterator _Where) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Where._Getcont() == _STD addressof(_Mypair._Myval2), "string iterator incompatible"); #endif // _ITERATOR_DEBUG_LEVEL != 0 const auto _Off = static_cast(_Unfancy(_Where._Ptr) - _Mypair._Myval2._Myptr()); - erase(_Off, 1); + _Erase_noexcept(_Off, 1); return begin() + static_cast(_Off); } @@ -3297,7 +3303,7 @@ public: _STL_VERIFY(_First._Getcont() == _STD addressof(_Mypair._Myval2), "string iterators incompatible"); #endif // _ITERATOR_DEBUG_LEVEL != 0 const auto _Off = static_cast(_Unfancy(_First._Ptr) - _Mypair._Myval2._Myptr()); - erase(_Off, static_cast(_Last._Ptr - _First._Ptr)); + _Erase_noexcept(_Off, static_cast(_Last._Ptr - _First._Ptr)); return begin() + static_cast(_Off); } diff --git a/stl/inc/xtree b/stl/inc/xtree index 26e9416211d..1dd2fffbe58 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -40,15 +40,15 @@ public: this->_Adopt(_Plist); } - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return _Ptr->_Myval; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Tree_unchecked_const_iterator& operator++() { + _Tree_unchecked_const_iterator& operator++() noexcept { if (_Ptr->_Right->_Isnil) { // climb looking for right subtree _Nodeptr _Pnode; while (!(_Pnode = _Ptr->_Parent)->_Isnil && _Ptr == _Pnode->_Right) { @@ -63,13 +63,13 @@ public: return *this; } - _Tree_unchecked_const_iterator operator++(int) { + _Tree_unchecked_const_iterator operator++(int) noexcept { _Tree_unchecked_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _Tree_unchecked_const_iterator& operator--() { + _Tree_unchecked_const_iterator& operator--() noexcept { if (_Ptr->_Isnil) { _Ptr = _Ptr->_Right; // end() ==> rightmost } else if (_Ptr->_Left->_Isnil) { // climb looking for left subtree @@ -88,17 +88,17 @@ public: return *this; } - _Tree_unchecked_const_iterator operator--(int) { + _Tree_unchecked_const_iterator operator--(int) noexcept { _Tree_unchecked_const_iterator _Tmp = *this; --*this; return _Tmp; } - _NODISCARD bool operator==(const _Tree_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Tree_unchecked_const_iterator& _Right) const noexcept { return _Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _Tree_unchecked_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Tree_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -129,31 +129,31 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Tree_unchecked_iterator& operator++() { + _Tree_unchecked_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Tree_unchecked_iterator operator++(int) { + _Tree_unchecked_iterator operator++(int) noexcept { _Tree_unchecked_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Tree_unchecked_iterator& operator--() { + _Tree_unchecked_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Tree_unchecked_iterator operator--(int) { + _Tree_unchecked_iterator operator--(int) noexcept { _Tree_unchecked_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; @@ -175,7 +175,7 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 const auto _Mycont = static_cast(this->_Getcont()); _STL_ASSERT(_Mycont, "cannot dereference value-initialized map/set iterator"); @@ -185,11 +185,11 @@ public: return this->_Ptr->_Myval; } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Tree_const_iterator& operator++() { + _Tree_const_iterator& operator++() noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(this->_Getcont(), "cannot increment value-initialized map/set iterator"); _STL_VERIFY(!this->_Ptr->_Isnil, "cannot increment end map/set iterator"); @@ -199,13 +199,13 @@ public: return *this; } - _Tree_const_iterator operator++(int) { + _Tree_const_iterator operator++(int) noexcept { _Tree_const_iterator _Tmp = *this; ++*this; return _Tmp; } - _Tree_const_iterator& operator--() { + _Tree_const_iterator& operator--() noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_ASSERT(this->_Getcont(), "cannot decrement value-initialized map/set iterator"); _Nodeptr _Ptrsav = this->_Ptr; @@ -218,13 +218,13 @@ public: return *this; } - _Tree_const_iterator operator--(int) { + _Tree_const_iterator operator--(int) noexcept { _Tree_const_iterator _Tmp = *this; --*this; return _Tmp; } - _NODISCARD bool operator==(const _Tree_const_iterator& _Right) const { + _NODISCARD bool operator==(const _Tree_const_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2 _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "map/set iterators incompatible"); #endif // _ITERATOR_DEBUG_LEVEL == 2 @@ -232,23 +232,23 @@ public: return this->_Ptr == _Right._Ptr; } - _NODISCARD bool operator!=(const _Tree_const_iterator& _Right) const { + _NODISCARD bool operator!=(const _Tree_const_iterator& _Right) const noexcept { return !(*this == _Right); } #if _ITERATOR_DEBUG_LEVEL == 2 - friend void _Verify_range(const _Tree_const_iterator& _First, const _Tree_const_iterator& _Last) { + friend void _Verify_range(const _Tree_const_iterator& _First, const _Tree_const_iterator& _Last) noexcept { _STL_VERIFY(_First._Getcont() == _Last._Getcont(), "map/set iterators in range are from different containers"); } #endif // _ITERATOR_DEBUG_LEVEL == 2 using _Prevent_inheriting_unwrap = _Tree_const_iterator; - _NODISCARD _Tree_unchecked_const_iterator<_Mytree> _Unwrapped() const { + _NODISCARD _Tree_unchecked_const_iterator<_Mytree> _Unwrapped() const noexcept { return _Tree_unchecked_const_iterator<_Mytree>(this->_Ptr, static_cast(this->_Getcont())); } - void _Seek_to(const _Tree_unchecked_const_iterator<_Mytree> _It) { + void _Seek_to(const _Tree_unchecked_const_iterator<_Mytree> _It) noexcept { this->_Ptr = _It._Ptr; } }; @@ -269,31 +269,31 @@ public: using _Mybase::_Mybase; - _NODISCARD reference operator*() const { + _NODISCARD reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } - _NODISCARD pointer operator->() const { + _NODISCARD pointer operator->() const noexcept { return pointer_traits::pointer_to(**this); } - _Tree_iterator& operator++() { + _Tree_iterator& operator++() noexcept { _Mybase::operator++(); return *this; } - _Tree_iterator operator++(int) { + _Tree_iterator operator++(int) noexcept { _Tree_iterator _Tmp = *this; _Mybase::operator++(); return _Tmp; } - _Tree_iterator& operator--() { + _Tree_iterator& operator--() noexcept { _Mybase::operator--(); return *this; } - _Tree_iterator operator--(int) { + _Tree_iterator operator--(int) noexcept { _Tree_iterator _Tmp = *this; _Mybase::operator--(); return _Tmp; @@ -301,7 +301,7 @@ public: using _Prevent_inheriting_unwrap = _Tree_iterator; - _NODISCARD _Tree_unchecked_iterator<_Mytree> _Unwrapped() const { + _NODISCARD _Tree_unchecked_iterator<_Mytree> _Unwrapped() const noexcept { return _Tree_unchecked_iterator<_Mytree>(this->_Ptr, static_cast(this->_Getcont())); } }; diff --git a/stl/inc/xutility b/stl/inc/xutility index 9c82bb27c55..7a08e0a3cc5 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -815,44 +815,34 @@ concept sized_sentinel_for = sentinel_for<_Se, _It> // clang-format on // ALIAS TEMPLATE _Iter_concept -template >> -struct _Iter_concept_impl {}; - -// clang-format off -template - requires _Has_member_iterator_concept> -struct _Iter_concept_impl<_It, false> { - using type = typename iterator_traits<_It>::iterator_concept; +template +struct _Iter_concept_impl2 { + template + using _Apply = typename _Traits::iterator_category; }; - -template - requires (!_Has_member_iterator_concept> - && _Has_member_iterator_category>) -struct _Iter_concept_impl<_It, false> { - using type = typename iterator_traits<_It>::iterator_category; -}; -// clang-format on - -template -struct _Iter_concept_impl<_It, true> { - using type = random_access_iterator_tag; +template <> +struct _Iter_concept_impl2 { + // clang-format off + template + requires _Is_from_primary> + using _Apply = random_access_iterator_tag; + // clang-format on }; -template <_Has_member_iterator_concept _It> -struct _Iter_concept_impl<_It, true> { - using type = typename _It::iterator_concept; +template +struct _Iter_concept_impl1 { + template + using _Apply = typename _Traits::iterator_concept; }; - -// clang-format off -template - requires(!_Has_member_iterator_concept<_It> && _Has_member_iterator_category<_It>) -struct _Iter_concept_impl<_It, true> { - using type = typename _It::iterator_category; +template <> +struct _Iter_concept_impl1 { + template + using _Apply = typename _Iter_concept_impl2<_Has_member_iterator_category<_Traits>>::template _Apply<_It, _Traits>; }; -// clang-format on -template -using _Iter_concept = typename _Iter_concept_impl<_It>::type; +template >, _It, iterator_traits<_It>>> +using _Iter_concept = + typename _Iter_concept_impl1<_Has_member_iterator_concept<_Traits>>::template _Apply<_It, _Traits>; // clang-format off // CONCEPT input_iterator @@ -4090,14 +4080,24 @@ public: return _Left._Current - _Right._Get_last(); } - _NODISCARD friend constexpr reference iter_move(const move_iterator& _It) noexcept( - noexcept(_RANGES iter_move(_It._Current))) { + _NODISCARD friend constexpr reference iter_move(const move_iterator& _It) +#ifdef __EDG__ // TRANSITION, VSO-1132105 + noexcept(noexcept(_RANGES iter_move(_STD declval()))) +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_RANGES iter_move(_It._Current))) +#endif // TRANSITION, VSO-1132105 + { return _RANGES iter_move(_It._Current); } template _Iter2> - friend constexpr void iter_swap(const move_iterator& _Left, const move_iterator<_Iter2>& _Right) noexcept( - noexcept(_RANGES iter_swap(_Left._Current, _Right.base()))) { + friend constexpr void iter_swap(const move_iterator& _Left, const move_iterator<_Iter2>& _Right) +#ifdef __EDG__ // TRANSITION, VSO-1132105 + noexcept(noexcept(_RANGES iter_swap(_STD declval(), _STD declval()))) +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_RANGES iter_swap(_Left._Current, _Right.base()))) +#endif // TRANSITION, VSO-1132105 + { _RANGES iter_swap(_Left._Current, _Right.base()); } #endif // __cpp_lib_concepts @@ -5963,6 +5963,15 @@ template , int> = 0> _NODISCARD _CONSTEXPR_BIT_CAST bool _Is_finite(const _Ty _Xx) { // constexpr isfinite() return _Float_abs_bits(_Xx) < _Float_traits<_Ty>::_Exponent_mask; } + +// STRUCT _Nontrivial_dummy_type +struct _Nontrivial_dummy_type { + constexpr _Nontrivial_dummy_type() noexcept { + // This default constructor is user-provided to avoid zero-initialization when objects are value-initialized. + } +}; +_STL_INTERNAL_STATIC_ASSERT(!is_trivially_default_constructible_v<_Nontrivial_dummy_type>); + _STD_END #undef _CONSTEXPR_BIT_CAST #pragma pop_macro("new") diff --git a/stl/src/StlCompareStringA.cpp b/stl/src/StlCompareStringA.cpp index 70aad1a6442..977838a3768 100644 --- a/stl/src/StlCompareStringA.cpp +++ b/stl/src/StlCompareStringA.cpp @@ -30,8 +30,9 @@ // 2 - if lpString1 == lpString2 // 3 - if lpString1 > lpString2 // Failure: 0 -extern "C" int __cdecl __crtCompareStringA(LPCWSTR LocaleName, DWORD dwCmpFlags, LPCSTR lpString1, int cchCount1, - LPCSTR lpString2, int cchCount2, int code_page) { +extern "C" int __cdecl __crtCompareStringA(_In_z_ LPCWSTR LocaleName, _In_ DWORD dwCmpFlags, + _In_reads_(cchCount1) LPCSTR lpString1, _In_ int cchCount1, _In_reads_(cchCount2) LPCSTR lpString2, + _In_ int cchCount2, _In_ int code_page) { // CompareString will compare past null terminator. Must find null terminator if in string before cchCountn chars. if (cchCount1 > 0) { cchCount1 = static_cast(__strncnt(lpString1, cchCount1)); @@ -133,6 +134,7 @@ extern "C" int __cdecl __crtCompareStringA(LPCWSTR LocaleName, DWORD dwCmpFlags, } // allocate enough space for chars +#pragma warning(suppress : 6386) // TRANSITION, VSO-1152705 false buffer overrun report in _malloca_crt_t const __crt_scoped_stack_ptr wbuffer2(_malloca_crt_t(wchar_t, buff_size2)); if (wbuffer2.get() == nullptr) { return 0; diff --git a/stl/src/StlCompareStringW.cpp b/stl/src/StlCompareStringW.cpp index 05d24f2c172..d4c80042608 100644 --- a/stl/src/StlCompareStringW.cpp +++ b/stl/src/StlCompareStringW.cpp @@ -26,8 +26,9 @@ // 2 - if lpString1 == lpString2 // 3 - if lpString1 > lpString2 // Failure: 0 -extern "C" int __cdecl __crtCompareStringW( - LPCWSTR LocaleName, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2) { +extern "C" int __cdecl __crtCompareStringW(_In_z_ LPCWSTR LocaleName, _In_ DWORD dwCmpFlags, + _In_reads_(cchCount1) LPCWSTR lpString1, _In_ int cchCount1, _In_reads_(cchCount2) LPCWSTR lpString2, + _In_ int cchCount2) { // CompareString will compare past null terminator. Must find null terminator if in string before cchCountn wide // characters. if (cchCount1 > 0) { diff --git a/stl/src/StlLCMapStringA.cpp b/stl/src/StlLCMapStringA.cpp index 0829495a1d7..bb5651e3bce 100644 --- a/stl/src/StlLCMapStringA.cpp +++ b/stl/src/StlLCMapStringA.cpp @@ -29,8 +29,9 @@ // Exit: // Success: number of chars written to lpDestStr (including null terminator) // Failure: 0 -extern "C" int __cdecl __crtLCMapStringA(LPCWSTR LocaleName, DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, - LPSTR lpDestStr, int cchDest, int code_page, BOOL bError) { +extern "C" int __cdecl __crtLCMapStringA(_In_opt_z_ LPCWSTR LocaleName, _In_ DWORD dwMapFlags, + _In_reads_(cchSrc) LPCSTR lpSrcStr, _In_ int cchSrc, _Out_writes_opt_(cchDest) char* lpDestStr, _In_ int cchDest, + _In_ int code_page, _In_ BOOL bError) { // LCMapString will map past the null terminator. We must find the null // terminator if it occurs in the string before cchSrc characters // and cap the number of characters to be considered. @@ -94,6 +95,7 @@ extern "C" int __cdecl __crtLCMapStringA(LPCWSTR LocaleName, DWORD dwMapFlags, L int outbuff_size = retval; // allocate enough space for wide chars (includes null terminator if any) +#pragma warning(suppress : 6386) // TRANSITION, VSO-1152705 false buffer overrun report in _malloca_crt_t const __crt_scoped_stack_ptr outwbuffer(_malloca_crt_t(wchar_t, outbuff_size)); if (!outwbuffer) { return retval; diff --git a/stl/src/StlLCMapStringW.cpp b/stl/src/StlLCMapStringW.cpp index 33899e40319..d388a2a7770 100644 --- a/stl/src/StlLCMapStringW.cpp +++ b/stl/src/StlLCMapStringW.cpp @@ -31,8 +31,9 @@ // else // number of wide characters written to destination (including null terminator) // Failure: 0 -extern "C" int __cdecl __crtLCMapStringW(LPCWSTR const locale_name, DWORD const map_flags, LPCWSTR const source, - int source_count, LPWSTR const destination, int const destination_count) { +extern "C" int __cdecl __crtLCMapStringW(_In_opt_z_ LPCWSTR const locale_name, _In_ DWORD const map_flags, + _In_reads_(source_count) LPCWSTR const source, _In_ int source_count, + _Out_writes_opt_(destination_count) wchar_t* const destination, _In_ int const destination_count) { // LCMapString will map past the null terminator. We must find the null terminator if it occurs in the string // before source_count characters and cap the number of characters to be considered. if (source_count > 0) { diff --git a/stl/src/awint.hpp b/stl/src/awint.hpp index 9ed1b0d3d23..c52f3ce746f 100644 --- a/stl/src/awint.hpp +++ b/stl/src/awint.hpp @@ -28,13 +28,13 @@ _CRTIMP2 BOOL __cdecl __crtIsPackagedApp(); #else // _STL_WIN32_WINNT >= _WIN32_WINNT_WS03 -DWORD __cdecl __crtFlsAlloc(__in PFLS_CALLBACK_FUNCTION lpCallback); +DWORD __cdecl __crtFlsAlloc(_In_opt_ PFLS_CALLBACK_FUNCTION lpCallback); -BOOL __cdecl __crtFlsFree(__in DWORD dwFlsIndex); +BOOL __cdecl __crtFlsFree(_In_ DWORD dwFlsIndex); -PVOID __cdecl __crtFlsGetValue(__in DWORD dwFlsIndex); +PVOID __cdecl __crtFlsGetValue(_In_ DWORD dwFlsIndex); -BOOL __cdecl __crtFlsSetValue(__in DWORD dwFlsIndex, __in_opt PVOID lpFlsData); +BOOL __cdecl __crtFlsSetValue(_In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData); #endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WS03 @@ -120,74 +120,77 @@ BOOL __cdecl __crtFlsSetValue(__in DWORD dwFlsIndex, __in_opt PVOID lpFlsData); #else // _STL_WIN32_WINNT >= _WIN32_WINNT_VISTA _CRTIMP2 BOOL __cdecl __crtInitializeCriticalSectionEx( - __out LPCRITICAL_SECTION lpCriticalSection, __in DWORD dwSpinCount, __in DWORD Flags); + _Out_ LPCRITICAL_SECTION lpCriticalSection, _In_ DWORD dwSpinCount, _In_ DWORD Flags); +// N.B. Context is not used _CRTIMP2 BOOL __cdecl __crtInitOnceExecuteOnce( - _Inout_ PINIT_ONCE InitOnce, _In_ PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Out_opt_ LPVOID* Context); + _Inout_ PINIT_ONCE InitOnce, _In_ PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, LPVOID* Context); -_CRTIMP2 HANDLE __cdecl __crtCreateEventExW(__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes, __in_opt LPCWSTR lpName, - __reserved DWORD dwFlags, __in DWORD dwDesiredAccess); +_CRTIMP2 HANDLE __cdecl __crtCreateEventExW(_In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, _In_opt_ LPCWSTR lpName, + _In_ DWORD dwFlags, _In_ DWORD dwDesiredAccess); -_CRTIMP2 HANDLE __cdecl __crtCreateSemaphoreExW(__in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, - __in LONG lInitialCount, __in LONG lMaximumCount, __in_opt LPCWSTR lpName, __reserved DWORD dwFlags, - __in DWORD dwDesiredAccess); +_CRTIMP2 HANDLE __cdecl __crtCreateSemaphoreExW(_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, + _In_ LONG lInitialCount, _In_ LONG lMaximumCount, _In_opt_ LPCWSTR lpName, _Reserved_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess); _CRTIMP2 PTP_TIMER __cdecl __crtCreateThreadpoolTimer( - __in PTP_TIMER_CALLBACK pfnti, __inout_opt PVOID pv, __in_opt PTP_CALLBACK_ENVIRON pcbe); + _In_ PTP_TIMER_CALLBACK pfnti, _Inout_opt_ PVOID pv, _In_opt_ PTP_CALLBACK_ENVIRON pcbe); _CRTIMP2 VOID __cdecl __crtSetThreadpoolTimer( - __inout PTP_TIMER pti, __in_opt PFILETIME pftDueTime, __in DWORD msPeriod, __in_opt DWORD msWindowLength); + _Inout_ PTP_TIMER pti, _In_opt_ PFILETIME pftDueTime, _In_ DWORD msPeriod, _In_opt_ DWORD msWindowLength); -_CRTIMP2 VOID __cdecl __crtWaitForThreadpoolTimerCallbacks(__inout PTP_TIMER pti, __in BOOL fCancelPendingCallbacks); +_CRTIMP2 VOID __cdecl __crtWaitForThreadpoolTimerCallbacks(_Inout_ PTP_TIMER pti, _In_ BOOL fCancelPendingCallbacks); -_CRTIMP2 VOID __cdecl __crtCloseThreadpoolTimer(__inout PTP_TIMER pti); +_CRTIMP2 VOID __cdecl __crtCloseThreadpoolTimer(_Inout_ PTP_TIMER pti); _CRTIMP2 PTP_WAIT __cdecl __crtCreateThreadpoolWait( - __in PTP_WAIT_CALLBACK pfnwa, __inout_opt PVOID pv, __in_opt PTP_CALLBACK_ENVIRON pcbe); + _In_ PTP_WAIT_CALLBACK pfnwa, _Inout_opt_ PVOID pv, _In_opt_ PTP_CALLBACK_ENVIRON pcbe); -_CRTIMP2 VOID __cdecl __crtSetThreadpoolWait(__inout PTP_WAIT pwa, __in_opt HANDLE h, __in_opt PFILETIME pftTimeout); +_CRTIMP2 VOID __cdecl __crtSetThreadpoolWait(_Inout_ PTP_WAIT pwa, _In_opt_ HANDLE h, _In_opt_ PFILETIME pftTimeout); -_CRTIMP2 VOID __cdecl __crtCloseThreadpoolWait(__inout PTP_WAIT pwa); +_CRTIMP2 VOID __cdecl __crtCloseThreadpoolWait(_Inout_ PTP_WAIT pwa); _CRTIMP2 VOID __cdecl __crtFlushProcessWriteBuffers(); -_CRTIMP2 VOID __cdecl __crtFreeLibraryWhenCallbackReturns(__inout PTP_CALLBACK_INSTANCE pci, __in HMODULE mod); +_CRTIMP2 VOID __cdecl __crtFreeLibraryWhenCallbackReturns(_Inout_ PTP_CALLBACK_INSTANCE pci, _In_ HMODULE mod); _CRTIMP2 DWORD __cdecl __crtGetCurrentProcessorNumber(); _CRTIMP2 BOOLEAN __cdecl __crtCreateSymbolicLinkW( - __in LPCWSTR lpSymlinkFileName, __in LPCWSTR lpTargetFileName, __in DWORD dwFlags); + _In_ LPCWSTR lpSymlinkFileName, _In_ LPCWSTR lpTargetFileName, _In_ DWORD dwFlags); -_CRTIMP2 BOOL __cdecl __crtGetFileInformationByHandleEx(_In_ HANDLE hFile, - _In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, _Out_ LPVOID lpFileInformation, _In_ DWORD dwBufferSize); +_CRTIMP2 _Success_(return ) BOOL + __cdecl __crtGetFileInformationByHandleEx(_In_ HANDLE hFile, _In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, + _Out_writes_bytes_(dwBufferSize) LPVOID lpFileInformation, _In_ DWORD dwBufferSize); _CRTIMP2 BOOL __cdecl __crtSetFileInformationByHandle(_In_ HANDLE hFile, - _In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, _In_ LPVOID lpFileInformation, _In_ DWORD dwBufferSize); + _In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, _In_reads_bytes_(dwBufferSize) LPVOID lpFileInformation, + _In_ DWORD dwBufferSize); _CRTIMP2 ULONGLONG __cdecl __crtGetTickCount64(); -VOID __cdecl __crtInitializeConditionVariable(__out PCONDITION_VARIABLE); +VOID __cdecl __crtInitializeConditionVariable(_Out_ PCONDITION_VARIABLE); -VOID __cdecl __crtWakeConditionVariable(__inout PCONDITION_VARIABLE); +VOID __cdecl __crtWakeConditionVariable(_Inout_ PCONDITION_VARIABLE); -VOID __cdecl __crtWakeAllConditionVariable(__inout PCONDITION_VARIABLE); +VOID __cdecl __crtWakeAllConditionVariable(_Inout_ PCONDITION_VARIABLE); -BOOL __cdecl __crtSleepConditionVariableCS(__inout PCONDITION_VARIABLE, __inout PCRITICAL_SECTION, __in DWORD); +BOOL __cdecl __crtSleepConditionVariableCS(_Inout_ PCONDITION_VARIABLE, _Inout_ PCRITICAL_SECTION, _In_ DWORD); -VOID __cdecl __crtInitializeSRWLock(__out PSRWLOCK); +VOID __cdecl __crtInitializeSRWLock(_Out_ PSRWLOCK); -VOID __cdecl __crtAcquireSRWLockExclusive(__inout PSRWLOCK); +VOID __cdecl __crtAcquireSRWLockExclusive(_Inout_ PSRWLOCK); -VOID __cdecl __crtReleaseSRWLockExclusive(__inout PSRWLOCK); +VOID __cdecl __crtReleaseSRWLockExclusive(_Inout_ PSRWLOCK); -BOOL __cdecl __crtSleepConditionVariableSRW(__inout PCONDITION_VARIABLE, __inout PSRWLOCK, __in DWORD, __in ULONG); +BOOL __cdecl __crtSleepConditionVariableSRW(_Inout_ PCONDITION_VARIABLE, _Inout_ PSRWLOCK, _In_ DWORD, _In_ ULONG); PTP_WORK __cdecl __crtCreateThreadpoolWork( - __in PTP_WORK_CALLBACK pfnwk, __inout_opt PVOID pv, __in_opt PTP_CALLBACK_ENVIRON pcbe); + _In_ PTP_WORK_CALLBACK pfnwk, _Inout_opt_ PVOID pv, _In_opt_ PTP_CALLBACK_ENVIRON pcbe); -VOID __cdecl __crtSubmitThreadpoolWork(__inout PTP_WORK pwk); +VOID __cdecl __crtSubmitThreadpoolWork(_Inout_ PTP_WORK pwk); -VOID __cdecl __crtCloseThreadpoolWork(__inout PTP_WORK pwk); +VOID __cdecl __crtCloseThreadpoolWork(_Inout_ PTP_WORK pwk); _CRTIMP2 int __cdecl __crtCompareStringEx(_In_opt_ LPCWSTR lpLocaleName, _In_ DWORD dwCmpFlags, _In_NLS_string_(cchCount1) LPCWCH lpString1, _In_ int cchCount1, _In_NLS_string_(cchCount2) LPCWCH lpString2, @@ -197,7 +200,7 @@ _CRTIMP2 int __cdecl __crtLCMapStringEx(_In_opt_ LPCWSTR lpLocaleName, _In_ DWOR _In_reads_(cchSrc) LPCWSTR lpSrcStr, _In_ int cchSrc, _Out_writes_opt_(cchDest) LPWSTR lpDestStr, _In_ int cchDest); _CRTIMP2 int __cdecl __crtGetLocaleInfoEx( - _In_opt_ LPCWSTR lpLocaleName, _In_ LCTYPE LCType, _Out_opt_ LPWSTR lpLCData, _In_ int cchData); + _In_opt_ LPCWSTR lpLocaleName, _In_ LCTYPE LCType, _Out_writes_opt_(cchData) LPWSTR lpLCData, _In_ int cchData); #endif // _STL_WIN32_WINNT >= _WIN32_WINNT_VISTA @@ -207,7 +210,7 @@ _CRTIMP2 int __cdecl __crtGetLocaleInfoEx( #else // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7 -BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(__inout PSRWLOCK); +BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(_Inout_ PSRWLOCK); #endif // _STL_WIN32_WINNT >= _WIN32_WINNT_WIN7 @@ -228,7 +231,7 @@ _CRTIMP2 void __cdecl __crtGetSystemTimePreciseAsFileTime(_Out_ LPFILETIME lpSys #else // _STL_WIN32_WINNT < _WIN32_WINNT_VISTA -BOOL __cdecl __crtQueueUserWorkItem(__in LPTHREAD_START_ROUTINE function, __in_opt PVOID context, __in ULONG flags); +BOOL __cdecl __crtQueueUserWorkItem(_In_ LPTHREAD_START_ROUTINE function, _In_opt_ PVOID context, _In_ ULONG flags); #endif // _STL_WIN32_WINNT < _WIN32_WINNT_VISTA @@ -342,20 +345,20 @@ using PFNLCMAPSTRINGEX = int(WINAPI*)(LPCWSTR, DWORD, LPCWSTR, int, LPWSTR, in DYNAMICGETCACHEDFUNCTION(function_pointer_type, function_name, variable_name); \ if (variable_name != nullptr) -_CRTIMP2 int __cdecl __crtCompareStringA(_In_ LPCWSTR _LocaleName, _In_ DWORD _DwCmpFlags, +_CRTIMP2 int __cdecl __crtCompareStringA(_In_z_ LPCWSTR _LocaleName, _In_ DWORD _DwCmpFlags, _In_reads_(_CchCount1) LPCSTR _LpString1, _In_ int _CchCount1, _In_reads_(_CchCount2) LPCSTR _LpString2, _In_ int _CchCount2, _In_ int _CodePage); -_CRTIMP2 int __cdecl __crtCompareStringW(_In_ LPCWSTR _LocaleName, _In_ DWORD _DwCmpFlags, +_CRTIMP2 int __cdecl __crtCompareStringW(_In_z_ LPCWSTR _LocaleName, _In_ DWORD _DwCmpFlags, _In_reads_(_CchCount1) LPCWSTR _LpString1, _In_ int _CchCount1, _In_reads_(_CchCount2) LPCWSTR _LpString2, _In_ int _CchCount2); -_CRTIMP2 int __cdecl __crtLCMapStringA(_In_ LPCWSTR _LocaleName, _In_ DWORD _DwMapFlag, - _In_reads_(_CchSrc) LPCSTR _LpSrcStr, _In_ int _CchSrc, _Out_writes_opt_(_CchDest) LPSTR _LpDestStr, +_CRTIMP2 int __cdecl __crtLCMapStringA(_In_opt_z_ LPCWSTR _LocaleName, _In_ DWORD _DwMapFlag, + _In_reads_(_CchSrc) LPCSTR _LpSrcStr, _In_ int _CchSrc, _Out_writes_opt_(_CchDest) char* _LpDestStr, _In_ int _CchDest, _In_ int _CodePage, _In_ BOOL _BError); -_CRTIMP2 int __cdecl __crtLCMapStringW(_In_ LPCWSTR _LocaleName, _In_ DWORD _DWMapFlag, - _In_reads_(_CchSrc) LPCWSTR _LpSrcStr, _In_ int _CchSrc, _Out_writes_opt_(_CchDest) LPWSTR _LpDestStr, +_CRTIMP2 int __cdecl __crtLCMapStringW(_In_opt_z_ LPCWSTR _LocaleName, _In_ DWORD _DWMapFlag, + _In_reads_(_CchSrc) LPCWSTR _LpSrcStr, _In_ int _CchSrc, _Out_writes_opt_(_CchDest) wchar_t* _LpDestStr, _In_ int _CchDest); _CRT_END_C_HEADER diff --git a/stl/src/excptptr.cpp b/stl/src/excptptr.cpp index 517c63c65b0..6b5879e328b 100644 --- a/stl/src/excptptr.cpp +++ b/stl/src/excptptr.cpp @@ -108,7 +108,8 @@ namespace { #if _EH_RELATIVE_TYPEINFO void* _ThrowImageBase = - RtlPcToFileHeader(const_cast(static_cast(_PThrow)), &_ThrowImageBase); + _PThrow ? RtlPcToFileHeader(const_cast(static_cast(_PThrow)), &_ThrowImageBase) + : nullptr; _Record.ExceptionInformation[3] = reinterpret_cast(_ThrowImageBase); // params.pThrowImageBase #endif // _EH_RELATIVE_TYPEINFO @@ -340,7 +341,8 @@ namespace { const auto _ExceptionObjectSize = static_cast(_PType->sizeOrOffset); const auto _AllocSize = sizeof(_ExceptionPtr_normal) + _ExceptionObjectSize; - auto _RxRaw = malloc(_AllocSize); + _Analysis_assume_(_AllocSize >= sizeof(_ExceptionPtr_normal)); + auto _RxRaw = malloc(_AllocSize); if (!_RxRaw) { _Dest = _ExceptionPtr_static::_Get(); return; @@ -422,33 +424,34 @@ namespace { } } // unnamed namespace -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(void* _Ptr) noexcept { +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void* _Ptr) noexcept { ::new (_Ptr) shared_ptr(); } -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(void* _Ptr) noexcept { +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void* _Ptr) noexcept { static_cast*>(_Ptr)->~shared_ptr(); } -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(void* _Dest, const void* _Src) noexcept { +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void* _Dest, _In_ const void* _Src) noexcept { ::new (_Dest) shared_ptr(*static_cast*>(_Src)); } -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrAssign(void* _Dest, const void* _Src) noexcept { +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrAssign(_Inout_ void* _Dest, _In_ const void* _Src) noexcept { *static_cast*>(_Dest) = *static_cast*>(_Src); } -_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrCompare(const void* _Lhs, const void* _Rhs) noexcept { +_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrCompare( + _In_ const void* _Lhs, _In_ const void* _Rhs) noexcept { return *static_cast*>(_Lhs) == *static_cast*>(_Rhs); } -_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrToBool(const void* _Ptr) noexcept { +_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrToBool(_In_ const void* _Ptr) noexcept { return static_cast(*static_cast*>(_Ptr)); } -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(void* _Lhs, void* _Rhs) noexcept { +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void* _Lhs, _Inout_ void* _Rhs) noexcept { static_cast*>(_Lhs)->swap( *static_cast*>(_Rhs)); } @@ -470,7 +473,7 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void* } } -[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrRethrow(const void* _PtrRaw) { +[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrRethrow(_In_ const void* _PtrRaw) { const shared_ptr* _Ptr = static_cast*>(_PtrRaw); // throwing a bad_exception if they give us a nullptr exception_ptr if (!*_Ptr) { @@ -512,6 +515,8 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void* // Alloc memory on stack for exception object. This might cause a stack overflow SEH exception, or another C++ // exception when copying the C++ exception object. In that case, we just let that become the thrown exception. + +#pragma warning(suppress : 6255) // _alloca indicates failure by raising a stack overflow exception void* _PExceptionBuffer = alloca(_PType->sizeOrOffset); _CopyExceptionObject(_PExceptionBuffer, _CppRecord.params.pExceptionObject, _PType #if _EH_RELATIVE_TYPEINFO @@ -531,7 +536,7 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void* } _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopyException( - void* _Ptr, const void* _PExceptRaw, const void* _PThrowRaw) noexcept { + _Inout_ void* _Ptr, _In_ const void* _PExceptRaw, _In_ const void* _PThrowRaw) noexcept { _EXCEPTION_RECORD _Record; _PopulateCppExceptionRecord(_Record, _PExceptRaw, static_cast(_PThrowRaw)); _Assign_cpp_exception_ptr_from_record( diff --git a/stl/src/filesystem.cpp b/stl/src/filesystem.cpp index 063f5f9c7a6..c5f3232e377 100644 --- a/stl/src/filesystem.cpp +++ b/stl/src/filesystem.cpp @@ -260,15 +260,15 @@ namespace { _EXTERN_C -[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_full_path_name( - const wchar_t* _Source, unsigned long _Target_size, wchar_t* _Target) noexcept { // calls GetFullPathNameW +[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_full_path_name(_In_z_ const wchar_t* _Source, + _In_ unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* _Target) noexcept { // calls GetFullPathNameW const auto _Result = GetFullPathNameW(_Source, _Target_size, _Target, nullptr); return {_Result, _Result == 0 ? __std_win_error{GetLastError()} : __std_win_error::_Success}; } -[[nodiscard]] __std_win_error __stdcall __std_fs_open_handle(__std_fs_file_handle* const _Handle, - const wchar_t* const _File_name, const __std_access_rights _Desired_access, - const __std_fs_file_flags _Flags) noexcept { // calls CreateFile2 or CreateFileW +[[nodiscard]] __std_win_error __stdcall __std_fs_open_handle(_Out_ __std_fs_file_handle* const _Handle, + _In_z_ const wchar_t* const _File_name, _In_ const __std_access_rights _Desired_access, + _In_ const __std_fs_file_flags _Flags) noexcept { // calls CreateFile2 or CreateFileW const HANDLE _Result = __vcp_CreateFile(_File_name, static_cast(_Desired_access), FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, static_cast(_Flags), 0); @@ -282,9 +282,10 @@ void __stdcall __std_fs_close_handle(const __std_fs_file_handle _Handle) noexcep } } -[[nodiscard]] __std_win_error __stdcall __std_fs_get_file_attributes_by_handle(const __std_fs_file_handle _Handle, - unsigned long* const - _File_attributes) noexcept { // read the attributes from _Handle and store it in _File_attributes +[[nodiscard]] _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_file_attributes_by_handle( + _In_ const __std_fs_file_handle _Handle, _Out_ unsigned long* const _File_attributes) noexcept { + // read the attributes from _Handle and store it in _File_attributes __std_win_error _Last_error; const HANDLE _As_plain_handle = reinterpret_cast(_Handle); @@ -311,9 +312,10 @@ void __stdcall __std_fs_close_handle(const __std_fs_file_handle _Handle) noexcep return _Last_error; } -[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_final_path_name_by_handle(const __std_fs_file_handle _Handle, - wchar_t* const _Target, const unsigned long _Target_size, - const __std_fs_volume_name_kind _Flags) noexcept { // calls GetFinalPathNameByHandleW +[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_final_path_name_by_handle( + _In_ const __std_fs_file_handle _Handle, _Out_writes_z_(_Target_size) wchar_t* const _Target, + _In_ const unsigned long _Target_size, + _In_ const __std_fs_volume_name_kind _Flags) noexcept { // calls GetFinalPathNameByHandleW const auto _Result = __vcrt_GetFinalPathNameByHandleW( reinterpret_cast(_Handle), _Target, _Target_size, static_cast(_Flags)); return {_Result, _Result == 0 ? __std_win_error{GetLastError()} : __std_win_error::_Success}; @@ -322,8 +324,8 @@ void __stdcall __std_fs_close_handle(const __std_fs_file_handle _Handle) noexcep static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(__std_fs_find_data)); static_assert(alignof(WIN32_FIND_DATAW) == alignof(__std_fs_find_data)); -[[nodiscard]] __std_win_error __stdcall __std_fs_directory_iterator_open( - const wchar_t* const _Path_spec, __std_fs_dir_handle* const _Handle, __std_fs_find_data* const _Results) noexcept { +[[nodiscard]] __std_win_error __stdcall __std_fs_directory_iterator_open(_In_z_ const wchar_t* const _Path_spec, + _Inout_ __std_fs_dir_handle* const _Handle, _Out_ __std_fs_find_data* const _Results) noexcept { __std_fs_directory_iterator_close(*_Handle); *_Handle = __std_fs_dir_handle{reinterpret_cast( FindFirstFileExW(_Path_spec, FindExInfoBasic, _Results, FindExSearchNameMatch, nullptr, 0))}; @@ -349,14 +351,14 @@ static_assert(alignof(WIN32_FIND_DATAW) == alignof(__std_fs_find_data)); return __std_win_error{GetLastError()}; } -void __stdcall __std_fs_directory_iterator_close(const __std_fs_dir_handle _Handle) noexcept { +void __stdcall __std_fs_directory_iterator_close(_In_ const __std_fs_dir_handle _Handle) noexcept { if (_Handle != __std_fs_dir_handle::_Invalid && !FindClose(reinterpret_cast(_Handle))) { terminate(); } } [[nodiscard]] __std_win_error __stdcall __std_fs_directory_iterator_advance( - const __std_fs_dir_handle _Handle, __std_fs_find_data* const _Results) noexcept { + _In_ const __std_fs_dir_handle _Handle, _Out_ __std_fs_find_data* const _Results) noexcept { if (FindNextFileW(reinterpret_cast(_Handle), reinterpret_cast(_Results))) { return __std_win_error::_Success; } @@ -378,15 +380,17 @@ void __stdcall __std_fs_directory_iterator_close(const __std_fs_dir_handle _Hand return __std_code_page{CP_ACP}; } -[[nodiscard]] __std_fs_convert_result __stdcall __std_fs_convert_narrow_to_wide(const __std_code_page _Code_page, - const char* const _Input_str, const int _Input_len, wchar_t* const _Output_str, const int _Output_len) noexcept { +[[nodiscard]] __std_fs_convert_result __stdcall __std_fs_convert_narrow_to_wide(_In_ const __std_code_page _Code_page, + _In_reads_(_Input_len) const char* const _Input_str, _In_ const int _Input_len, + _Out_writes_opt_(_Output_len) wchar_t* const _Output_str, _In_ const int _Output_len) noexcept { const int _Len = MultiByteToWideChar( static_cast(_Code_page), MB_ERR_INVALID_CHARS, _Input_str, _Input_len, _Output_str, _Output_len); return {_Len, _Len == 0 ? __std_win_error{GetLastError()} : __std_win_error::_Success}; } -[[nodiscard]] __std_fs_convert_result __stdcall __std_fs_convert_wide_to_narrow(const __std_code_page _Code_page, - const wchar_t* const _Input_str, const int _Input_len, char* const _Output_str, const int _Output_len) noexcept { +[[nodiscard]] __std_fs_convert_result __stdcall __std_fs_convert_wide_to_narrow(_In_ const __std_code_page _Code_page, + _In_reads_(_Input_len) const wchar_t* const _Input_str, _In_ const int _Input_len, + _Out_writes_opt_(_Output_len) char* const _Output_str, _In_ const int _Output_len) noexcept { __std_fs_convert_result _Result; if (_Code_page == __std_code_page{CP_UTF8} || _Code_page == __std_code_page{54936}) { @@ -421,8 +425,9 @@ void __stdcall __std_fs_directory_iterator_close(const __std_fs_dir_handle _Hand } [[nodiscard]] __std_fs_convert_result __stdcall __std_fs_convert_wide_to_narrow_replace_chars( - const __std_code_page _Code_page, const wchar_t* const _Input_str, const int _Input_len, char* const _Output_str, - const int _Output_len) noexcept { + _In_ const __std_code_page _Code_page, _In_reads_(_Input_len) const wchar_t* const _Input_str, + _In_ const int _Input_len, _Out_writes_opt_(_Output_len) char* const _Output_str, + _In_ const int _Output_len) noexcept { __std_fs_convert_result _Result; _Result._Len = WideCharToMultiByte(static_cast(_Code_page), WC_NO_BEST_FIT_CHARS, _Input_str, @@ -441,8 +446,8 @@ void __stdcall __std_fs_directory_iterator_close(const __std_fs_dir_handle _Hand return _Result; } -[[nodiscard]] __std_fs_copy_file_result __stdcall __std_fs_copy_file(const wchar_t* const _Source, - const wchar_t* const _Target, __std_fs_copy_options _Options) noexcept { // copy _Source to _Target +[[nodiscard]] __std_fs_copy_file_result __stdcall __std_fs_copy_file(_In_z_ const wchar_t* const _Source, + _In_z_ const wchar_t* const _Target, _In_ __std_fs_copy_options _Options) noexcept { // copy _Source to _Target _Options &= __std_fs_copy_options::_Existing_mask; if (_Options != __std_fs_copy_options::_Overwrite_existing) { const __std_fs_copy_file_result _First_try_result = @@ -506,7 +511,8 @@ void __stdcall __std_fs_directory_iterator_close(const __std_fs_dir_handle _Hand return __vcp_Copyfile(_Source, _Target, /* _Fail_if_exists = */ false); } -__std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, const wchar_t* const _Path) noexcept { +_Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_file_id(_Out_ __std_fs_file_id* const _Id, _In_z_ const wchar_t* const _Path) noexcept { __std_win_error _Last_error; const _STD _Fs_file _Handle( _Path, __std_access_rights::_File_read_attributes, __std_fs_file_flags::_Backup_semantics, &_Last_error); @@ -518,7 +524,8 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons static_assert(alignof(FILE_ID_INFO) == alignof(__std_fs_file_id)); if (__vcrt_GetFileInformationByHandleEx( _Handle._Get(), FileIdInfo, reinterpret_cast(_Id), sizeof(*_Id)) - != 0) { // if we could get FILE_ID_INFO, use that as the source of truth + != 0) { + // if we could get FILE_ID_INFO, use that as the source of truth return __std_win_error::_Success; } @@ -548,12 +555,12 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_create_directory_symbolic_link( - const wchar_t* const _Symlink_file_name, const wchar_t* const _Target_file_name) noexcept { + _In_z_ const wchar_t* const _Symlink_file_name, _In_z_ const wchar_t* const _Target_file_name) noexcept { return _Create_symlink(_Symlink_file_name, _Target_file_name, SYMBOLIC_LINK_FLAG_DIRECTORY); } [[nodiscard]] __std_win_error __stdcall __std_fs_create_hard_link( - const wchar_t* const _File_name, const wchar_t* const _Existing_file_name) noexcept { + _In_z_ const wchar_t* const _File_name, _In_z_ const wchar_t* const _Existing_file_name) noexcept { #if defined(_CRT_APP) (void) _File_name; (void) _Existing_file_name; @@ -568,12 +575,12 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_create_symbolic_link( - const wchar_t* const _Symlink_file_name, const wchar_t* const _Target_file_name) noexcept { + _In_z_ const wchar_t* const _Symlink_file_name, _In_z_ const wchar_t* const _Target_file_name) noexcept { return _Create_symlink(_Symlink_file_name, _Target_file_name, 0); } -[[nodiscard]] __std_win_error __stdcall __std_fs_read_reparse_data_buffer( - const __std_fs_file_handle _Handle, void* const _Buffer, const unsigned long _Buffer_size) noexcept { +[[nodiscard]] __std_win_error __stdcall __std_fs_read_reparse_data_buffer(_In_ const __std_fs_file_handle _Handle, + _Out_writes_bytes_(_Buffer_size) void* const _Buffer, _In_ const unsigned long _Buffer_size) noexcept { unsigned long _Bytes_returned; // If DeviceIoControl fails, it returns 0 and _Bytes_returned is 0. if (0 @@ -585,8 +592,9 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons return __std_win_error::_Success; } -[[nodiscard]] __std_win_error __stdcall __std_fs_read_name_from_reparse_data_buffer( - __std_fs_reparse_data_buffer* const _Buffer, wchar_t** const _Offset, unsigned short* const _Length) noexcept { +[[nodiscard]] _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_read_name_from_reparse_data_buffer(_In_ __std_fs_reparse_data_buffer* const _Buffer, + _Out_ wchar_t** const _Offset, _Out_ unsigned short* const _Length) noexcept { if (_Buffer->_Reparse_tag == IO_REPARSE_TAG_SYMLINK) { auto& _Symlink_buffer = _Buffer->_Symbolic_link_reparse_buffer; const unsigned short _Temp_length = _Symlink_buffer._Print_name_length / sizeof(wchar_t); @@ -606,7 +614,7 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_set_last_write_time( - const long long _Last_write_filetime, const wchar_t* const _Path) noexcept { + _In_ const long long _Last_write_filetime, _In_z_ const wchar_t* const _Path) noexcept { __std_win_error _Last_error; const _STD _Fs_file _Handle( _Path, __std_access_rights::_File_write_attributes, __std_fs_file_flags::_Backup_semantics, &_Last_error); @@ -621,7 +629,7 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons return __std_win_error{GetLastError()}; } -[[nodiscard]] __std_fs_remove_result __stdcall __std_fs_remove(const wchar_t* const _Target) noexcept { +[[nodiscard]] __std_fs_remove_result __stdcall __std_fs_remove(_In_z_ const wchar_t* const _Target) noexcept { // remove _Target without caring whether _Target is a file or directory __std_win_error _Last_error; #if _STL_ALWAYS_HAS_SetFileInformationByHandle @@ -695,7 +703,7 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_change_permissions( - const wchar_t* const _Path, const bool _Follow_symlinks, const bool _Readonly) noexcept { + _In_z_ const wchar_t* const _Path, _In_ const bool _Follow_symlinks, _In_ const bool _Readonly) noexcept { const DWORD _Old_attributes = GetFileAttributesW(_Path); if (_Old_attributes == INVALID_FILE_ATTRIBUTES) { return __std_win_error{GetLastError()}; @@ -741,7 +749,7 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_rename( - const wchar_t* const _Source, const wchar_t* const _Target) noexcept { + _In_z_ const wchar_t* const _Source, _In_z_ const wchar_t* const _Target) noexcept { if (MoveFileExW(_Source, _Target, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) { return __std_win_error::_Success; } @@ -750,7 +758,7 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons } [[nodiscard]] __std_win_error __stdcall __std_fs_resize_file( - const wchar_t* const _Target, const uintmax_t _New_size) noexcept { + _In_z_ const wchar_t* const _Target, const uintmax_t _New_size) noexcept { __std_win_error _Err; const _STD _Fs_file _Handle(_Target, __std_access_rights::_File_generic_write, __std_fs_file_flags::_None, &_Err); if (_Err != __std_win_error::_Success) { @@ -766,8 +774,9 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons return __std_win_error::_Success; } -[[nodiscard]] __std_win_error __stdcall __std_fs_space(const wchar_t* const _Target, uintmax_t* const _Available, - uintmax_t* const _Total_bytes, uintmax_t* const _Free_bytes) noexcept { +[[nodiscard]] __std_win_error __stdcall __std_fs_space(_In_z_ const wchar_t* const _Target, + _Out_ uintmax_t* const _Available, _Out_ uintmax_t* const _Total_bytes, + _Out_ uintmax_t* const _Free_bytes) noexcept { // get capacity information for the volume on which the file _Target resides static_assert(sizeof(uintmax_t) == sizeof(ULARGE_INTEGER) && alignof(uintmax_t) == alignof(ULARGE_INTEGER), "Size and alignment must match for reinterpret_cast"); @@ -843,7 +852,8 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons return __std_win_error{GetLastError()}; } -[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_temp_path(wchar_t* const _Target) noexcept { +[[nodiscard]] _Success_(return._Error == __std_win_error::_Success) __std_ulong_and_error + __stdcall __std_fs_get_temp_path(_Out_writes_z_(__std_fs_temp_path_max) wchar_t* const _Target) noexcept { // calls GetTempPathW // If getting the path failed, returns 0 size; otherwise, returns the size of the // expected directory. If the path could be resolved to an existing directory, @@ -901,8 +911,9 @@ struct alignas(long long) _Aligned_file_attrs { } }; -[[nodiscard]] __std_win_error __stdcall __std_fs_get_stats(const wchar_t* const _Path, __std_fs_stats* const _Stats, - __std_fs_stats_flags _Flags, const __std_fs_file_attr _Symlink_attribute_hint) noexcept { +[[nodiscard]] _Success_(return == __std_win_error::_Success) __std_win_error + __stdcall __std_fs_get_stats(_In_z_ const wchar_t* const _Path, __std_fs_stats* const _Stats, + _In_ __std_fs_stats_flags _Flags, _In_ const __std_fs_file_attr _Symlink_attribute_hint) noexcept { static_assert((offsetof(_Aligned_file_attrs, _Data._Last_write_time) % 8) == 0, "_Last_write_time not aligned"); static_assert(sizeof(_File_attr_data) == sizeof(WIN32_FILE_ATTRIBUTE_DATA)); static_assert(alignof(_File_attr_data) == alignof(WIN32_FILE_ATTRIBUTE_DATA)); @@ -1054,7 +1065,7 @@ struct alignas(long long) _Aligned_file_attrs { } [[nodiscard]] __std_fs_create_directory_result __stdcall __std_fs_create_directory( - const wchar_t* const _New_directory) noexcept { + _In_z_ const wchar_t* const _New_directory) noexcept { if (CreateDirectoryW(_New_directory, nullptr)) { return {true, __std_win_error::_Success}; } @@ -1075,7 +1086,7 @@ struct alignas(long long) _Aligned_file_attrs { // TRANSITION, ABI: __std_fs_create_directory_template() is preserved for binary compatibility [[nodiscard]] __std_fs_create_directory_result __stdcall __std_fs_create_directory_template( - const wchar_t* const _Template_directory, const wchar_t* const _New_directory) noexcept { + _In_z_ const wchar_t* const _Template_directory, _In_z_ const wchar_t* const _New_directory) noexcept { #if defined(_CRT_APP) (void) _Template_directory; return __std_fs_create_directory(_New_directory); @@ -1093,8 +1104,9 @@ struct alignas(long long) _Aligned_file_attrs { #endif // defined(_CRT_APP) } -[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_current_path( - const unsigned long _Target_size, wchar_t* const _Target) noexcept { +[[nodiscard]] _Success_(return._Error == __std_win_error::_Success) __std_ulong_and_error + __stdcall __std_fs_get_current_path( + _In_ const unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* const _Target) noexcept { // If getting the path failed, GetCurrentDirectoryW returns 0; otherwise, returns the size of the expected // directory. const auto _Size = GetCurrentDirectoryW(_Target_size, _Target); @@ -1105,7 +1117,7 @@ struct alignas(long long) _Aligned_file_attrs { return {_Size, __std_win_error::_Success}; } -[[nodiscard]] __std_win_error __stdcall __std_fs_set_current_path(const wchar_t* const _Target) noexcept { +[[nodiscard]] __std_win_error __stdcall __std_fs_set_current_path(_In_z_ const wchar_t* const _Target) noexcept { // If setting the path failed, SetCurrentDirectoryW returns 0; otherwise returns non-zero. const auto _Succeeded = SetCurrentDirectoryW(_Target); if (_Succeeded == 0) { diff --git a/stl/src/locale.cpp b/stl/src/locale.cpp index 75e6250b402..f2969d61d01 100644 --- a/stl/src/locale.cpp +++ b/stl/src/locale.cpp @@ -128,6 +128,7 @@ void __CLRCALL_PURE_OR_CDECL locale::_Locimp::_Locimp_Addfac( } } ptrfac->_Incref(); +#pragma warning(suppress : 6001) // PREfast isn't following through _realloc_crt here if (_This->_Facetvec[id] != nullptr) { delete _This->_Facetvec[id]->_Decref(); } diff --git a/stl/src/multprec.cpp b/stl/src/multprec.cpp index e81d0156c18..0fb8c9d7c25 100644 --- a/stl/src/multprec.cpp +++ b/stl/src/multprec.cpp @@ -112,7 +112,12 @@ void __CLRCALL_PURE_OR_CDECL _MP_Rem( v[0] = v0 & mask; v[1] = v0 >> shift; const int n = limit(v, 2); + _Analysis_assume_(n > 0); + _Analysis_assume_(n <= 2); const int m = limit(u, _MP_len) - n; + _Analysis_assume_(m > 0); + _Analysis_assume_(m <= _MP_len - n); + // Knuth, vol. 2, p. 272, Algorithm D // D1: [Normalize.] @@ -130,6 +135,7 @@ void __CLRCALL_PURE_OR_CDECL _MP_Rem( unsigned long long rh = ((u[j + n] << shift) + u[j + n - 1]) % v[n - 1]; for (;;) { +#pragma warning(suppress : 6385) // TRANSITION, GH-1008 if (qh < maxVal && qh * v[n - 2] <= (rh << shift) + u[j + n - 2]) { break; } else { // reduce tentative value and retry diff --git a/stl/src/primitives.hpp b/stl/src/primitives.hpp index 85eabcfb821..2f335143af1 100644 --- a/stl/src/primitives.hpp +++ b/stl/src/primitives.hpp @@ -16,8 +16,11 @@ #include "awint.hpp" #ifdef _STL_CONCRT_SUPPORT +#pragma warning(push) +#pragma warning(disable : 6297 6385 6386 6504 28204) #include #include +#pragma warning(pop) #endif enum class __stl_sync_api_modes_enum { normal, win7, vista, concrt }; diff --git a/stl/src/special_math.cpp b/stl/src/special_math.cpp index 105b54b268a..e824c10b2e1 100644 --- a/stl/src/special_math.cpp +++ b/stl/src/special_math.cpp @@ -12,6 +12,7 @@ #pragma warning(disable : 4643) // Forward declaring '%s' in namespace std is not permitted by the C++ Standard #pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 5219) // implicit conversion from '%s' to '%s', possible loss of data +#pragma warning(disable : 6326) // potential comparison of a constant with another constant #define BOOST_CHRONO_HEADER_ONLY #define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE @@ -472,9 +473,9 @@ namespace { _Dy = _STD abs(_Dy); _Dz = _STD abs(_Dz); - constexpr _Ty _Inf = _STD numeric_limits<_Ty>::infinity(); - if (_Dx == _Inf || _Dy == _Inf || _Dz == _Inf) { - return _Inf; + constexpr _Ty _Infinity = _STD numeric_limits<_Ty>::infinity(); + if (_Dx == _Infinity || _Dy == _Infinity || _Dz == _Infinity) { + return _Infinity; } if (_Dy > _Dx) { diff --git a/stl/src/stdhndlr.cpp b/stl/src/stdhndlr.cpp index 3c0b777eba2..af55e61873e 100644 --- a/stl/src/stdhndlr.cpp +++ b/stl/src/stdhndlr.cpp @@ -17,7 +17,7 @@ int __cdecl _New_handler_interface(size_t) { // interface to existing Microsoft return 1; } -_CRTIMP2 new_handler __cdecl set_new_handler(new_handler pnew) noexcept { // remove current handler +_CRTIMP2 new_handler __cdecl set_new_handler(_In_opt_ new_handler pnew) noexcept { // remove current handler _BEGIN_LOCK(_LOCK_MALLOC) // lock thread to ensure atomicity new_handler pold = _New_handler; _New_handler = pnew; diff --git a/stl/src/winapinls.cpp b/stl/src/winapinls.cpp index 55badb6a18b..a7a47a51348 100644 --- a/stl/src/winapinls.cpp +++ b/stl/src/winapinls.cpp @@ -622,8 +622,9 @@ extern "C" int __cdecl __crtDownlevelLCIDToLocaleName(LCID lcid, LPWSTR outLocal } // __crtCompareStringEx() - Wrapper for CompareStringEx(). -extern "C" int __cdecl __crtCompareStringEx( - LPCWSTR lpLocaleName, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2) { +extern "C" int __cdecl __crtCompareStringEx(_In_opt_ LPCWSTR lpLocaleName, _In_ DWORD dwCmpFlags, + _In_NLS_string_(cchCount1) LPCWSTR lpString1, _In_ int cchCount1, _In_NLS_string_(cchCount2) LPCWSTR lpString2, + _In_ int cchCount2) { // use CompareStringEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCOMPARESTRINGEX, CompareStringEx, pfCompareStringEx) { return pfCompareStringEx( @@ -636,8 +637,9 @@ extern "C" int __cdecl __crtCompareStringEx( } // __crtLCMapStringEx() - Wrapper for LCMapStringEx(). -extern "C" int __cdecl __crtLCMapStringEx( - LPCWSTR lpLocaleName, DWORD dwMapFlags, LPCWSTR lpSrcStr, int cchSrc, LPWSTR lpDestStr, int cchDest) { +extern "C" int __cdecl __crtLCMapStringEx(_In_opt_ LPCWSTR lpLocaleName, _In_ DWORD dwMapFlags, + _In_reads_(cchSrc) LPCWSTR lpSrcStr, _In_ int cchSrc, _Out_writes_opt_(cchDest) LPWSTR lpDestStr, + _In_ int cchDest) { // use LCMapStringEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNLCMAPSTRINGEX, LCMapStringEx, pfLCMapStringEx) { return pfLCMapStringEx(lpLocaleName, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest, nullptr, nullptr, 0); @@ -649,8 +651,8 @@ extern "C" int __cdecl __crtLCMapStringEx( // __crtGetLocaleInfoEx() - Wrapper for GetLocaleInfoEx(). -extern "C" int __cdecl __crtGetLocaleInfoEx( - LPCWSTR const lpLocaleName, LCTYPE const LCType, LPWSTR const lpLCData, int const cchData) { +extern "C" int __cdecl __crtGetLocaleInfoEx(_In_opt_ LPCWSTR const lpLocaleName, _In_ LCTYPE const LCType, + _Out_writes_opt_(cchData) LPWSTR const lpLCData, _In_ int const cchData) { IFDYNAMICGETCACHEDFUNCTION(PFNGETLOCALEINFOEX, GetLocaleInfoEx, pfGetLocaleInfoEx) { return pfGetLocaleInfoEx(lpLocaleName, LCType, lpLCData, cchData); } diff --git a/stl/src/winapisupp.cpp b/stl/src/winapisupp.cpp index 202995a9e1f..9e51805873c 100644 --- a/stl/src/winapisupp.cpp +++ b/stl/src/winapisupp.cpp @@ -131,7 +131,7 @@ extern "C" BOOL __cdecl __crtIsPackagedApp() { #if _STL_WIN32_WINNT < _WIN32_WINNT_WS03 -extern "C" DWORD __cdecl __crtFlsAlloc(PFLS_CALLBACK_FUNCTION const lpCallback) { +extern "C" DWORD __cdecl __crtFlsAlloc(_In_opt_ PFLS_CALLBACK_FUNCTION const lpCallback) { // use FlsAlloc if it is available (only on Windows Server 2003+)... IFDYNAMICGETCACHEDFUNCTION(PFNFLSALLOC, FlsAlloc, pfFlsAlloc) { return pfFlsAlloc(lpCallback); @@ -141,7 +141,7 @@ extern "C" DWORD __cdecl __crtFlsAlloc(PFLS_CALLBACK_FUNCTION const lpCallback) return TlsAlloc(); } -extern "C" BOOL __cdecl __crtFlsFree(DWORD const dwFlsIndex) { +extern "C" BOOL __cdecl __crtFlsFree(_In_ DWORD const dwFlsIndex) { // use FlsFree if it is available (only on Windows Server 2003+)... IFDYNAMICGETCACHEDFUNCTION(PFNFLSFREE, FlsFree, pfFlsFree) { return pfFlsFree(dwFlsIndex); @@ -151,7 +151,7 @@ extern "C" BOOL __cdecl __crtFlsFree(DWORD const dwFlsIndex) { return TlsFree(dwFlsIndex); } -extern "C" PVOID __cdecl __crtFlsGetValue(DWORD const dwFlsIndex) { +extern "C" PVOID __cdecl __crtFlsGetValue(_In_ DWORD const dwFlsIndex) { // use FlsGetValue if it is available (only on Windows Server 2003+)... IFDYNAMICGETCACHEDFUNCTION(PFNFLSGETVALUE, FlsGetValue, pfFlsGetValue) { return pfFlsGetValue(dwFlsIndex); @@ -161,7 +161,7 @@ extern "C" PVOID __cdecl __crtFlsGetValue(DWORD const dwFlsIndex) { return TlsGetValue(dwFlsIndex); } -extern "C" BOOL __cdecl __crtFlsSetValue(DWORD const dwFlsIndex, PVOID const lpFlsData) { +extern "C" BOOL __cdecl __crtFlsSetValue(_In_ DWORD const dwFlsIndex, _In_opt_ PVOID const lpFlsData) { // use FlsSetValue if it is available (only on Windows Server 2003+)... IFDYNAMICGETCACHEDFUNCTION(PFNFLSSETVALUE, FlsSetValue, pfFlsSetValue) { return pfFlsSetValue(dwFlsIndex, lpFlsData); @@ -183,11 +183,12 @@ extern "C" ULONGLONG __cdecl __crtGetTickCount64() { } // ...otherwise fall back to using GetTickCount. +#pragma warning(suppress : 28159) // Consider using 'GetTickCount64' instead of 'GetTickCount'. return GetTickCount(); } extern "C" BOOL __cdecl __crtInitializeCriticalSectionEx( - LPCRITICAL_SECTION const lpCriticalSection, DWORD const dwSpinCount, DWORD const Flags) { + _Out_ LPCRITICAL_SECTION const lpCriticalSection, _In_ DWORD const dwSpinCount, _In_ DWORD const Flags) { // use InitializeCriticalSectionEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION( PFNINITIALIZECRITICALSECTIONEX, InitializeCriticalSectionEx, pfInitializeCriticalSectionEx) { @@ -195,12 +196,11 @@ extern "C" BOOL __cdecl __crtInitializeCriticalSectionEx( } // ...otherwise fall back to using InitializeCriticalSectionAndSpinCount. - InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount); - return TRUE; + return InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount); } -extern "C" BOOL __cdecl __crtInitOnceExecuteOnce( - PINIT_ONCE const InitOnce, PINIT_ONCE_FN const InitFn, PVOID const Parameter, LPVOID* const Context) { +extern "C" BOOL __cdecl __crtInitOnceExecuteOnce(_Inout_ PINIT_ONCE const InitOnce, _In_ PINIT_ONCE_FN const InitFn, + _Inout_opt_ PVOID const Parameter, LPVOID* const Context) { // use InitOnceExecuteOnce if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNINITONCEEXECUTEONCE, InitOnceExecuteOnce, pfInitOnceExecuteOnce) { return pfInitOnceExecuteOnce(InitOnce, InitFn, Parameter, Context); @@ -242,8 +242,8 @@ extern "C" BOOL __cdecl __crtInitOnceExecuteOnce( } } -extern "C" HANDLE __cdecl __crtCreateEventExW(LPSECURITY_ATTRIBUTES const lpEventAttributes, LPCWSTR const lpName, - DWORD const dwFlags, DWORD const dwDesiredAccess) { +extern "C" HANDLE __cdecl __crtCreateEventExW(_In_opt_ LPSECURITY_ATTRIBUTES const lpEventAttributes, + _In_opt_ LPCWSTR const lpName, _In_ DWORD const dwFlags, _In_ DWORD const dwDesiredAccess) { // use CreateEventEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCREATEEVENTEXW, CreateEventExW, pfCreateEventExW) { return pfCreateEventExW(lpEventAttributes, lpName, dwFlags, dwDesiredAccess); @@ -254,9 +254,9 @@ extern "C" HANDLE __cdecl __crtCreateEventExW(LPSECURITY_ATTRIBUTES const lpEven lpEventAttributes, dwFlags & CREATE_EVENT_MANUAL_RESET, dwFlags & CREATE_EVENT_INITIAL_SET, lpName); } -extern "C" HANDLE __cdecl __crtCreateSemaphoreExW(LPSECURITY_ATTRIBUTES const lpSemaphoreAttributes, - LONG const lInitialCount, LONG const lMaximumCount, LPCWSTR const lpName, DWORD const dwFlags, - DWORD const dwDesiredAccess) { +extern "C" HANDLE __cdecl __crtCreateSemaphoreExW(_In_opt_ LPSECURITY_ATTRIBUTES const lpSemaphoreAttributes, + _In_ LONG const lInitialCount, _In_ LONG const lMaximumCount, _In_opt_ LPCWSTR const lpName, + _Reserved_ DWORD const dwFlags, _In_ DWORD const dwDesiredAccess) { // use CreateSemaphoreEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCREATESEMAPHOREEXW, CreateSemaphoreExW, pfCreateSemaphoreExW) { return pfCreateSemaphoreExW( @@ -273,7 +273,7 @@ extern "C" HANDLE __cdecl __crtCreateSemaphoreExW(LPSECURITY_ATTRIBUTES const lp } extern "C" PTP_TIMER __cdecl __crtCreateThreadpoolTimer( - PTP_TIMER_CALLBACK const pfnti, PVOID const pv, PTP_CALLBACK_ENVIRON const pcbe) { + _In_ PTP_TIMER_CALLBACK const pfnti, _Inout_opt_ PVOID const pv, _In_opt_ PTP_CALLBACK_ENVIRON const pcbe) { // use CreateThreadpoolTimer if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCREATETHREADPOOLTIMER, CreateThreadpoolTimer, pfCreateThreadpoolTimer) { return pfCreateThreadpoolTimer(pfnti, pv, pcbe); @@ -283,8 +283,8 @@ extern "C" PTP_TIMER __cdecl __crtCreateThreadpoolTimer( return nullptr; } -extern "C" VOID __cdecl __crtSetThreadpoolTimer( - PTP_TIMER const pti, PFILETIME const pftDueTime, DWORD const msPeriod, DWORD const msWindowLength) { +extern "C" VOID __cdecl __crtSetThreadpoolTimer(_Inout_ PTP_TIMER const pti, _In_opt_ PFILETIME const pftDueTime, + _In_ DWORD const msPeriod, _In_opt_ DWORD const msWindowLength) { // use SetThreadpoolTimer if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNSETTHREADPOOLTIMER, SetThreadpoolTimer, pfSetThreadpoolTimer) { pfSetThreadpoolTimer(pti, pftDueTime, msPeriod, msWindowLength); @@ -294,7 +294,8 @@ extern "C" VOID __cdecl __crtSetThreadpoolTimer( return; } -extern "C" VOID __cdecl __crtWaitForThreadpoolTimerCallbacks(PTP_TIMER const pti, BOOL const fCancelPendingCallbacks) { +extern "C" VOID __cdecl __crtWaitForThreadpoolTimerCallbacks( + _Inout_ PTP_TIMER const pti, _In_ BOOL const fCancelPendingCallbacks) { // use WaitForThreadpoolTimerCallbacks if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION( PFNWAITFORTHREADPOOLTIMERCALLBACKS, WaitForThreadpoolTimerCallbacks, pfWaitForThreadpoolTimerCallbacks) { @@ -305,7 +306,7 @@ extern "C" VOID __cdecl __crtWaitForThreadpoolTimerCallbacks(PTP_TIMER const pti return; } -extern "C" VOID __cdecl __crtCloseThreadpoolTimer(PTP_TIMER const pti) { +extern "C" VOID __cdecl __crtCloseThreadpoolTimer(_Inout_ PTP_TIMER const pti) { // use CloseThreadpoolTimer if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCLOSETHREADPOOLTIMER, CloseThreadpoolTimer, pfCloseThreadpoolTimer) { pfCloseThreadpoolTimer(pti); @@ -316,7 +317,7 @@ extern "C" VOID __cdecl __crtCloseThreadpoolTimer(PTP_TIMER const pti) { } extern "C" PTP_WAIT __cdecl __crtCreateThreadpoolWait( - PTP_WAIT_CALLBACK const pfnwa, PVOID const pv, PTP_CALLBACK_ENVIRON const pcbe) { + _In_ PTP_WAIT_CALLBACK const pfnwa, _Inout_opt_ PVOID const pv, _In_opt_ PTP_CALLBACK_ENVIRON const pcbe) { // use CreateThreadpoolWait if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCREATETHREADPOOLWAIT, CreateThreadpoolWait, pfCreateThreadpoolWait) { return pfCreateThreadpoolWait(pfnwa, pv, pcbe); @@ -326,7 +327,8 @@ extern "C" PTP_WAIT __cdecl __crtCreateThreadpoolWait( return nullptr; } -extern "C" VOID __cdecl __crtSetThreadpoolWait(PTP_WAIT const pwa, HANDLE const h, PFILETIME const pftTimeout) { +extern "C" VOID __cdecl __crtSetThreadpoolWait( + _Inout_ PTP_WAIT const pwa, _In_opt_ HANDLE const h, _In_opt_ PFILETIME const pftTimeout) { // use SetThreadpoolWait if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNSETTHREADPOOLWAIT, SetThreadpoolWait, pfSetThreadpoolWait) { pfSetThreadpoolWait(pwa, h, pftTimeout); @@ -335,7 +337,7 @@ extern "C" VOID __cdecl __crtSetThreadpoolWait(PTP_WAIT const pwa, HANDLE const // ...otherwise there is no fall back. } -extern "C" VOID __cdecl __crtCloseThreadpoolWait(PTP_WAIT const pwa) { +extern "C" VOID __cdecl __crtCloseThreadpoolWait(_Inout_ PTP_WAIT const pwa) { // use CloseThreadpoolWait if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCLOSETHREADPOOLWAIT, CloseThreadpoolWait, pfCloseThreadpoolWait) { pfCloseThreadpoolWait(pwa); @@ -353,7 +355,8 @@ extern "C" VOID __cdecl __crtFlushProcessWriteBuffers() { // ...otherwise there is no fall back. } -extern "C" VOID __cdecl __crtFreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE const pci, HMODULE const mod) { +extern "C" VOID __cdecl __crtFreeLibraryWhenCallbackReturns( + _Inout_ PTP_CALLBACK_INSTANCE const pci, _In_ HMODULE const mod) { // use FreeLibraryWhenCallbackReturns if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION( PFNFREELIBRARYWHENCALLBACKRETURNS, FreeLibraryWhenCallbackReturns, pfFreeLibraryWhenCallbackReturns) { @@ -374,7 +377,7 @@ extern "C" DWORD __cdecl __crtGetCurrentProcessorNumber() { } extern "C" BOOLEAN __cdecl __crtCreateSymbolicLinkW( - LPCWSTR const lpSymlinkFileName, LPCWSTR const lpTargetFileName, DWORD const dwFlags) { + _In_ LPCWSTR const lpSymlinkFileName, _In_ LPCWSTR const lpTargetFileName, _In_ DWORD const dwFlags) { // use CreateSymbolicLink if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION(PFNCREATESYMBOLICLINKW, CreateSymbolicLinkW, pfCreateSymbolicLink) { return pfCreateSymbolicLink(lpSymlinkFileName, lpTargetFileName, dwFlags); @@ -385,8 +388,9 @@ extern "C" BOOLEAN __cdecl __crtCreateSymbolicLinkW( return 0; } -extern "C" BOOL __cdecl __crtGetFileInformationByHandleEx(HANDLE const hFile, - FILE_INFO_BY_HANDLE_CLASS const FileInformationClass, LPVOID const lpFileInformation, DWORD const dwBufferSize) { +extern "C" _Success_(return ) BOOL __cdecl __crtGetFileInformationByHandleEx(_In_ HANDLE const hFile, + _In_ FILE_INFO_BY_HANDLE_CLASS const FileInformationClass, + _Out_writes_bytes_(dwBufferSize) LPVOID const lpFileInformation, _In_ DWORD const dwBufferSize) { // use GetFileInformationByHandleEx if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION( PFNGETFILEINFORMATIONBYHANDLEEX, GetFileInformationByHandleEx, pfGetFileInformationByHandleEx) { @@ -398,8 +402,9 @@ extern "C" BOOL __cdecl __crtGetFileInformationByHandleEx(HANDLE const hFile, return 0; } -extern "C" BOOL __cdecl __crtSetFileInformationByHandle(HANDLE const hFile, - FILE_INFO_BY_HANDLE_CLASS const FileInformationClass, LPVOID const lpFileInformation, DWORD const dwBufferSize) { +extern "C" BOOL __cdecl __crtSetFileInformationByHandle(_In_ HANDLE const hFile, + _In_ FILE_INFO_BY_HANDLE_CLASS const FileInformationClass, + _In_reads_bytes_(dwBufferSize) LPVOID const lpFileInformation, _In_ DWORD const dwBufferSize) { // use SetFileInformationByHandle if it is available (only on Windows Vista+)... IFDYNAMICGETCACHEDFUNCTION( PFNSETFILEINFORMATIONBYHANDLE, SetFileInformationByHandle, pfSetFileInformationByHandle) { @@ -411,78 +416,78 @@ extern "C" BOOL __cdecl __crtSetFileInformationByHandle(HANDLE const hFile, return 0; } -extern "C" VOID __cdecl __crtInitializeConditionVariable(PCONDITION_VARIABLE const pCond) { +extern "C" VOID __cdecl __crtInitializeConditionVariable(_Out_ PCONDITION_VARIABLE const pCond) { DYNAMICGETCACHEDFUNCTION( PFNINITIALIZECONDITIONVARIABLE, InitializeConditionVariable, pfInitializeConditionVariable); pfInitializeConditionVariable(pCond); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" VOID __cdecl __crtWakeConditionVariable(PCONDITION_VARIABLE const pCond) { +extern "C" VOID __cdecl __crtWakeConditionVariable(_Inout_ PCONDITION_VARIABLE const pCond) { DYNAMICGETCACHEDFUNCTION(PFNWAKECONDITIONVARIABLE, WakeConditionVariable, pfWakeConditionVariable); pfWakeConditionVariable(pCond); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" VOID __cdecl __crtWakeAllConditionVariable(PCONDITION_VARIABLE const pCond) { +extern "C" VOID __cdecl __crtWakeAllConditionVariable(_Inout_ PCONDITION_VARIABLE const pCond) { DYNAMICGETCACHEDFUNCTION(PFNWAKEALLCONDITIONVARIABLE, WakeAllConditionVariable, pfWakeAllConditionVariable); pfWakeAllConditionVariable(pCond); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } extern "C" BOOL __cdecl __crtSleepConditionVariableCS( - PCONDITION_VARIABLE const pCond, PCRITICAL_SECTION const pLock, DWORD const dwMs) { + _Inout_ PCONDITION_VARIABLE const pCond, _Inout_ PCRITICAL_SECTION const pLock, _In_ DWORD const dwMs) { DYNAMICGETCACHEDFUNCTION(PFNSLEEPCONDITIONVARIABLECS, SleepConditionVariableCS, pfSleepConditionVariableCS); return pfSleepConditionVariableCS(pCond, pLock, dwMs); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" VOID __cdecl __crtInitializeSRWLock(PSRWLOCK const pLock) { +extern "C" VOID __cdecl __crtInitializeSRWLock(_Out_ PSRWLOCK const pLock) { DYNAMICGETCACHEDFUNCTION(PFNINITIALIZESRWLOCK, InitializeSRWLock, pfInitializeSRWLock); pfInitializeSRWLock(pLock); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" VOID __cdecl __crtAcquireSRWLockExclusive(PSRWLOCK const pLock) { +extern "C" VOID __cdecl __crtAcquireSRWLockExclusive(_Inout_ PSRWLOCK const pLock) { DYNAMICGETCACHEDFUNCTION(PFNACQUIRESRWLOCKEXCLUSIVE, AcquireSRWLockExclusive, pfAcquireSRWLockExclusive); pfAcquireSRWLockExclusive(pLock); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" VOID __cdecl __crtReleaseSRWLockExclusive(PSRWLOCK const pLock) { +extern "C" VOID __cdecl __crtReleaseSRWLockExclusive(_Inout_ PSRWLOCK const pLock) { DYNAMICGETCACHEDFUNCTION(PFNRELEASESRWLOCKEXCLUSIVE, ReleaseSRWLockExclusive, pfReleaseSRWLockExclusive); pfReleaseSRWLockExclusive(pLock); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } -extern "C" BOOL __cdecl __crtSleepConditionVariableSRW( - PCONDITION_VARIABLE const pCond, PSRWLOCK const pLock, DWORD const dwMs, ULONG const flags) { +extern "C" BOOL __cdecl __crtSleepConditionVariableSRW(_Inout_ PCONDITION_VARIABLE const pCond, + _Inout_ PSRWLOCK const pLock, _In_ DWORD const dwMs, _In_ ULONG const flags) { DYNAMICGETCACHEDFUNCTION(PFNSLEEPCONDITIONVARIABLESRW, SleepConditionVariableSRW, pfSleepConditionVariableSRW); return pfSleepConditionVariableSRW(pCond, pLock, dwMs, flags); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling } extern "C" PTP_WORK __cdecl __crtCreateThreadpoolWork( - PTP_WORK_CALLBACK const pfnwk, PVOID const pv, PTP_CALLBACK_ENVIRON const pcbe) { + _In_ PTP_WORK_CALLBACK const pfnwk, _Inout_opt_ PVOID const pv, _In_opt_ PTP_CALLBACK_ENVIRON const pcbe) { DYNAMICGETCACHEDFUNCTION(PFNCREATETHREADPOOLWORK, CreateThreadpoolWork, pfCreateThreadpoolWork); return pfCreateThreadpoolWork(pfnwk, pv, pcbe); // Don't have fallbacks because the only caller (in taskscheduler.cpp) will check the existence before calling } -extern "C" VOID __cdecl __crtSubmitThreadpoolWork(PTP_WORK const pwk) { +extern "C" VOID __cdecl __crtSubmitThreadpoolWork(_Inout_ PTP_WORK const pwk) { DYNAMICGETCACHEDFUNCTION(PFNSUBMITTHREADPOOLWORK, SubmitThreadpoolWork, pfSubmitThreadpoolWork); return pfSubmitThreadpoolWork(pwk); // Don't have fallbacks because the only caller (in taskscheduler.cpp) will check the existence before calling } -extern "C" VOID __cdecl __crtCloseThreadpoolWork(PTP_WORK const pwk) { +extern "C" VOID __cdecl __crtCloseThreadpoolWork(_Inout_ PTP_WORK const pwk) { DYNAMICGETCACHEDFUNCTION(PFNCLOSETHREADPOOLWORK, CloseThreadpoolWork, pfCloseThreadpoolWork); return pfCloseThreadpoolWork(pwk); // Don't have fallbacks because the only caller (in taskscheduler.cpp) will check the existence before calling } #else // _STL_WIN32_WINNT < _WIN32_WINNT_VISTA -extern "C" BOOL __cdecl __crtQueueUserWorkItem(LPTHREAD_START_ROUTINE, PVOID, ULONG) { +extern "C" BOOL __cdecl __crtQueueUserWorkItem(_In_ LPTHREAD_START_ROUTINE, _In_opt_ PVOID, _In_ ULONG) { // This function doesn't have an implementation as it is only used on Windows XP return 0; } @@ -491,7 +496,7 @@ extern "C" BOOL __cdecl __crtQueueUserWorkItem(LPTHREAD_START_ROUTINE, PVOID, UL #if _STL_WIN32_WINNT < _WIN32_WINNT_WIN7 -extern "C" BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(PSRWLOCK const pLock) { +extern "C" BOOLEAN __cdecl __crtTryAcquireSRWLockExclusive(_Inout_ PSRWLOCK const pLock) { DYNAMICGETCACHEDFUNCTION(PFNTRYACQUIRESRWLOCKEXCLUSIVE, TryAcquireSRWLockExclusive, pfTryAcquireSRWLockExclusive); return pfTryAcquireSRWLockExclusive(pLock); // Don't have fallbacks because the only caller (in primitives.hpp) will check the existence before calling @@ -529,6 +534,7 @@ extern "C" PVOID __KERNEL32Functions[eMaxKernel32Function] = {0}; static int __cdecl initialize_pointers() { HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + _Analysis_assume_(hKernel32); STOREFUNCTIONPOINTER(hKernel32, FlsAlloc); STOREFUNCTIONPOINTER(hKernel32, FlsFree); diff --git a/stl/src/xfvalues.cpp b/stl/src/xfvalues.cpp index 5822c050fae..d0329ee4860 100644 --- a/stl/src/xfvalues.cpp +++ b/stl/src/xfvalues.cpp @@ -28,6 +28,6 @@ extern /* const */ _Dconst _FNan = {INIT((_FMAX << _FOFF) | (1 << (_FOFF - 1) extern /* const */ _Dconst _FSnan = {INIT2(_FMAX << _FOFF, 1)}; extern const _Dconst _FRteps = {INIT((_FBIAS - NBITS / 2) << _FOFF)}; -extern const float _FXbig = (NBITS + 1) * 347L / 1000; +extern const float _FXbig = (NBITS + 2) * 0.347f; _END_EXTERN_C_UNLESS_PURE diff --git a/stl/src/xlvalues.cpp b/stl/src/xlvalues.cpp index c2720fe8d16..7ec133738c2 100644 --- a/stl/src/xlvalues.cpp +++ b/stl/src/xlvalues.cpp @@ -26,4 +26,4 @@ extern /* const */ _Dconst _LNan = {INIT((_DMAX << _DOFF) | (1 << (_DOFF - 1) extern /* const */ _Dconst _LSnan = {INIT2(_DMAX << _DOFF, 1)}; extern const _Dconst _LRteps = {INIT((_DBIAS - NBITS / 2) << _DOFF)}; -extern const long double _LXbig = (NBITS + 1) * 347L / 1000; +extern const long double _LXbig = (NBITS + 2) * 0.347L; diff --git a/stl/src/xmath.hpp b/stl/src/xmath.hpp index 32bd8b60f7b..200d7a9d981 100644 --- a/stl/src/xmath.hpp +++ b/stl/src/xmath.hpp @@ -49,11 +49,15 @@ _EXTERN_C_UNLESS_PURE int _Stopfx(const char**, char**); -int _Stoflt(const char*, const char*, char**, long[], int); -int _Stoxflt(const char*, const char*, char**, long[], int); +_In_range_(0, maxsig) int _Stoflt( + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); +_In_range_(0, maxsig) int _Stoxflt( + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); int _WStopfx(const wchar_t**, wchar_t**); -int _WStoflt(const wchar_t*, const wchar_t*, wchar_t**, long[], int); -int _WStoxflt(const wchar_t*, const wchar_t*, wchar_t**, long[], int); +_In_range_(0, maxsig) int _WStoflt( + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); +_In_range_(0, maxsig) int _WStoxflt( + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); // double declarations union _Dval { // pun floating type as integer array diff --git a/stl/src/xmbtowc.cpp b/stl/src/xmbtowc.cpp index 0983f451519..5bc58a872cf 100644 --- a/stl/src/xmbtowc.cpp +++ b/stl/src/xmbtowc.cpp @@ -66,7 +66,8 @@ static int _Decode_utf8_trailing_byte(unsigned long* partialCh, unsigned char ch // -1 (if the next n or fewer bytes not valid mbc) // -2 (if partial conversion) // number of bytes comprising converted mbc -_MRTIMP2 int __cdecl _Mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* pst, const _Cvtvec* ploc) { +_MRTIMP2 _Success_(return >= 0) int __cdecl _Mbrtowc( + _When_(n != 0, _Out_) wchar_t* pwc, const char* s, size_t n, mbstate_t* pst, const _Cvtvec* ploc) { (void) pst; if (n == 0) { // indicate do not have state-dependent encodings, handle zero length string return 0; diff --git a/stl/src/xstoflt.cpp b/stl/src/xstoflt.cpp index 98c203cdd7a..57dfdaf5707 100644 --- a/stl/src/xstoflt.cpp +++ b/stl/src/xstoflt.cpp @@ -15,8 +15,9 @@ constexpr int _Base = 10; // decimal constexpr int _Ndig = 9; // decimal digits per long word constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -int _Stoflt(const char* s0, const char* s, char** endptr, long lo[], - int maxsig) { // convert string to array of long plus exponent +_In_range_(0, maxsig) int _Stoflt( + const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen diff --git a/stl/src/xstoxflt.cpp b/stl/src/xstoxflt.cpp index 7ef6b4d2018..3c18095a71d 100644 --- a/stl/src/xstoxflt.cpp +++ b/stl/src/xstoxflt.cpp @@ -16,8 +16,9 @@ constexpr int _Base = 16; // hexadecimal constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -int _Stoxflt(const char* s0, const char* s, char** endptr, long lo[], - int maxsig) { // convert string to array of long plus exponent +_In_range_(0, maxsig) int _Stoxflt( + const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen diff --git a/stl/src/xstrxfrm.cpp b/stl/src/xstrxfrm.cpp index 3348cf0957c..e7988a747ab 100644 --- a/stl/src/xstrxfrm.cpp +++ b/stl/src/xstrxfrm.cpp @@ -52,8 +52,9 @@ _EXTERN_C_UNLESS_PURE // // Exceptions: // Non-standard: if OM/API error, return INT_MAX. -_CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Strxfrm( - char* string1, char* end1, const char* string2, const char* end2, const _Collvec* ploc) { +_CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Strxfrm(_Out_writes_(end1 - string1) + _Post_readable_size_(return ) char* string1, + _In_z_ char* end1, const char* string2, const char* end2, const _Collvec* ploc) { size_t n1 = end1 - string1; size_t n2 = end2 - string2; size_t retval = static_cast(-1); // NON-ANSI: default if OM or API error diff --git a/stl/src/xvalues.cpp b/stl/src/xvalues.cpp index e48d493d42c..1d9a1fb1e30 100644 --- a/stl/src/xvalues.cpp +++ b/stl/src/xvalues.cpp @@ -28,4 +28,4 @@ extern /* const */ _Dconst _Nan = {INIT((_DMAX << _DOFF) | (1 << (_DOFF - 1) extern /* const */ _Dconst _Snan = {INIT2(_DMAX << _DOFF, 1)}; extern const _Dconst _Rteps = {INIT((_DBIAS - NBITS / 2) << _DOFF)}; -extern const double _Xbig = (NBITS + 1) * 347L / 1000; +extern const double _Xbig = (NBITS + 2) * 0.347; diff --git a/stl/src/xwcsxfrm.cpp b/stl/src/xwcsxfrm.cpp index 31fc90a6b28..ab3692be410 100644 --- a/stl/src/xwcsxfrm.cpp +++ b/stl/src/xwcsxfrm.cpp @@ -44,12 +44,12 @@ _EXTERN_C_UNLESS_PURE // // Exceptions: // Non-standard: if OM/API error, return INT_MAX. -_CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm( - wchar_t* string1, wchar_t* end1, const wchar_t* string2, const wchar_t* end2, const _Collvec* ploc) { - size_t n1 = end1 - string1; - size_t n2 = end2 - string2; - size_t size = static_cast(-1); - unsigned char* bbuffer = nullptr; +_CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm(_Out_writes_(end1 - string1) _Post_readable_size_(return ) + wchar_t* string1, + _In_z_ wchar_t* end1, const wchar_t* string2, const wchar_t* end2, const _Collvec* ploc) { + size_t n1 = end1 - string1; + size_t n2 = end2 - string2; + size_t size = static_cast(-1); const wchar_t* locale_name; if (ploc == nullptr) { @@ -71,11 +71,12 @@ _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm( // compared using wcscmp(). User's buffer is n1 wide chars, so // use an internal buffer of n1 bytes. - bbuffer = static_cast(_malloc_crt(n1)); + auto bbuffer = _malloc_crt_t(unsigned char, n1); - if (bbuffer != nullptr) { + if (bbuffer) { +#pragma warning(suppress : 6386) // PREfast doesn't understand LCMAP_SORTKEY size = __crtLCMapStringW(locale_name, LCMAP_SORTKEY, string2, static_cast(n2), - reinterpret_cast(bbuffer), static_cast(n1)); + reinterpret_cast(bbuffer.get()), static_cast(n1)); if (size == 0) { // buffer not big enough, get size required. @@ -88,16 +89,12 @@ _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm( // string successfully mapped, convert to wide char for (size_t i = 0; i < size; ++i) { - string1[i] = static_cast(bbuffer[i]); + string1[i] = static_cast(bbuffer.get()[i]); } } } } - if (bbuffer) { - _free_crt(bbuffer); - } - return size; } diff --git a/stl/src/xwctomb.cpp b/stl/src/xwctomb.cpp index 2c94e37da6a..d82f8a5bdaa 100644 --- a/stl/src/xwctomb.cpp +++ b/stl/src/xwctomb.cpp @@ -41,7 +41,8 @@ _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL __Wcrtomb_lk(char* s, wchar_t wchar, m return _Wcrtomb(s, wchar, pst, ploc); } -_CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Wcrtomb(char* s, wchar_t wchar, mbstate_t* pst, const _Cvtvec* ploc) { +_CRTIMP2_PURE _Success_(return != -1) int __CLRCALL_PURE_OR_CDECL + _Wcrtomb(_Out_ char* s, wchar_t wchar, mbstate_t* pst, const _Cvtvec* ploc) { _CRT_UNUSED(pst); if (ploc->_Isclocale) { if (wchar > 255) { // validate high byte diff --git a/stl/src/xwstoflt.cpp b/stl/src/xwstoflt.cpp index 7f5f3fddac4..0631679e5d2 100644 --- a/stl/src/xwstoflt.cpp +++ b/stl/src/xwstoflt.cpp @@ -15,8 +15,9 @@ constexpr int _Base = 10; // decimal constexpr int _Ndig = 9; // decimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -int _WStoflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, long lo[], - int maxsig) { // convert wide string to array of long plus exponent +_In_range_(0, maxsig) int _WStoflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen diff --git a/stl/src/xwstoxfl.cpp b/stl/src/xwstoxfl.cpp index f694b9bd201..871501031e3 100644 --- a/stl/src/xwstoxfl.cpp +++ b/stl/src/xwstoxfl.cpp @@ -16,8 +16,9 @@ constexpr int _Base = 16; // hexadecimal constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, long lo[], - int maxsig) { // convert wide string to array of long plus exponent +_In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen diff --git a/stl/src/xxstod.hpp b/stl/src/xxstod.hpp index 25f93fb7f47..58c81be89aa 100644 --- a/stl/src/xxstod.hpp +++ b/stl/src/xxstod.hpp @@ -9,15 +9,13 @@ #define D16TO7 FLIT(268435456.0) // 16^7 #define D10TO9 FLIT(1e9) // 10^9 -#if FBITS <= 24 +#if FBITS == 24 #define NLONG 1 // 7 * NLONG == max hexadecimal digits - -#elif FBITS <= 64 +#elif FBITS == 53 #define NLONG 3 - -#else // NLONG -#define NLONG 5 -#endif // NLONG +#else // FBITS +#error Unexpected value for FBITS +#endif // FBITS // FTYPE _Stodx(const CTYPE *s, CTYPE **endptr, long pten, int *perr) { // convert string to FTYPE, with checking @@ -35,7 +33,9 @@ if ((code &= ~FL_NEG) == FL_DEC) { // parse decimal format const int nlo = CNAME(Stoflt)(s0, s, endptr, lo, NLONG); - FTYPE xpx[ACSIZE], xpf[ACSIZE]; + _Analysis_assume_(nlo <= NLONG); + FTYPE xpx[ACSIZE]; + FTYPE xpf[ACSIZE]; int i; FNAME(Xp_setw)(xpf, ACSIZE, D10TO9); @@ -56,7 +56,9 @@ x = FNAME(Dtento)(xpx, pten, perr); } else if (code == FL_HEX) { // parse hexadecimal format const int nlo = CNAME(Stoxflt)(s0, s, endptr, lo, NLONG); - FTYPE xpx[ACSIZE], xpf[ACSIZE]; + _Analysis_assume_(nlo <= NLONG); + FTYPE xpx[ACSIZE]; + FTYPE xpf[ACSIZE]; int i; FNAME(Xp_setw)(xpf, ACSIZE, D16TO7); diff --git a/stl/src/xxxprec.hpp b/stl/src/xxxprec.hpp index a5990e030d7..7f63882fa38 100644 --- a/stl/src/xxxprec.hpp +++ b/stl/src/xxxprec.hpp @@ -6,6 +6,10 @@ #include #include "xmath.hpp" + +#pragma warning(push) +#pragma warning(disable : _STL_DISABLED_WARNINGS) + #if !defined(MRTDLL) _EXTERN_C #endif // defined(MRTDLL) @@ -63,20 +67,31 @@ FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value short errx; short xexp; - if (n > 0) { - if (n == 1 || (errx = FNAME(Dunscale)(&xexp, &x0)) == 0) { - p[0] = x0; // zero or no extra room, store original value - } else if (0 < errx) { // store Inf or NaN with backstop for safety - p[0] = x0; - p[1] = FLIT(0.0); - } else { // finite, unpack it - FNAME(Dint)(&x0, BITS_WORD); - FNAME(Dscale)(&x0, xexp); - - p[0] = x0; // ms bits - p[1] = x - x0; // ls bits -#pragma warning(suppress : 4127) - if ((FBITS & 1) != 0 && 2 < n && p[1] != FLIT(0.0)) { // may need a third word + if (n <= 0) { + return p; + } + + if (n == 1 || (errx = FNAME(Dunscale)(&xexp, &x0)) == 0) { + p[0] = x0; // zero or no extra room, store original value + return p; + } + + if (0 < errx) { // store Inf or NaN with backstop for safety + p[0] = x0; + p[1] = FLIT(0.0); + return p; + } + + // finite, unpack it + FNAME(Dint)(&x0, BITS_WORD); + FNAME(Dscale)(&x0, xexp); + + p[0] = x0; // ms bits + p[1] = x - x0; // ls bits + + if (2 < n) { + if constexpr ((FBITS & 1) != 0) { + if (p[1] != FLIT(0.0)) { // may need a third word x = p[1]; FNAME(Dunscale)(&xexp, &p[1]); FNAME(Dint)(&p[1], BITS_WORD); @@ -85,10 +100,12 @@ FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value if (3 < n && p[2] != FLIT(0.0)) { p[3] = FLIT(0.0); } - } else if (2 < n) { - p[2] = FLIT(0.0); + + return p; } } + + p[2] = FLIT(0.0); } return p; @@ -265,13 +282,15 @@ FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) { // multiply by a half-precisi FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) { // load a long integer -#if 27 <= FBITS +#if FBITS == 53 FNAME(Xp_setw)(p, n, static_cast(x)); -#else // 27 <= FBITS +#elif FBITS == 24 FNAME(Xp_setw)(p, n, static_cast(x / 10000)); FNAME(Xp_mulh)(p, n, static_cast(10000)); FNAME(Xp_addh)(p, n, static_cast(x % 10000)); -#endif // 27 <= FBITS +#else // FBITS +#error Unexpected value for FBITS +#endif // FBITS return p; } @@ -412,3 +431,5 @@ FTYPE* FNAME(Xp_sqrtx)(FTYPE* p, int n, FTYPE* ptemp4) { #if !defined(MRTDLL) _END_EXTERN_C #endif // !defined(MRTDLL) + +#pragma warning(pop) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 97eb5036ed5..40698cb88b2 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -506,9 +506,6 @@ std/thread/futures/futures.task/futures.task.members/make_ready_at_thread_exit.p # *** C1XX COMPILER BUGS *** -# Compiler bug: VSO-106654 "error C2580 "multiple versions of a defaulted special member functions are not allowed" is bogus and ungrammatical" -std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp:0 FAIL - # Compiler bug: DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference" std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp:0 FAIL diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 0aceecdbb57..2f3866059fb 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -506,9 +506,6 @@ thread\futures\futures.task\futures.task.members\make_ready_at_thread_exit.pass. # *** C1XX COMPILER BUGS *** -# Compiler bug: VSO-106654 "error C2580 "multiple versions of a defaulted special member functions are not allowed" is bogus and ungrammatical" -utilities\tuple\tuple.tuple\tuple.cnstr\test_lazy_sfinae.pass.cpp - # Compiler bug: DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference" utilities\meta\meta.unary\meta.unary.prop\is_constructible.pass.cpp diff --git a/tests/std/expected_results.txt b/tests/std/expected_results.txt index ab51c8331ca..2ac2a854cb0 100644 --- a/tests/std/expected_results.txt +++ b/tests/std/expected_results.txt @@ -1,13 +1,2 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# TRANSITION, VSO-1093670 "Memory corruption in EDG when processing multiple TUs" -tests/GH_000545_include_compare:15 SKIPPED -tests/GH_000545_include_compare:16 SKIPPED -tests/P0607R0_inline_variables:19 SKIPPED -tests/P0607R0_inline_variables:20 SKIPPED -tests/P0607R0_inline_variables:21 SKIPPED - -# TRANSITION, GH-697 "We should have means of collecting compiler and test crash dumps" -# The ICE we are skipping this test because of is not easily reproducible we need to collect dumps -tests/VSO_0000000_string_view_idl:15 SKIPPED diff --git a/tests/std/include/range_algorithm_support.hpp b/tests/std/include/range_algorithm_support.hpp index 7b71a423a0e..60fa690bc52 100644 --- a/tests/std/include/range_algorithm_support.hpp +++ b/tests/std/include/range_algorithm_support.hpp @@ -968,6 +968,56 @@ struct with_output_ranges { } }; +template +struct with_input_or_output_ranges { + template + static constexpr void call() { + using namespace test; + using test::range; + + // For all ranges, IsCommon implies Eq. + // For single-pass ranges, Eq is uninteresting without IsCommon (there's only one valid iterator + // value at a time, and no reason to compare it with itself for equality). + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + Continuation::template call>(); + + with_output_ranges::template call(); + } +}; + template struct with_input_iterators { template @@ -1018,6 +1068,11 @@ constexpr void test_in() { with_input_ranges::call(); } +template +constexpr void test_inout() { + with_input_or_output_ranges::call(); +} + template constexpr void test_fwd() { with_forward_ranges::call(); diff --git a/tests/std/test.lst b/tests/std/test.lst index 0e60c21053b..499a40f9004 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -164,6 +164,7 @@ tests\GH_000890_pow_template tests\GH_000940_missing_valarray_copy tests\GH_001010_filesystem_error_encoding tests\GH_001017_discrete_distribution_out_of_range +tests\GH_001059_hyperbolic_truncation tests\GH_001086_partial_sort_copy tests\GH_001103_countl_zero_correctness tests\LWG2597_complex_branch_cut @@ -312,11 +313,15 @@ tests\P0896R4_ranges_alg_unique_copy tests\P0896R4_ranges_algorithm_machinery tests\P0896R4_ranges_iterator_machinery tests\P0896R4_ranges_range_machinery +tests\P0896R4_ranges_ref_view tests\P0896R4_ranges_subrange tests\P0896R4_ranges_test_machinery tests\P0896R4_ranges_to_address +tests\P0896R4_views_empty +tests\P0896R4_views_single tests\P0898R3_concepts tests\P0898R3_identity +tests\P0912R5_coroutine tests\P0919R3_heterogeneous_unordered_lookup tests\P0966R1_string_reserve_should_not_shrink tests\P1023R0_constexpr_for_array_comparisons diff --git a/tests/std/tests/Dev10_881629_vector_erase_return_value/test.cpp b/tests/std/tests/Dev10_881629_vector_erase_return_value/test.cpp index 9b6358318bd..d7aa0dbcfde 100644 --- a/tests/std/tests/Dev10_881629_vector_erase_return_value/test.cpp +++ b/tests/std/tests/Dev10_881629_vector_erase_return_value/test.cpp @@ -44,6 +44,28 @@ void test_case_devcom_776568() { assert(it == c.end()); } +template