Skip to content

Commit bbb2b81

Browse files
authored
Added C++20 <bit>, added to <type_traits>, fixed __NOEXCEPT in C++98 (#536)
1 parent 4f00ea9 commit bbb2b81

File tree

4 files changed

+120
-2
lines changed

4 files changed

+120
-2
lines changed

src/libc/include/cdefs.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@
1212
#ifndef __cplusplus
1313
# define __BEGIN_DECLS
1414
# define __END_DECLS
15-
# define __NOEXCEPT __attribute__((__nothrow__, __leaf__))
1615
# define __IGNORE(expr) ((void)(expr))
1716
#else /* __cplusplus */
1817
# define __BEGIN_DECLS extern "C" {
1918
# define __END_DECLS }
20-
# define __NOEXCEPT noexcept
2119
# define __IGNORE(expr) (static_cast<void>(expr))
2220
#endif /* __cplusplus */
2321

22+
#if defined(__cplusplus) && __cplusplus >= 201103L
23+
# define __NOEXCEPT noexcept
24+
#else /* __cplusplus */
25+
# define __NOEXCEPT __attribute__((__nothrow__, __leaf__))
26+
#endif /* __cplusplus */
27+
2428
#ifndef NULL
2529
# ifndef __cplusplus
2630
# define NULL ((void *)0)

src/libcxx/include/bit

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// -*- C++ -*-
2+
#ifndef _EZCXX_BIT
3+
#define _EZCXX_BIT
4+
5+
#include <cstring> // for memcpy
6+
#include <type_traits>
7+
8+
#pragma clang system_header
9+
10+
namespace std {
11+
12+
enum class endian {
13+
little = __ORDER_LITTLE_ENDIAN__,
14+
big = __ORDER_BIG_ENDIAN__,
15+
native = __BYTE_ORDER__
16+
}; // endian
17+
18+
template<class _To, class _From>
19+
std::enable_if_t<
20+
sizeof(_To) == sizeof(_From) &&
21+
std::is_trivially_copyable_v<_From> &&
22+
std::is_trivially_copyable_v<_To>, _To>
23+
constexpr bit_cast(const _From& src) noexcept {
24+
static_assert(std::is_trivially_constructible_v<_To>,
25+
"destination type is required to be trivially constructible");
26+
_To dst;
27+
std::memcpy(&dst, &src, sizeof(_To));
28+
return dst;
29+
}
30+
31+
} // namespace std
32+
33+
#endif // _EZCXX_BIT

src/libcxx/include/type_traits

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ template<class _Tp> inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::
120120
template<class _Tp> using is_fundamental = disjunction<is_void<_Tp>, is_null_pointer<_Tp>, is_arithmetic<_Tp>>;
121121
template<class _Tp> inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
122122

123+
template<class _Tp> struct is_compound : std::integral_constant<bool, !std::is_fundamental<_Tp>::value> {};
124+
template<class _Tp> inline constexpr bool is_compound_v = is_compound<_Tp>::value;
125+
123126
template<class _Tp, bool = is_arithmetic<_Tp>::value> struct __is_signed : integral_constant<bool, _Tp(-1) < _Tp(0)> {};
124127
template<class _Tp> struct __is_signed<_Tp, false> : false_type {};
125128
template<class _Tp> struct is_signed : __is_signed<_Tp>::type {};
@@ -150,6 +153,41 @@ template<class _Tp> inline constexpr bool is_class_v = __is_class(_Tp);
150153
template<class _Tp> using is_class = bool_constant<is_class_v<_Tp>>;
151154
#endif
152155

156+
#if __has_feature(is_trivial)
157+
template<class _Tp> inline constexpr bool is_trivial_v = __is_trivial(_Tp);
158+
template<class _Tp> using is_trivial = bool_constant<is_trivial_v<_Tp>>;
159+
#endif
160+
161+
#if __has_feature(is_trivially_copyable)
162+
template<class _Tp> inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
163+
template<class _Tp> using is_trivially_copyable = bool_constant<is_trivially_copyable_v<_Tp>>;
164+
#endif
165+
166+
#if __has_feature(is_standard_layout)
167+
template<class _Tp> inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
168+
template<class _Tp> using is_standard_layout = bool_constant<is_standard_layout_v<_Tp>>;
169+
#endif
170+
171+
#if __has_feature(is_pod)
172+
template<class _Tp> inline constexpr bool is_pod_v = __is_pod(_Tp);
173+
template<class _Tp> using is_pod = bool_constant<is_pod_v<_Tp>>;
174+
#endif
175+
176+
#if __has_feature(is_empty)
177+
template<class _Tp> inline constexpr bool is_empty_v = __is_empty(_Tp);
178+
template<class _Tp> using is_empty = bool_constant<is_empty_v<_Tp>>;
179+
#endif
180+
181+
#if __has_feature(is_polymorphic)
182+
template<class _Tp> inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
183+
template<class _Tp> using is_polymorphic = bool_constant<is_polymorphic_v<_Tp>>;
184+
#endif
185+
186+
#if __has_feature(is_abstract)
187+
template<class _Tp> inline constexpr bool is_abstract_v = __is_abstract(_Tp);
188+
template<class _Tp> using is_abstract = bool_constant<is_abstract_v<_Tp>>;
189+
#endif
190+
153191
template<class> struct is_pointer : false_type {};
154192
template<class _Tp> struct is_pointer<_Tp*> : true_type {};
155193
template<class _Tp> inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
@@ -183,6 +221,23 @@ template<class _Tp, class _Cp> struct __member_object_pointer<_Tp _Cp::*> : nega
183221
template<class _Tp> using is_member_object_pointer = __member_object_pointer<remove_cv_t<_Tp>>;
184222
template<class _Tp> inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
185223

224+
template <class _Tp> struct is_scalar : public integral_constant<bool,
225+
is_arithmetic<_Tp>::value ||
226+
is_member_pointer<_Tp>::value ||
227+
is_pointer<_Tp>::value ||
228+
is_null_pointer<_Tp>::value ||
229+
is_enum<_Tp>::value
230+
> {};
231+
template <class _Tp> inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
232+
233+
template <class _Tp> struct is_object : integral_constant<bool,
234+
is_scalar<_Tp>::value ||
235+
is_array<_Tp>::value ||
236+
is_union<_Tp>::value ||
237+
is_class<_Tp>::value
238+
> {};
239+
template <class _Tp> inline constexpr bool is_object_v = is_object<_Tp>::value;
240+
186241
// const/volatile addition traits:
187242
template<class _Tp> using add_const = conditional<disjunction_v<is_reference<_Tp>, is_function<_Tp>, is_const<_Tp>>,
188243
_Tp, _Tp const>;

src/libcxx/type_traits.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,32 @@ C((is_nothrow_move_constructible<test_class>::value));
481481
C((is_nothrow_move_constructible_v<test_union>));
482482
C((!is_nothrow_move_constructible<int()>::value));
483483

484+
// test is_signed
485+
C((std::is_signed_v<void> == false));
486+
C((std::is_signed_v<void*> == false));
487+
C((std::is_signed_v<int> == true));
488+
C((std::is_signed_v<int*> == false));
489+
C((std::is_signed_v<unsigned int> == false));
490+
C((std::is_signed_v<unsigned int*> == false));
491+
C((std::is_signed_v<float> == true));
492+
C((std::is_signed_v<double> == true));
493+
C((std::is_signed_v< signed __int48> == true));
494+
C((std::is_signed_v<unsigned __int48> == false));
495+
C((std::is_signed_v<bool> == false));
496+
497+
// test is_unsigned
498+
C((std::is_unsigned_v<void> == false));
499+
C((std::is_unsigned_v<void*> == false));
500+
C((std::is_unsigned_v<int> == false));
501+
C((std::is_unsigned_v<int*> == false));
502+
C((std::is_unsigned_v<unsigned int> == true));
503+
C((std::is_unsigned_v<unsigned int*> == false));
504+
C((std::is_unsigned_v<float> == false));
505+
C((std::is_unsigned_v<double> == false));
506+
C((std::is_unsigned_v< signed __int48> == false));
507+
C((std::is_unsigned_v<unsigned __int48> == true));
508+
C((std::is_unsigned_v<bool> == true));
509+
484510
#undef C
485511

486512
} // namespace

0 commit comments

Comments
 (0)