Skip to content

Commit

Permalink
✨ Improved additions to to_underlying
Browse files Browse the repository at this point in the history
— ✨ New basic concepts for iterator and friends
  • Loading branch information
ThePhD committed Aug 1, 2022
1 parent 67c320b commit 063e538
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 8 deletions.
71 changes: 70 additions & 1 deletion include/ztd/idk/to_underlying.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,83 @@ namespace ztd {
template <typename _MaybeEnum>
inline constexpr auto any_to_underlying(_MaybeEnum __value) noexcept {
if constexpr (::std::is_enum_v<_MaybeEnum>) {
return to_underlying(__value);
return ::ztd::to_underlying(__value);
}
else {
static_assert(::std::is_integral_v<_MaybeEnum>);
return __value;
}
}

template <typename _Integralish>
inline constexpr auto any_enum_or_char_to_underlying(_Integralish __val) noexcept {
if constexpr (::std::is_same_v<_Integralish, char>) {
using _UTy = ::std::conditional_t<::std::is_signed_v<char>, ::std::int_least8_t, ::std::uint_least8_t>;
return static_cast<_UTy>(__val);
}
else if constexpr (::std::is_same_v<_Integralish, wchar_t>) {
if constexpr (::std::is_signed_v<wchar_t>) {
if constexpr (sizeof(wchar_t) <= sizeof(::std::uint_least8_t)) {
using _UTy = ::std::conditional_t<::std::is_signed_v<wchar_t>, ::std::int_least8_t,
::std::uint_least8_t>;
return static_cast<_UTy>(__val);
}
else if constexpr (sizeof(wchar_t) <= sizeof(::std::uint_least16_t)) {
using _UTy = ::std::conditional_t<::std::is_signed_v<wchar_t>, ::std::int_least16_t,
::std::uint_least16_t>;
return static_cast<_UTy>(__val);
}
else if constexpr (sizeof(wchar_t) <= sizeof(::std::uint_least32_t)) {
using _UTy = ::std::conditional_t<::std::is_signed_v<wchar_t>, ::std::int_least32_t,
::std::uint_least32_t>;
return static_cast<_UTy>(__val);
}
else {
using _UTy = ::std::conditional_t<::std::is_signed_v<wchar_t>, ::std::int_least64_t,
::std::uint_least64_t>;
return static_cast<_UTy>(__val);
}
}
else {
return static_cast<uint_least8_t>(__val);
}
}
#if ZTD_IS_ON(ZTD_NATIVE_CHAR8_T)
else if constexpr (::std::is_same_v<_Integralish, char8_t>) {
return static_cast<unsigned char>(__val);
}
#endif // char8_t
else if constexpr (::std::is_same_v<_Integralish, char16_t>) {
return static_cast<uint_least16_t>(__val);
}
else if constexpr (::std::is_same_v<_Integralish, char32_t>) {
return static_cast<uint_least32_t>(__val);
}
else {
return any_to_underlying(__val);
}
}

namespace __idk_detail {

template <typename _Enumish, typename = void>
struct __any_to_underlying {
using type = _Enumish;
};

template <typename _Enumish>
struct __any_to_underlying<_Enumish, ::std::enable_if_t<::std::is_enum_v<_Enumish>>> {
using type = ::std::underlying_type_t<_Enumish>;
};
} // namespace __idk_detail

template <typename _Enumish>
using any_to_underlying_t = typename ::ztd::__idk_detail::__any_to_underlying<_Enumish>::type;

template <typename _Enumish>
using any_enum_or_char_to_underlying_t
= decltype(::ztd::any_enum_or_char_to_underlying(::std::declval<_Enumish>()));

ZTD_IDK_INLINE_ABI_NAMESPACE_CLOSE_I_
} // namespace ztd

