Skip to content
Permalink
Browse files

Example conversion for `deque`, using [[trivially_relocatable]].

  • Loading branch information...
Quuxplusone committed Nov 19, 2018
1 parent 0533994 commit 1df78ab704b8b3d5a5e225a7624eb5fe10e3f401
Showing with 60 additions and 18 deletions.
  1. +8 −0 include/__config
  2. +52 −18 include/deque
@@ -1281,6 +1281,14 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
#define _LIBCPP_HAS_NO_IS_AGGREGATE
#endif

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

#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
#define _LIBCPP_HAS_NO_COROUTINES
#endif
@@ -952,6 +952,13 @@ protected:
typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
difference_type> const_iterator;

public:
typedef integral_constant<bool,
is_trivially_relocatable<pointer>::value &&
is_trivially_relocatable<__pointer_allocator>::value &&
is_trivially_relocatable<size_type>::value &&
is_trivially_relocatable<allocator_type>::value
> __allow_trivial_relocation;
protected:
__map __map_;
size_type __start_;
@@ -1190,9 +1197,43 @@ __deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
}
}

template <class _Tp, class _Allocator, bool = __deque_base<_Tp, _Allocator>::__allow_trivial_relocation::value>
class _LIBCPP_TEMPLATE_VIS __deque_relocate_base
: protected __deque_base<_Tp, _Allocator>
{
protected:
#ifndef _LIBCPP_CXX03_LANG
using __deque_base<_Tp, _Allocator>::__deque_base;
#else
_LIBCPP_INLINE_VISIBILITY
__deque_relocate_base() = default;

_LIBCPP_INLINE_VISIBILITY
__deque_relocate_base(const _Allocator& __a)
: __deque_base<_Tp, _Allocator>(__a) {}
#endif // _LIBCPP_CXX03_LANG
};

template <class _Tp, class _Allocator>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE __deque_relocate_base<_Tp, _Allocator, true>
: protected __deque_base<_Tp, _Allocator>
{
protected:
#ifndef _LIBCPP_CXX03_LANG
using __deque_base<_Tp, _Allocator>::__deque_base;
#else
_LIBCPP_INLINE_VISIBILITY
__deque_relocate_base() = default;

_LIBCPP_INLINE_VISIBILITY
__deque_relocate_base(const _Allocator& __a)
: __deque_base<_Tp, _Allocator>(__a) {}
#endif // _LIBCPP_CXX03_LANG
};

template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS deque
: private __deque_base<_Tp, _Allocator>
: private __deque_relocate_base<_Tp, _Allocator>
{
public:
// types:
@@ -1203,6 +1244,7 @@ public:
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");

typedef __deque_relocate_base<value_type, allocator_type> __relocate_base;
typedef __deque_base<value_type, allocator_type> __base;

typedef typename __base::__alloc_traits __alloc_traits;
@@ -1223,7 +1265,7 @@ public:
deque()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
{}
_LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
_LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __relocate_base(__a) {}
explicit deque(size_type __n);
#if _LIBCPP_STD_VER > 11
explicit deque(size_type __n, const _Allocator& __a);
@@ -1249,7 +1291,7 @@ public:
deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}

_LIBCPP_INLINE_VISIBILITY
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
deque(deque&& __c) = default;
_LIBCPP_INLINE_VISIBILITY
deque(deque&& __c, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
@@ -1495,7 +1537,7 @@ deque<_Tp, _Allocator>::deque(size_type __n)
#if _LIBCPP_STD_VER > 11
template <class _Tp, class _Allocator>
deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
: __base(__a)
: __relocate_base(__a)
{
if (__n > 0)
__append(__n);
@@ -1511,7 +1553,7 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)

template <class _Tp, class _Allocator>
deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
: __base(__a)
: __relocate_base(__a)
{
if (__n > 0)
__append(__n, __v);
@@ -1529,21 +1571,21 @@ template <class _Tp, class _Allocator>
template <class _InputIter>
deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
: __base(__a)
: __relocate_base(__a)
{
__append(__f, __l);
}

template <class _Tp, class _Allocator>
deque<_Tp, _Allocator>::deque(const deque& __c)
: __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
: __relocate_base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
{
__append(__c.begin(), __c.end());
}

template <class _Tp, class _Allocator>
deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
: __base(__a)
: __relocate_base(__a)
{
__append(__c.begin(), __c.end());
}
@@ -1570,23 +1612,15 @@ deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)

template <class _Tp, class _Allocator>
deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
: __base(__a)
: __relocate_base(__a)
{
__append(__il.begin(), __il.end());
}

template <class _Tp, class _Allocator>
inline
deque<_Tp, _Allocator>::deque(deque&& __c)
_NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
: __base(_VSTD::move(__c))
{
}

template <class _Tp, class _Allocator>
inline
deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
: __base(_VSTD::move(__c), __a)
: __relocate_base(_VSTD::move(__c), __a)
{
if (__a != __c.__alloc())
{

0 comments on commit 1df78ab

Please sign in to comment.
You can’t perform that action at this time.