Skip to content

Commit 91ee5a1

Browse files
committed
Implemented more of <type_traits>, and patched errors when compiling type_traits/utility in C++11
1 parent 0a76fd8 commit 91ee5a1

File tree

4 files changed

+107
-3
lines changed

4 files changed

+107
-3
lines changed

src/libcxx/include/type_traits

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ template<class _Tp> inline constexpr bool is_abstract_v = __is_abstract(_Tp);
188188
template<class _Tp> using is_abstract = bool_constant<is_abstract_v<_Tp>>;
189189
#endif
190190

191+
#if __has_feature(is_final)
192+
template<class _Tp> inline constexpr bool is_final_v = __is_final(_Tp);
193+
template<class _Tp> using is_final = bool_constant<is_final_v<_Tp>>;
194+
#endif
195+
191196
template<class> struct is_pointer : false_type {};
192197
template<class _Tp> struct is_pointer<_Tp*> : true_type {};
193198
template<class _Tp> inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
@@ -263,6 +268,10 @@ template<class _Tp> struct remove_reference<_Tp&> : type_identity<_Tp> {};
263268
template<class _Tp> struct remove_reference<_Tp&&> : type_identity<_Tp> {};
264269
template<class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
265270

271+
template <class _Tp> using __remove_cvref_t = typename remove_cv<typename remove_reference<_Tp>::type>::type;
272+
template <class _Tp> struct remove_cvref { using type = __remove_cvref_t<_Tp>; };
273+
template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
274+
266275
template<class _Tp> auto __add_pointer(int) -> type_identity<_Tp*>;
267276
template<class _Tp> auto __add_pointer(...) -> type_identity<_Tp>;
268277
template<class _Tp> using add_pointer = decltype(__add_pointer<_Tp>(0));
@@ -278,6 +287,60 @@ template<class _Tp> auto __add_rvalue_reference(...) -> type_identity<_Tp>;
278287
template<class _Tp> using add_rvalue_reference = decltype(__add_rvalue_reference<_Tp>(0));
279288
template<class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
280289

290+
// alignment_of:
291+
template <class _Tp> struct alignment_of
292+
: public integral_constant<size_t, alignof(_Tp)> {};
293+
template <class _Tp> inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
294+
295+
// rank/extent:
296+
template <class _Tp> struct rank
297+
: public integral_constant<size_t, 0> {};
298+
template <class _Tp> struct rank<_Tp[]>
299+
: public integral_constant<size_t, rank<_Tp>::value + 1> {};
300+
template <class _Tp, size_t _Np> struct rank<_Tp[_Np]>
301+
: public integral_constant<size_t, rank<_Tp>::value + 1> {};
302+
template <class _Tp> inline constexpr size_t rank_v = rank<_Tp>::value;
303+
304+
template <class _Tp, unsigned _Ip = 0> struct extent
305+
: public integral_constant<size_t, 0> {};
306+
template <class _Tp> struct extent<_Tp[], 0>
307+
: public integral_constant<size_t, 0> {};
308+
template <class _Tp, unsigned _Ip> struct extent<_Tp[], _Ip>
309+
: public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
310+
template <class _Tp, size_t _Np> struct extent<_Tp[_Np], 0>
311+
: public integral_constant<size_t, _Np> {};
312+
template <class _Tp, size_t _Np, unsigned _Ip> struct extent<_Tp[_Np], _Ip>
313+
: public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
314+
template <class _Tp, unsigned _Ip = 0> inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
315+
316+
template<class _Tp> struct remove_extent { typedef _Tp type; };
317+
template<class _Tp> struct remove_extent<_Tp[]> { typedef _Tp type; };
318+
template<class _Tp, size_t _Np> struct remove_extent<_Tp[_Np]> { typedef _Tp type; };
319+
template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;
320+
321+
template <class _Tp> struct remove_all_extents { typedef _Tp type; };
322+
template <class _Tp> struct remove_all_extents<_Tp[]> { typedef typename remove_all_extents<_Tp>::type type; };
323+
template <class _Tp, size_t _Np> struct remove_all_extents<_Tp[_Np]> { typedef typename remove_all_extents<_Tp>::type type; };
324+
template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
325+
326+
// decay:
327+
template<class _Tp>
328+
struct decay {
329+
private:
330+
typedef typename std::remove_reference<_Tp>::type _Up;
331+
public:
332+
typedef typename std::conditional<
333+
std::is_array<_Up>::value,
334+
typename std::add_pointer<typename std::remove_extent<_Up>::type>::type,
335+
typename std::conditional<
336+
std::is_function<_Up>::value,
337+
typename std::add_pointer<_Up>::type,
338+
typename std::remove_cv<_Up>::type
339+
>::type
340+
>::type type;
341+
};
342+
template <class _Tp> using decay_t = typename decay<_Tp>::type;
343+
281344
// <utility> functions:
282345
template<class _Tp> add_rvalue_reference_t<_Tp> declval() noexcept;
283346

@@ -356,16 +419,20 @@ template<class _Tp> using has_virtual_destructor = bool_constant<has_virtual_des
356419
#endif
357420

358421
// more <utility> functions:
422+
#if __cplusplus > 201103L
359423
template<class _Tp> _EZCXX_INLINE constexpr auto move(_Tp&& __value) noexcept {
360424
return static_cast<remove_reference_t<_Tp>&&>(__value);
361425
}
426+
#endif // __cplusplus > 201103L
362427

