Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ce5196e
more operator of int128
steve02081504 Mar 11, 2023
2e8b843
remove operator bool and template operator float_T
steve02081504 Mar 11, 2023
faec74d
remove operators
steve02081504 Mar 11, 2023
636907b
fix negative
steve02081504 Mar 11, 2023
165b493
Update stl/inc/__msvc_int128.hpp
steve02081504 Mar 11, 2023
22a0383
Update __msvc_int128.hpp
steve02081504 Mar 11, 2023
7f9e7b3
fromat
steve02081504 Mar 11, 2023
0cbc610
fixof cast
steve02081504 Mar 11, 2023
d374ebf
is_integral & is_arithmetic of int128
steve02081504 Mar 11, 2023
8128a52
format
steve02081504 Mar 11, 2023
85d4229
float to int128
steve02081504 Mar 11, 2023
71fd942
format
steve02081504 Mar 11, 2023
6de8a8e
fix of float2signed128
steve02081504 Mar 11, 2023
96a6c68
looks like int128 can't cast to size_t, idk why
steve02081504 Mar 11, 2023
6aa5c10
remove is_integral & is_arithmetic of int128
steve02081504 Mar 11, 2023
1cf420d
explicit。
steve02081504 Mar 11, 2023
59e0bb8
Revert "remove is_integral & is_arithmetic of int128"
steve02081504 Mar 11, 2023
a711aa9
fix abs using
steve02081504 Mar 11, 2023
acf5ff6
Revert "Revert "remove is_integral & is_arithmetic of int128""
steve02081504 Mar 11, 2023
3f96d6d
fix float to int128
steve02081504 Mar 11, 2023
ec352e2
fix of int128tofloat
steve02081504 Mar 11, 2023
7416bfa
workaround of clong
steve02081504 Mar 11, 2023
54d1e2a
Just a note
steve02081504 Mar 11, 2023
f86914c
workaround of _Signed128
steve02081504 Mar 11, 2023
6d99bac
little update
steve02081504 Mar 11, 2023
035ec61
**clang-format**
steve02081504 Mar 11, 2023
1c63f8f
Cleanup workaround
frederick-vs-ja Mar 12, 2023
bf9c0b3
Simple test coverage for FP conversions
frederick-vs-ja Mar 12, 2023
564b107
C++14 and `static_assert`
frederick-vs-ja Mar 12, 2023
6a8aa31
Merge pull request #1 from frederick-vs-ja/int-class-fp-conv
steve02081504 Mar 12, 2023
8f1ec0b
format
steve02081504 Mar 12, 2023
6eee4c5
Update tests/std/tests/P1522R1_difference_type/test.cpp
steve02081504 Mar 12, 2023
19b5ce1
I like longer names so
steve02081504 Mar 12, 2023
d29abb3
Treating long double as long double
steve02081504 Mar 14, 2023
d1b8d00
remove f
steve02081504 Mar 14, 2023
e876bbd
Revert "Treating long double as long double"
steve02081504 Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 82 additions & 7 deletions stl/inc/__msvc_int128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@

#ifdef __cpp_lib_concepts
#include <concepts>
#define _TEMPLATE_CLASS_INTEGRAL(type) template <integral type>
#define _TEMPLATE_CLASS_INTEGRAL(type) template <integral type>
#define _TEMPLATE_CLASS_FLOATING_POINT(type) template <floating_point type>
#else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv
#define _TEMPLATE_CLASS_INTEGRAL(type) template <class type, enable_if_t<is_integral_v<type>, int> = 0>
#define _TEMPLATE_CLASS_INTEGRAL(type) template <class type, enable_if_t<is_integral_v<type>, int> = 0>
#define _TEMPLATE_CLASS_FLOATING_POINT(type) template <class type, enable_if_t<is_floating_point_v<type>, int> = 0>
#endif // ^^^ !defined(__cpp_lib_concepts) ^^^

#pragma pack(push, _CRT_PACKING)
Expand Down Expand Up @@ -309,11 +311,6 @@ struct

constexpr explicit _Base128(const uint64_t _Low, const uint64_t _High) noexcept : _Word{_Low, _High} {}

_TEMPLATE_CLASS_INTEGRAL(_Ty)
_NODISCARD constexpr explicit operator _Ty() const noexcept {
return static_cast<_Ty>(_Word[0]);
}

