Skip to content

Commit

Permalink
Merge pull request #2 from microsoft/master
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
AdamBucior authored Dec 5, 2019
2 parents 580e61a + 19067f6 commit e3c45e5
Show file tree
Hide file tree
Showing 24 changed files with 1,062 additions and 470 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ issue. The [bug tag][] and [enhancement tag][] remain to be populated.

# Goals

We're implementing the latest C++ Working Draft, currently [N4835][], which will eventually become the next C++
We're implementing the latest C++ Working Draft, currently [N4842][], which will eventually become the next C++
International Standard (which is sometimes referred to as C++2a, but we optimistically refer to it as C++20). The terms
Working Draft (WD) and Working Paper (WP) are interchangeable; we often informally refer to these drafts as "the
Standard" while being aware of the difference. (There are other relevant Standards; for example, supporting `/std:c++14`
Expand Down Expand Up @@ -257,7 +257,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
[LWG issues]: https://cplusplus.github.io/LWG/lwg-toc.html
[LWG tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3ALWG
[Microsoft Open Source Code of Conduct]: https://opensource.microsoft.com/codeofconduct/
[N4835]: https://wg21.link/n4835
[N4842]: https://wg21.link/n4842
[NOTICE.txt]: NOTICE.txt
[Ninja]: https://ninja-build.org
[Pipelines]: https://dev.azure.com/vclibs/STL/_build/latest?definitionId=2&branchName=master
Expand Down
1 change: 1 addition & 0 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/any
${CMAKE_CURRENT_LIST_DIR}/inc/array
${CMAKE_CURRENT_LIST_DIR}/inc/atomic
${CMAKE_CURRENT_LIST_DIR}/inc/bit
${CMAKE_CURRENT_LIST_DIR}/inc/bitset
${CMAKE_CURRENT_LIST_DIR}/inc/cassert
${CMAKE_CURRENT_LIST_DIR}/inc/ccomplex
Expand Down
1 change: 1 addition & 0 deletions stl/inc/__msvc_all_public_headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <algorithm>
#include <any>
#include <array>
#include <bit>
#include <bitset>
#include <charconv>
#include <chrono>
Expand Down
69 changes: 69 additions & 0 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,74 @@ _NODISCARD _FwdIt unique(_ExPo&&, _FwdIt _First, _FwdIt _Last) noexcept /* termi
#endif // _HAS_CXX17

// FUNCTION TEMPLATE unique_copy
#if _HAS_IF_CONSTEXPR
// clang-format off
#ifdef __cpp_lib_concepts
template <class _InIt, class _OutIt>
concept _Can_reread_dest = forward_iterator<_OutIt> && same_as<iter_value_t<_InIt>, iter_value_t<_OutIt>>;
#else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv
template <class _InIt, class _OutIt>
_INLINE_VAR constexpr bool _Can_reread_dest =
_Is_fwd_iter_v<_OutIt> && is_same_v<_Iter_value_t<_InIt>, _Iter_value_t<_OutIt>>;
#endif // __cpp_lib_concepts
// clang-format on

template <class _InIt, class _OutIt, class _Pr>
_OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) { // copy compressing pairs that match
_Adl_verify_range(_First, _Last);

auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);

if (_UFirst == _ULast) {
return _Dest;
}

auto _UDest = _Get_unwrapped_unverified(_Dest);

if constexpr (_Is_fwd_iter_v<_InIt>) { // can reread the source for comparison
auto _Firstb = _UFirst;

*_UDest = *_Firstb;
++_UDest;

while (++_UFirst != _ULast) {
if (!static_cast<bool>(_Pred(*_Firstb, *_UFirst))) { // copy unmatched
_Firstb = _UFirst;
*_UDest = *_Firstb;
++_UDest;
}
}
} else if constexpr (_Can_reread_dest<_InIt, _OutIt>) { // assignment copies T; can reread dest for comparison
*_UDest = *_UFirst;

while (++_UFirst != _ULast) {
if (!static_cast<bool>(_Pred(*_UDest, *_UFirst))) {
*++_UDest = *_UFirst;
}
}

++_UDest;
} else { // can't reread source or dest, construct a temporary
_Iter_value_t<_InIt> _Val = *_UFirst;

*_UDest = _Val;
++_UDest;

while (++_UFirst != _ULast) {
if (!static_cast<bool>(_Pred(_Val, *_UFirst))) { // copy unmatched
_Val = *_UFirst;
*_UDest = _Val;
++_UDest;
}
}
}

_Seek_wrapped(_Dest, _UDest);
return _Dest;
}

#else // ^^^ _HAS_IF_CONSTEXPR / !_HAS_IF_CONSTEXPR vvv
template <class _FwdIt, class _OutIt, class _Pr>
_OutIt _Unique_copy_unchecked(_FwdIt _First, _FwdIt _Last, _OutIt _Dest, _Pr _Pred, true_type, _Any_tag) {
// copy compressing pairs satisfying _Pred, forward source iterator
Expand Down Expand Up @@ -1865,6 +1933,7 @@ _OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) { // copy

return _Dest;
}
#endif // _HAS_IF_CONSTEXPR

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Pr>
Expand Down
151 changes: 151 additions & 0 deletions stl/inc/bit
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// bit standard header (core)

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once
#ifndef _BIT_
#define _BIT_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#if !_HAS_CXX20
#pragma message("The contents of <bit> are available only with C++20 or later.")
#else // ^^^ !_HAS_CXX20 / _HAS_CXX20 vvv

#include <limits>
#include <type_traits>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN
enum class endian { little = 0, big = 1, native = little };

#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212
template <class _Ty>
inline constexpr bool _Is_standard_unsigned_integer =
_Is_any_of_v<remove_cv_t<_Ty>, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>;


template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr int countl_zero(_Ty _Val) noexcept;

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr bool ispow2(const _Ty _Val) noexcept {
return _Val != 0 && (_Val & (_Val - 1)) == 0;
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty ceil2(const _Ty _Val) noexcept /* strengthened */ {
if (_Val == 0) {
return 1;
}

return static_cast<_Ty>(_Ty{1} << (numeric_limits<_Ty>::digits - _STD countl_zero(static_cast<_Ty>(_Val - 1))));
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty floor2(const _Ty _Val) noexcept {
if (_Val == 0) {
return 0;
}

return static_cast<_Ty>(_Ty{1} << (numeric_limits<_Ty>::digits - 1 - _STD countl_zero(_Val)));
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty bit_length(const _Ty _Val) noexcept {
return static_cast<_Ty>(numeric_limits<_Ty>::digits - _STD countl_zero(_Val));
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty rotr(_Ty _Val, int _Rotation) noexcept;

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty rotl(const _Ty _Val, const int _Rotation) noexcept {
constexpr auto _Digits = numeric_limits<_Ty>::digits;
const auto _Remainder = _Rotation % _Digits;
if (_Remainder > 0) {
return static_cast<_Ty>(
static_cast<_Ty>(_Val << _Remainder) | static_cast<_Ty>(_Val >> (_Digits - _Remainder)));
} else if (_Remainder == 0) {
return _Val;
} else { // _Remainder < 0
return _STD rotr(_Val, -_Remainder);
}
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled>
_NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept {
constexpr auto _Digits = numeric_limits<_Ty>::digits;
const auto _Remainder = _Rotation % _Digits;
if (_Remainder > 0) {
return static_cast<_Ty>(
static_cast<_Ty>(_Val >> _Remainder) | static_cast<_Ty>(_Val << (_Digits - _Remainder)));
} else if (_Remainder == 0) {
return _Val;
} else { // _Remainder < 0
return _STD rotl(_Val, -_Remainder);
}
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled>
_NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept {
constexpr int _Digits = numeric_limits<_Ty>::digits;
if (_Val == 0) {
return _Digits;
}

if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) {
return __builtin_clz(_Val) - (numeric_limits<unsigned int>::digits - _Digits);
} else {
return __builtin_clzll(_Val) - (numeric_limits<unsigned long long>::digits - _Digits);
}
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr int countl_one(const _Ty _Val) noexcept {
return _STD countl_zero(static_cast<_Ty>(~_Val));
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr int countr_zero(const _Ty _Val) noexcept {
if (_Val == 0) {
return numeric_limits<_Ty>::digits;
}

if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) {
return __builtin_ctz(_Val);
} else {
return __builtin_ctzll(_Val);
}
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled = 0>
_NODISCARD constexpr int countr_one(const _Ty _Val) noexcept {
return _STD countr_zero(static_cast<_Ty>(~_Val));
}

template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled = 0>
_NODISCARD constexpr int popcount(const _Ty _Val) noexcept {
if constexpr (sizeof(_Ty) <= sizeof(unsigned int)) {
return __builtin_popcount(_Val);
} else {
return __builtin_popcountll(_Val);
}
}
#endif // __cpp_lib_bitops

_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _HAS_CXX20
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _BIT_
11 changes: 8 additions & 3 deletions stl/inc/bitset
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,14 @@ basic_istream<_Elem, _Tr>& operator>>(basic_istream<_Elem, _Tr>& _Istr, bitset<_
_CATCH_IO_(_Istr_t, _Istr)
}

if (!_Changed) {
_State |= _Istr_t::failbit;
}
constexpr bool _Has_bits = _Bits > 0;

if
_CONSTEXPR_IF(_Has_bits) {
if (!_Changed) {
_State |= _Istr_t::failbit;
}
}

_Istr.setstate(_State);
_Right = bitset<_Bits>(_Str); // convert string and store
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/charconv
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ inline to_chars_result to_chars(char* const _First, char* const _Last, const uns
return _Integer_to_chars(_First, _Last, _Value, _Base);
}

to_chars_result to_chars(char* _First, char* _Last, bool _Value, int _Base = 10) = delete;


// FUNCTION TEMPLATE _Bit_cast
template <class _To, class _From,
Expand Down
10 changes: 5 additions & 5 deletions stl/inc/concepts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ namespace ranges {
// CONCEPT swappable
template <class _Ty>
concept swappable = requires(_Ty& __x, _Ty& __y) {
_STD ranges::swap(__x, __y);
_RANGES swap(__x, __y);
};

// CONCEPT swappable_with
Expand All @@ -192,10 +192,10 @@ concept swappable_with =
common_reference_with<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>
#endif // select LWG-3175 vs. N4810
&& requires(_Ty1&& __t, _Ty2&& __u) {
_STD ranges::swap(static_cast<_Ty1&&>(__t), static_cast<_Ty1&&>(__t));
_STD ranges::swap(static_cast<_Ty2&&>(__u), static_cast<_Ty2&&>(__u));
_STD ranges::swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u));
_STD ranges::swap(static_cast<_Ty2&&>(__u), static_cast<_Ty1&&>(__t));
_RANGES swap(static_cast<_Ty1&&>(__t), static_cast<_Ty1&&>(__t));
_RANGES swap(static_cast<_Ty2&&>(__u), static_cast<_Ty2&&>(__u));
_RANGES swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u));
_RANGES swap(static_cast<_Ty2&&>(__u), static_cast<_Ty1&&>(__t));
};

// CONCEPT copy_constructible
Expand Down
Loading

0 comments on commit e3c45e5

Please sign in to comment.