Skip to content

Commit

Permalink
[libc++] Granularize some more type_traits
Browse files Browse the repository at this point in the history
Reviewed By: ldionne, #libc

Spies: libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D128948
  • Loading branch information
philnik777 committed Jul 24, 2022
1 parent ea29810 commit b7aa9c4
Show file tree
Hide file tree
Showing 31 changed files with 1,333 additions and 792 deletions.
19 changes: 19 additions & 0 deletions libcxx/include/CMakeLists.txt
Expand Up @@ -505,10 +505,16 @@ set(files
__type_traits/add_pointer.h
__type_traits/add_rvalue_reference.h
__type_traits/add_volatile.h
__type_traits/aligned_storage.h
__type_traits/aligned_union.h
__type_traits/alignment_of.h
__type_traits/apply_cv.h
__type_traits/common_reference.h
__type_traits/common_type.h
__type_traits/conditional.h
__type_traits/conjunction.h
__type_traits/copy_cv.h
__type_traits/copy_cvref.h
__type_traits/decay.h
__type_traits/disjunction.h
__type_traits/enable_if.h
Expand Down Expand Up @@ -550,6 +556,7 @@ set(files
__type_traits/is_move_constructible.h
__type_traits/is_nothrow_assignable.h
__type_traits/is_nothrow_constructible.h
__type_traits/is_nothrow_convertible.h
__type_traits/is_nothrow_copy_assignable.h
__type_traits/is_nothrow_copy_constructible.h
__type_traits/is_nothrow_default_constructible.h
Expand All @@ -561,13 +568,15 @@ set(files
__type_traits/is_pod.h
__type_traits/is_pointer.h
__type_traits/is_polymorphic.h
__type_traits/is_primary_template.h
__type_traits/is_reference.h
__type_traits/is_reference_wrapper.h
__type_traits/is_referenceable.h
__type_traits/is_same.h
__type_traits/is_scalar.h
__type_traits/is_scoped_enum.h
__type_traits/is_signed.h
__type_traits/is_signed_integer.h
__type_traits/is_standard_layout.h
__type_traits/is_trivial.h
__type_traits/is_trivially_assignable.h
Expand All @@ -582,18 +591,28 @@ set(files
__type_traits/is_unbounded_array.h
__type_traits/is_union.h
__type_traits/is_unsigned.h
__type_traits/is_unsigned_integer.h
__type_traits/is_valid_expansion.h
__type_traits/is_void.h
__type_traits/is_volatile.h
__type_traits/lazy.h
__type_traits/make_32_64_or_128_bit.h
__type_traits/make_signed.h
__type_traits/make_unsigned.h
__type_traits/nat.h
__type_traits/negation.h
__type_traits/promote.h
__type_traits/rank.h
__type_traits/remove_all_extents.h
__type_traits/remove_const.h
__type_traits/remove_cv.h
__type_traits/remove_cvref.h
__type_traits/remove_extent.h
__type_traits/remove_pointer.h
__type_traits/remove_reference.h
__type_traits/remove_volatile.h
__type_traits/type_identity.h
__type_traits/type_list.h
__type_traits/underlying_type.h
__type_traits/void_t.h
__undef_macros
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__concepts/arithmetic.h
Expand Up @@ -10,6 +10,8 @@
#define _LIBCPP___CONCEPTS_ARITHMETIC_H

#include <__config>
#include <__type_traits/is_signed_integer.h>
#include <__type_traits/is_unsigned_integer.h>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__format/formatter_integer.h
Expand Up @@ -19,6 +19,7 @@
#include <__format/formatter_integral.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
#include <__type_traits/make_32_64_or_128_bit.h>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down
11 changes: 1 addition & 10 deletions libcxx/include/__functional/invoke.h
Expand Up @@ -24,6 +24,7 @@
#include <__type_traits/is_reference_wrapper.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_void.h>
#include <__type_traits/nat.h>
#include <__type_traits/remove_cv.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
Expand All @@ -41,16 +42,6 @@ struct __any
__any(...);
};

struct __nat
{
#ifndef _LIBCPP_CXX03_LANG
__nat() = delete;
__nat(const __nat&) = delete;
__nat& operator=(const __nat&) = delete;
~__nat() = delete;
#endif
};

template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
struct __member_pointer_traits_imp
{
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__iterator/incrementable_traits.h
Expand Up @@ -11,6 +11,7 @@
#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H

#include <__config>
#include <__type_traits/is_primary_template.h>
#include <concepts>
#include <type_traits>

Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__memory/temporary_buffer.h
Expand Up @@ -11,6 +11,7 @@
#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H

#include <__config>
#include <__type_traits/alignment_of.h>
#include <__utility/pair.h>
#include <cstddef>
#include <new>
Expand Down
142 changes: 142 additions & 0 deletions libcxx/include/__type_traits/aligned_storage.h
@@ -0,0 +1,142 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
#define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H

#include <__config>
#include <__type_traits/conditional.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/nat.h>
#include <__type_traits/type_list.h>
#include <cstddef>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp>
struct __align_type
{
static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
typedef _Tp type;
};

struct __struct_double {long double __lx;};
struct __struct_double4 {double __lx[4];};

typedef
__type_list<__align_type<unsigned char>,
__type_list<__align_type<unsigned short>,
__type_list<__align_type<unsigned int>,
__type_list<__align_type<unsigned long>,
__type_list<__align_type<unsigned long long>,
__type_list<__align_type<double>,
__type_list<__align_type<long double>,
__type_list<__align_type<__struct_double>,
__type_list<__align_type<__struct_double4>,
__type_list<__align_type<int*>,
__nat
> > > > > > > > > > __all_types;

template <size_t _Align>
struct _ALIGNAS(_Align) __fallback_overaligned {};

template <class _TL, size_t _Align> struct __find_pod;

template <class _Hp, size_t _Align>
struct __find_pod<__type_list<_Hp, __nat>, _Align>
{
typedef typename conditional<
_Align == _Hp::value,
typename _Hp::type,
__fallback_overaligned<_Align>
>::type type;
};

template <class _Hp, class _Tp, size_t _Align>
struct __find_pod<__type_list<_Hp, _Tp>, _Align>
{
typedef typename conditional<
_Align == _Hp::value,
typename _Hp::type,
typename __find_pod<_Tp, _Align>::type
>::type type;
};

template <class _TL, size_t _Len> struct __find_max_align;

template <class _Hp, size_t _Len>
struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};

template <size_t _Len, size_t _A1, size_t _A2>
struct __select_align
{
private:
static const size_t __min = _A2 < _A1 ? _A2 : _A1;
static const size_t __max = _A1 < _A2 ? _A2 : _A1;
public:
static const size_t value = _Len < __max ? __min : __max;
};

template <class _Hp, class _Tp, size_t _Len>
struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
: public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};

template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
struct _LIBCPP_TEMPLATE_VIS aligned_storage
{
typedef typename __find_pod<__all_types, _Align>::type _Aligner;
union type
{
_Aligner __align;
unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
};
};

#if _LIBCPP_STD_VER > 11
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
#endif

#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
template <size_t _Len>\
struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
{\
struct _ALIGNAS(n) type\
{\
unsigned char __lx[(_Len + n - 1)/n * n];\
};\
}

_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
// PE/COFF does not support alignment beyond 8192 (=0x2000)
#if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
#endif // !defined(_LIBCPP_OBJECT_FORMAT_COFF)

#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
55 changes: 55 additions & 0 deletions libcxx/include/__type_traits/aligned_union.h
@@ -0,0 +1,55 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H
#define _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H

#include <__config>
#include <__type_traits/aligned_storage.h>
#include <__type_traits/integral_constant.h>
#include <cstddef>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <size_t _I0, size_t ..._In>
struct __static_max;

template <size_t _I0>
struct __static_max<_I0>
{
static const size_t value = _I0;
};

template <size_t _I0, size_t _I1, size_t ..._In>
struct __static_max<_I0, _I1, _In...>
{
static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
__static_max<_I1, _In...>::value;
};

template <size_t _Len, class _Type0, class ..._Types>
struct aligned_union
{
static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
_LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
static const size_t __len = __static_max<_Len, sizeof(_Type0),
sizeof(_Types)...>::value;
typedef typename aligned_storage<__len, alignment_value>::type type;
};

#if _LIBCPP_STD_VER > 11
template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
#endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H

0 comments on commit b7aa9c4

Please sign in to comment.