428+
#if __cplusplus > 201103L
363429
template<class _Tp> _EZCXX_INLINE constexpr enable_if_t<is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp>>
364430
swap(_Tp& __lhs, _Tp& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) {
365431
_Tp __temp(move(__lhs));
366432
__lhs = move(__rhs);
367433
__rhs = move(__temp);
368434
}
435+
#endif // __cplusplus > 201103L
369436

370437
// swappable classification traits:
371438
template<class _Lp, class _Rp> auto __swappable(int) -> __require<decltype(swap(declval<_Lp>(), declval<_Rp>()))>;

src/libcxx/include/utility

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ template<class _Tp> _EZCXX_INLINE constexpr conditional_t<!is_nothrow_move_const
2828
is_copy_constructible_v<_Tp>, _Tp const&, _Tp&&>
2929
move_if_noexcept(_Tp& __value) noexcept { return move(__value); }
3030

31+
#if __cplusplus > 201103L
3132
template<class _Tp> _EZCXX_INLINE constexpr std::add_const_t<_Tp>& as_const(_Tp& __value) noexcept { return __value; }
3233
template<class _Tp> _EZCXX_INLINE constexpr auto as_const(_Tp const&& __value) noexcept = delete;
34+
#endif // __cplusplus > 201103L
3335

3436
} // namespace std
3537

src/libcxx/include/version

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// # define __cpp_lib_generic_associative_lookup 201304L
1212
// # define __cpp_lib_integer_sequence 201304L
1313
# define __cpp_lib_integral_constant_callable 201304L
14-
// # define __cpp_lib_is_final 201402L
14+
# define __cpp_lib_is_final 201402L
1515
# define __cpp_lib_is_null_pointer 201309L
1616
// # define __cpp_lib_make_reverse_iterator 201402L
1717
// # define __cpp_lib_make_unique 201304L
@@ -135,7 +135,7 @@
135135
// # define __cpp_lib_move_iterator_concept 202207L
136136
// # define __cpp_lib_polymorphic_allocator 201902L
137137
// # define __cpp_lib_ranges 202110L
138-
// # define __cpp_lib_remove_cvref 201711L
138+
# define __cpp_lib_remove_cvref 201711L
139139
// # define __cpp_lib_semaphore 201907L
140140
// # undef __cpp_lib_shared_ptr_arrays
141141
// # define __cpp_lib_shared_ptr_arrays 201707L
@@ -151,7 +151,7 @@
151151
// # define __cpp_lib_three_way_comparison 201907L
152152
// # define __cpp_lib_to_address 201711L
153153
// # define __cpp_lib_to_array 201907L
154-
// # define __cpp_lib_type_identity 201806L
154+
# define __cpp_lib_type_identity 201806L
155155
// # define __cpp_lib_unwrap_ref 201811L
156156
#endif // __cplusplus >= 202002L
157157

src/libcxx/type_traits.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,41 @@ C((std::is_unsigned_v< signed __int48> == false));
507507
C((std::is_unsigned_v<unsigned __int48> == true));
508508
C((std::is_unsigned_v<bool> == true));
509509

510+
// test rank
511+
C((std::rank<int>{} == 0));
512+
C((std::rank<int[5]>{} == 1));
513+
C((std::rank<int[5][5]>{} == 2));
514+
C((std::rank<int[][5][5]>{} == 3));
515+
516+
// test extent
517+
C((std::extent_v<int[3]> == 3));
518+
C((std::extent_v<int[3], 0> == 3));
519+
C((std::extent_v<int[3][4], 0> == 3));
520+
C((std::extent_v<int[3][4], 1> == 4));
521+
C((std::extent_v<int[3][4], 2> == 0));
522+
C((std::extent_v<int[]> == 0));
523+
524+
// test remove_cvref
525+
C((std::is_same_v<std::remove_cvref_t<int>, int>));
526+
C((std::is_same_v<std::remove_cvref_t<int&>, int>));
527+
C((std::is_same_v<std::remove_cvref_t<int&&>, int>));
528+
C((std::is_same_v<std::remove_cvref_t<const int&>, int>));
529+
C((std::is_same_v<std::remove_cvref_t<const int[2]>, int[2]>));
530+
C((std::is_same_v<std::remove_cvref_t<const int(&)[2]>, int[2]>));
531+
C((std::is_same_v<std::remove_cvref_t<int(int)>, int(int)>));
532+
533+
// test decay
534+
C(( std::is_same_v<std::decay_t<int >, int >));
535+
C((!std::is_same_v<std::decay_t<int >, float >));
536+
C(( std::is_same_v<std::decay_t<int& >, int >));
537+
C(( std::is_same_v<std::decay_t<int&& >, int >));
538+
C(( std::is_same_v<std::decay_t<const int&>, int >));
539+
C(( std::is_same_v<std::decay_t<int[2] >, int* >));
540+
C((!std::is_same_v<std::decay_t<int[4][2] >, int* >));
541+
C((!std::is_same_v<std::decay_t<int[4][2] >, int** >));
542+
C(( std::is_same_v<std::decay_t<int[4][2] >, int(*)[2] >));
543+
C(( std::is_same_v<std::decay_t<int(int) >, int(*)(int)>));
544+
510545
#undef C
511546

512547
} // namespace

0 commit comments

Comments
 (0)