_NODISCARD constexpr explicit operator bool() const noexcept {
return (_Word[0] | _Word[1]) != 0;
}
Expand Down Expand Up @@ -721,6 +718,36 @@ struct _Unsigned128 : _Base128 {
using _Base128::_Base128;
constexpr explicit _Unsigned128(const _Base128& _That) noexcept : _Base128{_That} {}

#ifdef __clang__ // TRANSITION, Clang 16 or 17
constexpr explicit _Unsigned128(const float _Val) noexcept {
_Word[0] = static_cast<uint64_t>(_Val);
_Word[1] = static_cast<uint64_t>(_Val / 18446744073709551616.0f);
}

constexpr explicit _Unsigned128(const double _Val) noexcept {
_Word[0] = static_cast<uint64_t>(_Val);
_Word[1] = static_cast<uint64_t>(_Val / 18446744073709551616.0);
}

constexpr explicit _Unsigned128(const long double _Val) noexcept : _Unsigned128(static_cast<double>(_Val)) {}
#else // ^^^ workaround / no workaround vvv
_TEMPLATE_CLASS_FLOATING_POINT(_Ty)
constexpr explicit _Unsigned128(const _Ty _Val) noexcept {
_Word[0] = static_cast<uint64_t>(_Val);
_Word[1] = static_cast<uint64_t>(_Val / static_cast<_Ty>(18446744073709551616.0));
}
#endif // ^^^ no workaround ^^^

_TEMPLATE_CLASS_INTEGRAL(_Ty)
_NODISCARD constexpr explicit operator _Ty() const noexcept {
return static_cast<_Ty>(_Word[0]);
}

_TEMPLATE_CLASS_FLOATING_POINT(_Ty)
_NODISCARD constexpr explicit operator _Ty() const noexcept {
return static_cast<_Ty>(_Word[1]) * static_cast<_Ty>(18446744073709551616.0) + static_cast<_Ty>(_Word[0]);
}

constexpr _Unsigned128& operator=(const _Base128& _That) noexcept {
_Base128::operator=(_That);
return *this;
Expand Down Expand Up @@ -1038,6 +1065,53 @@ struct _Signed128 : _Base128 {
using _Base128::_Base128;
constexpr explicit _Signed128(const _Base128& _That) noexcept : _Base128{_That} {}

#ifdef __clang__ // TRANSITION, Clang 16 or 17
constexpr explicit _Signed128(const float _Val) noexcept {
const bool _Negative = _Val < 0.0f;
const float _Absval = _Negative ? -_Val : _Val;
_Word[0] = static_cast<uint64_t>(_Absval);
_Word[1] = static_cast<uint64_t>(_Absval / 18446744073709551616.0f);
if (_Negative) {
*this = -*this;
}
}

constexpr explicit _Signed128(const double _Val) noexcept {
const bool _Negative = _Val < 0.0;
const double _Absval = _Negative ? -_Val : _Val;
_Word[0] = static_cast<uint64_t>(_Absval);
_Word[1] = static_cast<uint64_t>(_Absval / 18446744073709551616.0);
if (_Negative) {
*this = -*this;
}
}

constexpr explicit _Signed128(const long double _Val) noexcept : _Signed128(static_cast<double>(_Val)) {}
#else // ^^^ workaround / no workaround vvv
_TEMPLATE_CLASS_FLOATING_POINT(_Ty)
constexpr explicit _Signed128(const _Ty _Val) noexcept {
const bool _Negative = _Val < 0.0f;
const _Ty _Absval = _Negative ? -_Val : _Val;
_Word[0] = static_cast<uint64_t>(_Absval);
_Word[1] = static_cast<uint64_t>(_Absval / static_cast<_Ty>(18446744073709551616.0));
if (_Negative) {
*this = -*this;
}
}
#endif // ^^^ no workaround ^^^

_TEMPLATE_CLASS_INTEGRAL(_Ty)
_NODISCARD constexpr explicit operator _Ty() const noexcept {
return static_cast<_Ty>(_Word[0]);
}

_TEMPLATE_CLASS_FLOATING_POINT(_Ty)
_NODISCARD constexpr explicit operator _Ty() const noexcept {
const auto _Unsigned_self = static_cast<_Unsigned128>(*this);
return static_cast<int64_t>(_Word[1]) < 0 ? -static_cast<_Ty>(-_Unsigned_self)
: static_cast<_Ty>(_Unsigned_self);
}

constexpr _Signed128& operator=(const _Base128& _That) noexcept {
_Base128::operator=(_That);
return *this;
Expand Down Expand Up @@ -1427,6 +1501,7 @@ struct common_type<_Unsigned128, _Signed128> {

_STD_END

#undef _TEMPLATE_CLASS_FLOATING_POINT
#undef _TEMPLATE_CLASS_INTEGRAL
#undef _ZERO_OR_NO_INIT

Expand Down
41 changes: 41 additions & 0 deletions tests/std/tests/P1522R1_difference_type/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1345,11 +1345,52 @@ constexpr bool test_cross() {
return true;
}

// Extension: explicit conversion from and to floating-point types

template <class Flt>
constexpr bool test_one_floating_point() {
constexpr Flt zero = Flt{};
constexpr Flt one = Flt{1.0};
constexpr Flt neg_one = Flt{-1.0};

assert(_Unsigned128{zero} == _Unsigned128{});
assert(_Unsigned128{zero} == 0);
assert(static_cast<Flt>(_Unsigned128{zero}) == Flt{});

assert(_Unsigned128{one} == _Unsigned128{1});
assert(_Unsigned128{one} == 1);
assert(static_cast<Flt>(_Unsigned128{one}) == Flt{1.0});

assert(_Signed128{zero} == _Signed128{});
assert(_Signed128{zero} == 0);
assert(static_cast<Flt>(_Signed128{zero}) == Flt{});

assert(_Signed128{one} == _Signed128{1});
assert(_Signed128{one} == 1);
assert(static_cast<Flt>(_Signed128{one}) == Flt{1.0});

assert(_Signed128{neg_one} == _Signed128{-1});
assert(_Signed128{neg_one} == -1);
assert(static_cast<Flt>(_Signed128{neg_one}) == Flt{-1.0});

return true;
}

constexpr bool test_floating_point() {
assert(test_one_floating_point<float>());
assert(test_one_floating_point<double>());
assert(test_one_floating_point<long double>());

return true;
}

int main() {
test_unsigned();
STATIC_ASSERT(test_unsigned());
test_signed();
STATIC_ASSERT(test_signed());
test_cross();
STATIC_ASSERT(test_cross());
test_floating_point();
STATIC_ASSERT(test_floating_point());
}