Skip to content

Commit

Permalink
[libc++] Trivially relocatable (2/3): Add explicit warrants to std li…
Browse files Browse the repository at this point in the history
…brary types.

All this stuff uses the name `__libcpp_is_trivially_relocatable`
instead of `std::is_trivially_relocatable`.
  • Loading branch information
Arthur O'Dwyer committed Dec 14, 2022
1 parent bbde734 commit cc0addf
Show file tree
Hide file tree
Showing 39 changed files with 1,972 additions and 109 deletions.
10 changes: 9 additions & 1 deletion libcxx/include/__bit_reference
Expand Up @@ -1106,9 +1106,17 @@ equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __b
return _VSTD::__equal_unaligned(__first1, __last1, __first2);
}

template <class _Cp, bool _IsConst>
struct __bit_iterator_is_trivially_relocatable {
typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
typename _Cp::__storage_pointer>::type __storage_pointer;

typedef __libcpp_is_trivially_relocatable<__storage_pointer> type;
};

template <class _Cp, bool _IsConst,
typename _Cp::__storage_type>
class __bit_iterator
class _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__bit_iterator_is_trivially_relocatable<_Cp, _IsConst>::type::value)) __bit_iterator
{
public:
typedef typename _Cp::difference_type difference_type;
Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/__config
Expand Up @@ -1086,6 +1086,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES

# if __has_extension(trivially_relocatable)
# define _LIBCPP_TRIVIALLY_RELOCATABLE [[clang::trivially_relocatable]]
# define _LIBCPP_TRIVIALLY_RELOCATABLE_IF(x) [[clang::trivially_relocatable(x)]]
# else
# define _LIBCPP_TRIVIALLY_RELOCATABLE
# define _LIBCPP_TRIVIALLY_RELOCATABLE_IF(x)
# endif

# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")")
# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")")

Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__functional/move_only_function_impl.h
Expand Up @@ -120,6 +120,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ReturnT, class... _ArgTypes>
class
_LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI
_LIBCPP_TRIVIALLY_RELOCATABLE
move_only_function<_ReturnT(_ArgTypes...) _LIBCPP_MOVE_ONLY_FUNCTION_CV_REF noexcept(_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT)>
{
template <class...>
Expand Down
16 changes: 15 additions & 1 deletion libcxx/include/__hash_table
Expand Up @@ -740,7 +740,8 @@ private:
};

template <class _Alloc>
class __bucket_list_deallocator
class _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__libcpp_is_trivially_relocatable<__compressed_pair<typename allocator_traits<_Alloc>::size_type, _Alloc>>::value))
__bucket_list_deallocator
{
typedef _Alloc allocator_type;
typedef allocator_traits<allocator_type> __alloc_traits;
Expand Down Expand Up @@ -1346,6 +1347,19 @@ private:
void __deallocate_node(__next_pointer __np) _NOEXCEPT;
__next_pointer __detach() _NOEXCEPT;

public:
typedef integral_constant<bool,
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
false
#else
__libcpp_is_trivially_relocatable<__bucket_list>::value &&
__libcpp_is_trivially_relocatable<__first_node>::value &&
__libcpp_is_trivially_relocatable<__node_allocator>::value &&
__libcpp_is_trivially_relocatable<hasher>::value &&
__libcpp_is_trivially_relocatable<key_equal>::value
#endif
> __allow_trivial_relocation;

template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
};
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__locale
Expand Up @@ -121,7 +121,7 @@ _LIBCPP_INLINE_VISIBILITY
const _Facet&
use_facet(const locale&);