Expand Down
5 changes: 4 additions & 1 deletion include/ztd/ranges/iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,11 @@ namespace ztd { namespace ranges {
template <typename _It>
using iterator_concept_t = __rng_detail::__iterator_concept_or_fallback_t<_It>;

template <typename _Tag, typename _ActualTag>
inline constexpr bool is_concept_or_better_v = ::std::is_base_of_v<_Tag, _ActualTag>;

template <typename _Tag, typename _It>
inline constexpr bool is_iterator_concept_or_better_v = ::std::is_base_of_v<_Tag, iterator_concept_t<_It>>;
inline constexpr bool is_iterator_concept_or_better_v = is_concept_or_better_v<_Tag, iterator_concept_t<_It>>;

template <typename _It>
inline constexpr bool is_iterator_random_access_iterator_v
Expand Down
15 changes: 9 additions & 6 deletions include/ztd/ranges/word_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <ztd/idk/endian.hpp>
#include <ztd/idk/reference_wrapper.hpp>
#include <ztd/idk/detail/math.hpp>
#include <ztd/idk/to_underlying.hpp>

#include <cstddef>
#include <limits>
Expand Down Expand Up @@ -147,8 +148,9 @@ namespace ztd { namespace ranges {
using value_type = _Word;

private:
using __underlying_base_value_type = decltype(any_to_underlying(__base_value_type {}));
using __underlying_value_type = decltype(any_to_underlying(value_type {}));
using __underlying_base_value_type
= decltype(::ztd::any_enum_or_char_to_underlying(__base_value_type {}));
using __underlying_value_type = decltype(::ztd::any_enum_or_char_to_underlying(value_type {}));
inline static constexpr __underlying_value_type __base_bits_per_element
= static_cast<__underlying_value_type>(sizeof(__underlying_base_value_type) * CHAR_BIT);
inline static constexpr __underlying_value_type __base_lowest_bit_mask
Expand Down Expand Up @@ -184,8 +186,9 @@ namespace ztd { namespace ranges {
{
// God's given, handwritten, bit-splittin'
// one-way """memcpy""". 😵
__underlying_value_type __bit_value = any_to_underlying(static_cast<value_type>(__val));
auto __write_storage_it = __write_storage + 0;
__underlying_value_type __bit_value
= any_enum_or_char_to_undeerlying(static_cast<value_type>(__val));
auto __write_storage_it = __write_storage + 0;
for (::std::size_t __index = 0; __index < __base_values_per_word; ++__index) {
__underlying_value_type __bit_position
= static_cast<__underlying_value_type>(__index * __base_bits_per_element);
Expand Down Expand Up @@ -268,8 +271,8 @@ namespace ztd { namespace ranges {
// God's given, handwritten, bit-fusin'
// one-way """memcpy""". 😵
for (::std::size_t __index = 0; __index < __base_values_per_word; ++__index) {
__underlying_value_type __bit_value
= static_cast<__underlying_value_type>(any_to_underlying(__read_storage[__index]));
__underlying_value_type __bit_value = static_cast<__underlying_value_type>(
::ztd::any_enum_or_char_to_underlying(__read_storage[__index]));
__underlying_value_type __bit_position
= static_cast<__underlying_value_type>(__index * __base_bits_per_element);
__underlying_value_type __shifted_bit_value = (__bit_value << __bit_position);
Expand Down
10 changes: 10 additions & 0 deletions include/ztd/version/detail/version.c++.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,16 @@
#define ZTD_STD_LIBRARY_STRING_CONTAINS_I_ ZTD_DEFAULT_OFF
#endif

#if defined(__cpp_lib_bitops)
#if __cpp_lib_bitops != 0
#define ZTD_STD_LIBRARY_BIT_I_ ZTD_ON
#else
#define ZTD_STD_LIBRARY_BIT_I_ ZTD_OFF
#endif
#else
#define ZTD_STD_LIBRARY_BIT_I_ ZTD_DEFAULT_OFF
#endif

#if defined(ZTD_STD_LIBRARY_SPAN)
#if (ZTD_STD_LIBRARY_SPAN != 0)
#define ZTD_STD_LIBRARY_SPAN_I_ ZTD_ON
Expand Down
21 changes: 21 additions & 0 deletions include/ztd/version/detail/version.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,27 @@

#define ZTD_INTERMEDIATE_BUFFER_SUGGESTED_SIZE_I_(...) (ZTD_INTERMEDIATE_BUFFER_SUGGESTED_BYTE_SIZE_I_ / sizeof(__VA_ARGS__))

#if defined(ZTD_VCXX_CONSTEXPR_BIT_INTRINSICS)
#if (ZTD_VCXX_CONSTEXPR_BIT_INTRINSICS != 0)
#define ZTD_VCXX_CONSTEXPR_BIT_INTRINSICS_I_ ZTD_ON
#else
#define ZTD_VCXX_CONSTEXPR_BIT_INTRINSICS_I_ ZTD_OFF
#endif
#else
#define ZTD_VCXX_CONSTEXPR_BIT_INTRINSICS_I_ ZTD_DEFAULT_OFF
#endif

#if defined(ZTD_NONPORTABLE_MSVC_INTRINSICS)
#if (ZTD_NONPORTABLE_MSVC_INTRINSICS != 0)
#define ZTD_NONPORTABLE_MSVC_INTRINSICS_I_ ZTD_ON
#else
#define ZTD_NONPORTABLE_MSVC_INTRINSICS_I_ ZTD_OFF
#endif
#else
#define ZTD_NONPORTABLE_MSVC_INTRINSICS_I_ ZTD_DEFAULT_OFF
#endif


// Cache line size: number of bytes
#if defined(ZTD_L1_CACHE_LINE_SIZE)
#define ZTD_L1_CACHE_LINE_SIZE_USER_DEFINED_I_ ZTD_ON
Expand Down

0 comments on commit 063e538

Please sign in to comment.