Skip to content

Commit

Permalink
Added C++20 <bit>, added to <type_traits>, fixed __NOEXCEPT in C++98 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ZERICO2005 authored Feb 2, 2025
1 parent 4f00ea9 commit bbb2b81
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/libc/include/cdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@
#ifndef __cplusplus
# define __BEGIN_DECLS
# define __END_DECLS
# define __NOEXCEPT __attribute__((__nothrow__, __leaf__))
# define __IGNORE(expr) ((void)(expr))
#else /* __cplusplus */
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# define __NOEXCEPT noexcept
# define __IGNORE(expr) (static_cast<void>(expr))
#endif /* __cplusplus */

#if defined(__cplusplus) && __cplusplus >= 201103L
# define __NOEXCEPT noexcept
#else /* __cplusplus */
# define __NOEXCEPT __attribute__((__nothrow__, __leaf__))
#endif /* __cplusplus */

#ifndef NULL
# ifndef __cplusplus
# define NULL ((void *)0)
Expand Down
33 changes: 33 additions & 0 deletions src/libcxx/include/bit
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// -*- C++ -*-
#ifndef _EZCXX_BIT
#define _EZCXX_BIT

#include <cstring> // for memcpy
#include <type_traits>

#pragma clang system_header

namespace std {

enum class endian {
little = __ORDER_LITTLE_ENDIAN__,
big = __ORDER_BIG_ENDIAN__,
native = __BYTE_ORDER__
}; // endian

template<class _To, class _From>
std::enable_if_t<
sizeof(_To) == sizeof(_From) &&
std::is_trivially_copyable_v<_From> &&
std::is_trivially_copyable_v<_To>, _To>
constexpr bit_cast(const _From& src) noexcept {
static_assert(std::is_trivially_constructible_v<_To>,
"destination type is required to be trivially constructible");
_To dst;
std::memcpy(&dst, &src, sizeof(_To));
return dst;
}

} // namespace std

#endif // _EZCXX_BIT
55 changes: 55 additions & 0 deletions src/libcxx/include/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ template<class _Tp> inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::
template<class _Tp> using is_fundamental = disjunction<is_void<_Tp>, is_null_pointer<_Tp>, is_arithmetic<_Tp>>;
template<class _Tp> inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;

template<class _Tp> struct is_compound : std::integral_constant<bool, !std::is_fundamental<_Tp>::value> {};
template<class _Tp> inline constexpr bool is_compound_v = is_compound<_Tp>::value;

template<class _Tp, bool = is_arithmetic<_Tp>::value> struct __is_signed : integral_constant<bool, _Tp(-1) < _Tp(0)> {};
template<class _Tp> struct __is_signed<_Tp, false> : false_type {};
template<class _Tp> struct is_signed : __is_signed<_Tp>::type {};
Expand Down Expand Up @@ -150,6 +153,41 @@ template<class _Tp> inline constexpr bool is_class_v = __is_class(_Tp);
template<class _Tp> using is_class = bool_constant<is_class_v<_Tp>>;
#endif

#if __has_feature(is_trivial)
template<class _Tp> inline constexpr bool is_trivial_v = __is_trivial(_Tp);
template<class _Tp> using is_trivial = bool_constant<is_trivial_v<_Tp>>;
#endif

#if __has_feature(is_trivially_copyable)
template<class _Tp> inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
template<class _Tp> using is_trivially_copyable = bool_constant<is_trivially_copyable_v<_Tp>>;
#endif

#if __has_feature(is_standard_layout)
template<class _Tp> inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
template<class _Tp> using is_standard_layout = bool_constant<is_standard_layout_v<_Tp>>;
#endif

#if __has_feature(is_pod)
template<class _Tp> inline constexpr bool is_pod_v = __is_pod(_Tp);
template<class _Tp> using is_pod = bool_constant<is_pod_v<_Tp>>;
#endif

#if __has_feature(is_empty)
template<class _Tp> inline constexpr bool is_empty_v = __is_empty(_Tp);
template<class _Tp> using is_empty = bool_constant<is_empty_v<_Tp>>;
#endif

#if __has_feature(is_polymorphic)
template<class _Tp> inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
template<class _Tp> using is_polymorphic = bool_constant<is_polymorphic_v<_Tp>>;
#endif

#if __has_feature(is_abstract)
template<class _Tp> inline constexpr bool is_abstract_v = __is_abstract(_Tp);
template<class _Tp> using is_abstract = bool_constant<is_abstract_v<_Tp>>;
#endif

template<class> struct is_pointer : false_type {};
template<class _Tp> struct is_pointer<_Tp*> : true_type {};
template<class _Tp> inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
Expand Down Expand Up @@ -183,6 +221,23 @@ template<class _Tp, class _Cp> struct __member_object_pointer<_Tp _Cp::*> : nega
template<class _Tp> using is_member_object_pointer = __member_object_pointer<remove_cv_t<_Tp>>;
template<class _Tp> inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;

template <class _Tp> struct is_scalar : public integral_constant<bool,
is_arithmetic<_Tp>::value ||
is_member_pointer<_Tp>::value ||
is_pointer<_Tp>::value ||
is_null_pointer<_Tp>::value ||
is_enum<_Tp>::value
> {};
template <class _Tp> inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;

template <class _Tp> struct is_object : integral_constant<bool,
is_scalar<_Tp>::value ||
is_array<_Tp>::value ||
is_union<_Tp>::value ||
is_class<_Tp>::value
> {};
template <class _Tp> inline constexpr bool is_object_v = is_object<_Tp>::value;

// const/volatile addition traits:
template<class _Tp> using add_const = conditional<disjunction_v<is_reference<_Tp>, is_function<_Tp>, is_const<_Tp>>,
_Tp, _Tp const>;
Expand Down
26 changes: 26 additions & 0 deletions src/libcxx/type_traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,32 @@ C((is_nothrow_move_constructible<test_class>::value));
C((is_nothrow_move_constructible_v<test_union>));
C((!is_nothrow_move_constructible<int()>::value));

// test is_signed
C((std::is_signed_v<void> == false));
C((std::is_signed_v<void*> == false));
C((std::is_signed_v<int> == true));
C((std::is_signed_v<int*> == false));
C((std::is_signed_v<unsigned int> == false));
C((std::is_signed_v<unsigned int*> == false));
C((std::is_signed_v<float> == true));
C((std::is_signed_v<double> == true));
C((std::is_signed_v< signed __int48> == true));
C((std::is_signed_v<unsigned __int48> == false));
C((std::is_signed_v<bool> == false));

// test is_unsigned
C((std::is_unsigned_v<void> == false));
C((std::is_unsigned_v<void*> == false));
C((std::is_unsigned_v<int> == false));
C((std::is_unsigned_v<int*> == false));
C((std::is_unsigned_v<unsigned int> == true));
C((std::is_unsigned_v<unsigned int*> == false));
C((std::is_unsigned_v<float> == false));
C((std::is_unsigned_v<double> == false));
C((std::is_unsigned_v< signed __int48> == false));
C((std::is_unsigned_v<unsigned __int48> == true));
C((std::is_unsigned_v<bool> == true));

#undef C

} // namespace
Expand Down

0 comments on commit bbb2b81

Please sign in to comment.