class _LIBCPP_TYPE_VIS locale
class _LIBCPP_TYPE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE locale
{
public:
// types:
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__memory/shared_ptr.h
Expand Up @@ -399,7 +399,7 @@ struct __shared_ptr_deleter_ctor_reqs
#endif

template<class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE shared_ptr
{
public:
#if _LIBCPP_STD_VER > 14
Expand Down Expand Up @@ -1394,7 +1394,7 @@ get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
#endif // _LIBCPP_NO_RTTI

template<class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE weak_ptr
{
public:
#if _LIBCPP_STD_VER > 14
Expand Down
12 changes: 10 additions & 2 deletions libcxx/include/__memory/unique_ptr.h
Expand Up @@ -104,8 +104,16 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
#endif

template <class _Tp, class _Dp>
struct __unique_ptr_is_trivially_relocatable {
typedef _Tp element_type;
typedef _Dp deleter_type;
typedef typename __pointer<_Tp, deleter_type>::type pointer;
typedef __libcpp_is_trivially_relocatable<__compressed_pair<pointer, deleter_type> > type;
};

template <class _Tp, class _Dp = default_delete<_Tp> >
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__unique_ptr_is_trivially_relocatable<_Tp, _Dp>::type::value)) unique_ptr {
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
Expand Down Expand Up @@ -288,7 +296,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {


template <class _Tp, class _Dp>
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__unique_ptr_is_trivially_relocatable<_Tp, _Dp>::type::value)) unique_ptr<_Tp[], _Dp> {
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__mutex_base
Expand Up @@ -106,7 +106,7 @@ private:
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);

template <class _Mutex>
class _LIBCPP_TEMPLATE_VIS unique_lock
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE unique_lock
{
public:
typedef _Mutex mutex_type;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__utility/pair.h
Expand Up @@ -43,7 +43,7 @@ struct __non_trivially_copyable_base {
#endif

template <class _T1, class _T2>
struct _LIBCPP_TEMPLATE_VIS pair
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value)) pair
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
: private __non_trivially_copyable_base<_T1, _T2>
#endif
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/bitset
Expand Up @@ -156,12 +156,12 @@ public:
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef size_type __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);

protected:
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
Expand Down Expand Up @@ -455,12 +455,12 @@ public:
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef size_type __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);

protected:
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
Expand Down Expand Up @@ -614,12 +614,12 @@ public:
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef size_type __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);

protected:
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
Expand Down
16 changes: 15 additions & 1 deletion libcxx/include/deque
Expand Up @@ -937,8 +937,22 @@ move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
return __r;
}

template <class _Tp, class _Allocator>
struct __deque_allow_trivial_relocation {
using __alloc_traits = allocator_traits<_Allocator>;
using pointer = typename __alloc_traits::pointer;
using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>;
using size_type = typename __alloc_traits::size_type;

static const bool value =
__libcpp_is_trivially_relocatable<pointer>::value &&
__libcpp_is_trivially_relocatable<__pointer_allocator>::value &&
__libcpp_is_trivially_relocatable<size_type>::value &&
__libcpp_is_trivially_relocatable<_Allocator>::value;
};

template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS deque
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__deque_allow_trivial_relocation<_Tp, _Allocator>::value)) deque
{
public:
// types:
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/exception
Expand Up @@ -185,7 +185,7 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);

#ifndef _LIBCPP_ABI_MICROSOFT

class _LIBCPP_TYPE_VIS exception_ptr
class _LIBCPP_TYPE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE exception_ptr
{
void* __ptr_;
public:
Expand Down
7 changes: 6 additions & 1 deletion libcxx/include/forward_list
Expand Up @@ -578,6 +578,9 @@ private:
void __move_assign_alloc(__forward_list_base& __x, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
{__alloc() = _VSTD::move(__x.__alloc());}

public:
typedef __libcpp_is_trivially_relocatable<__compressed_pair<__begin_node, __node_allocator> > __allow_trivial_relocation;
};

#ifndef _LIBCPP_CXX03_LANG
Expand Down Expand Up @@ -645,7 +648,9 @@ __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
}

template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS forward_list
class _LIBCPP_TEMPLATE_VIS
_LIBCPP_TRIVIALLY_RELOCATABLE_IF((__forward_list_base<_Tp, _Alloc>::__allow_trivial_relocation::value))
forward_list
: private __forward_list_base<_Tp, _Alloc>
{
typedef __forward_list_base<_Tp, _Alloc> base;
Expand Down
18 changes: 9 additions & 9 deletions libcxx/include/future
Expand Up @@ -1037,7 +1037,7 @@ _LIBCPP_INLINE_VISIBILITY future<_Rp>
__make_async_assoc_state(_Fp&& __f);

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE future
{
__assoc_state<_Rp>* __state_;

Expand Down Expand Up @@ -1124,7 +1124,7 @@ future<_Rp>::get()
}

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE future<_Rp&>
{
__assoc_state<_Rp&>* __state_;

Expand Down Expand Up @@ -1206,7 +1206,7 @@ future<_Rp&>::get()
}

template <>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE future<void>
{
__assoc_sub_state* __state_;

Expand Down Expand Up @@ -1276,7 +1276,7 @@ swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
template <class _Callable> class packaged_task;

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE promise
{
__assoc_state<_Rp>* __state_;

Expand Down Expand Up @@ -1420,7 +1420,7 @@ promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
// promise<R&>

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE promise<_Rp&>
{
__assoc_state<_Rp&>* __state_;

Expand Down Expand Up @@ -1545,7 +1545,7 @@ promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
// promise<void>

template <>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE promise<void>
{
__assoc_sub_state* __state_;

Expand Down Expand Up @@ -2210,7 +2210,7 @@ async(_Fp&& __f, _Args&&... __args)
// shared_future

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS shared_future
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE shared_future
{
__assoc_state<_Rp>* __state_;

Expand Down Expand Up @@ -2280,7 +2280,7 @@ shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
}

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE shared_future<_Rp&>
{
__assoc_state<_Rp&>* __state_;

Expand Down Expand Up @@ -2350,7 +2350,7 @@ shared_future<_Rp&>::operator=(const shared_future& __rhs)
}

template <>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_TRIVIALLY_RELOCATABLE shared_future<void>
{
__assoc_sub_state* __state_;

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/optional
Expand Up @@ -628,7 +628,7 @@ struct __is_std_optional : false_type {};
template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};

template <class _Tp>
class optional
class _LIBCPP_TRIVIALLY_RELOCATABLE_IF(__libcpp_is_trivially_relocatable<_Tp>::value) optional
: private __optional_move_assign_base<_Tp>
, private __optional_sfinae_ctor_base_t<_Tp>
, private __optional_sfinae_assign_base_t<_Tp>
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/queue
Expand Up @@ -256,7 +256,7 @@ bool
operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);

template <class _Tp, class _Container /*= deque<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS queue
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__libcpp_is_trivially_relocatable<_Container>::value)) queue
{
public:
typedef _Container container_type;
Expand Down Expand Up @@ -490,7 +490,7 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator<queue<_Tp, _Container>, _Alloc>

template <class _Tp, class _Container = vector<_Tp>,
class _Compare = less<typename _Container::value_type> >
class _LIBCPP_TEMPLATE_VIS priority_queue
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__libcpp_is_trivially_relocatable<_Container>::value && __libcpp_is_trivially_relocatable<_Compare>::value)) priority_queue
{
public:
typedef _Container container_type;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/shared_mutex
Expand Up @@ -308,7 +308,7 @@ shared_timed_mutex::try_lock_shared_until(
}

template <class _Mutex>
class shared_lock
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE shared_lock
{
public:
typedef _Mutex mutex_type;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/stack
Expand Up @@ -132,7 +132,7 @@ bool
operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);

template <class _Tp, class _Container /*= deque<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS stack
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE_IF((__libcpp_is_trivially_relocatable<_Container>::value)) stack
{
public:
typedef _Container container_type;
Expand Down
17 changes: 16 additions & 1 deletion libcxx/include/string
Expand Up @@ -653,8 +653,23 @@ struct __can_be_converted_to_string_view : public _BoolConstant<

struct __uninitialized_size_tag {};

template<class _Allocator>
struct __basic_string_is_trivially_relocatable {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
typedef false_type type;
#else
typedef typename allocator_traits<_Allocator>::pointer pointer;
typedef integral_constant<bool,
__libcpp_is_trivially_relocatable<pointer>::value &&
__libcpp_is_trivially_relocatable<_Allocator>::value
> type;
#endif
};

template<class _CharT, class _Traits, class _Allocator>
class basic_string
class
_LIBCPP_TRIVIALLY_RELOCATABLE_IF(__basic_string_is_trivially_relocatable<_Allocator>::type::value)
basic_string
{
public:
typedef basic_string __self;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/thread
Expand Up @@ -219,7 +219,7 @@ basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
{return __os << __id.__id_;}

class _LIBCPP_TYPE_VIS thread
class _LIBCPP_TYPE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE thread
{
__libcpp_thread_t __t_;

Expand Down

0 comments on commit cc0addf

Please sign in to comment.