1#ifndef VEG_VECTOR_HPP_QWFSH3ROS
2#define VEG_VECTOR_HPP_QWFSH3ROS
28min2(T a, T b)
noexcept -> T
30 return (
static_cast<T const&
>(a) <
static_cast<T const&
>(b)) ?
VEG_FWD(a)
35max2(T a, T b)
noexcept -> T
37 return (
static_cast<T const&
>(a) <
static_cast<T const&
>(b)) ?
VEG_FWD(b)
41namespace _collections {
45 return current_cap + current_cap;
56relocate(
void* out,
void const* in,
usize nbytes)
noexcept ->
void*;
62template<typename T, bool = cpo::is_trivially_relocatable<T>::value>
69 static constexpr void* (*value)(
void*,
76namespace collections {
102namespace _collections {
103template<
bool IsNoExcept>
106template<
bool NoThrow,
typename T,
typename A,
typename C>
122 template<
typename T,
typename A,
typename C>
130 for (; out < out_end; ++out, ++in) {
139 template<
typename T,
typename A,
typename C>
149 for (; _.fn.ptr < _.fn.ptr_end; ++_.fn.ptr, ++in) {
150 mem::construct_with(_.fn.ptr,
160template<
typename T,
typename A,
typename C>
170 alloc, cloner, out, out_end, in);
173template<
typename T,
typename A,
typename C>
182 if (out == out_end) {
199 T* out_T =
static_cast<T*
>(out);
200 T* in_T =
const_cast<T*
>(
static_cast<T const*
>(in));
201 usize n = nbytes /
sizeof(T);
203 for (
usize i = 0; i < n; ++i) {
204 mem::construct_at(out_T + i,
static_cast<T&&
>(in_T[i]));
215 T* out_T =
static_cast<T*
>(out);
216 T* in_T =
const_cast<T*
>(
static_cast<T const*
>(in));
217 usize n = nbytes /
sizeof(T);
219 for (
usize i = 0; i < n; ++i) {
220 mem::construct_at(out_T + (n - i - 1),
static_cast<T&&
>(in_T[n - i - 1]));
221 in_T[n - i - 1].~T();
237 if (
data !=
nullptr) {
244template<
typename T,
typename A,
typename C>
264 static_cast<T*
>(block.
data),
265 static_cast<T*
>(block.
data) + len,
272template<
typename T,
typename A,
typename C>
289 if (out.byte_cap >= (in_len + out_len) *
sizeof(T)) {
290 mem::AllocBlock block = mem::Alloc<A>::grow(
292 static_cast<void*
>(out.data),
293 mem::Layout{ out.byte_cap, alignof(T) },
295 mem::RelocFn{ collections::relocate_pointer<T>::value });
298 Defer<AllocCleanup<A>> _{ {
301 mem::Layout{ block.byte_cap,
alignof(T) },
304 Defer<Cleanup<T, A, C>> destroy{ {
307 static_cast<T*
>(block.data),
308 static_cast<T*
>(block.data) + out_len,
315 static_cast<T*
>(block.data) + out_len,
316 static_cast<T*
>(block.data) + in_len,
319 destroy.fn.ptr =
nullptr;
320 destroy.fn.ptr_end =
nullptr;
329 static_cast<T*
>(out.data) + out_len,
330 static_cast<T*
>(out.data) + in_len,
336template<
bool TrivialAssign>
340struct CloneFromImpl<false>
342 template<
typename T,
typename A,
typename C>
355 usize rhs_len = (rhs_raw.end - rhs_raw.data);
357 if (!(lhs_alloc == rhs_alloc)) {
358 T* data = lhs_copy.
data;
359 T* data_end = lhs_copy.
end;
362 _collections::backward_destroy(lhs_alloc, cloner, data, data_end);
372 static_cast<void*
>(data),
377 lhs_alloc.get() = rhs_alloc.get();
379 if (lhs_raw.data ==
nullptr) {
380 usize len = rhs_raw.end - rhs_raw.data;
383 _collections::alloc_and_copy(lhs_alloc, cloner, rhs_raw.data, len);
384 T* data =
static_cast<T*
>(blk.
data);
393 usize assign_len = _detail::min2(lhs_copy.
len(), rhs_raw.len());
395 _collections::slice_clone_from(
399 lhs_copy.
data + assign_len,
403 lhs_raw.end = lhs_raw.data + assign_len;
404 _collections::backward_destroy(
407 lhs_copy.
data + assign_len,
422 rhs_raw.
data + assign_len,
423 rhs_len - assign_len);
426 static_cast<T*
>(block.
data),
427 static_cast<T*
>(block.
data) + rhs_len,
428 static_cast<T*
>(block.
data) + block.
byte_cap /
sizeof(T),
433struct CloneFromImpl<true>
435 template<
typename T,
typename A,
typename C>
448 bool need_to_realloc = (!(lhs_alloc.get() == rhs_alloc.get()) ||
449 (lhs_copy.
cap() < rhs_raw.len()));
450 if (need_to_realloc) {
451 T* data = lhs_copy.
data;
458 static_cast<void*
>(data),
463 lhs_alloc.get() = rhs_alloc.get();
466 if (need_to_realloc) {
472 lhs_raw.data =
static_cast<T*
>(block.
data);
473 lhs_raw.end_alloc = lhs_raw.data + block.
byte_cap /
sizeof(T);
475 _collections::slice_clone(
479 lhs_copy.
data + rhs_raw.len(),
482 lhs_raw.
end = lhs_raw.data + rhs_raw.len();
486template<
typename T,
typename A,
typename C>
498 _collections::CloneFromImpl<
530template<
typename T,
typename A>
534 Tuple<A, RawVectorMoveRaii<T>>
555 _detail::__sanitizer_annotate_contiguous_container(
562 mem::Alloc<A>::dealloc(
564 static_cast<void*>(raw.data),
565 mem::Layout{ usize(raw.end_alloc - raw.data) * sizeof(T), alignof(T) });
573#define __VEG_ASAN_ANNOTATE() \
574 if (ptr() != nullptr) { \
575 _detail::__sanitizer_annotate_contiguous_container( \
576 ptr(), ptr() + capacity(), ptr() + len(), ptr() + capacity()); \
578 auto&& _veglib_asan = defer([&]() noexcept { \
579 if (ptr() != nullptr) { \
580 _detail::__sanitizer_annotate_contiguous_container( \
581 ptr(), ptr() + capacity(), ptr() + capacity(), ptr() + len()); \
586#define __VEG_ASAN_ANNOTATE() (void)0;
590namespace _collections {
592 typename A = mem::SystemAlloc,
593 mem::DtorAvailable Dtor = mem::DtorAvailableFor<T>::value,
594 mem::CopyAvailable Copy = mem::CopyAvailableFor<T>::value>
609 return ref(_[1_c]._);
619 return mut(_[1_c]._);
629 auto len =
usize(this->len());
632 this->alloc_mut(unsafe),
633 static_cast<void*
>(raw.
data),
635 usize(byte_capacity()),
639 mem::RelocFn{ collections::relocate_pointer<T>::value });
641 T* data =
static_cast<T*
>(new_block.
data);
645 data + new_block.
byte_cap /
sizeof(T),
651 isize old_len = len();
652 this->_reserve_grow_exact_impl(unsafe,
usize(new_cap));
653 meta::unreachable_if(capacity() < new_cap);
654 meta::unreachable_if(len() != old_len);
658 this->_reserve_grow_exact(
660 1 + isize(_detail::_collections::vector_grow_compute(usize(capacity()))));
663 static_assert(
VEG_CONCEPT(nothrow_move_assignable<A>),
".");
664 static_assert(
VEG_CONCEPT(nothrow_movable<A>),
".");
673 if (raw.
data !=
nullptr) {
697 auto cleanup =
static_cast<VecImpl&&
>(*this);
701 this->alloc_mut(unsafe).get() =
702 static_cast<A&&
>(rhs.alloc_mut(unsafe).get());
703 this->raw_mut(unsafe).get() = rhs.raw_ref().get();
704 rhs.raw_mut(unsafe).get() = {};
712 Copy == mem::CopyAvailable::yes_nothrow)
719 _detail::_collections::alloc_and_copy(this->alloc_mut(unsafe),
724 T* data =
static_cast<T*
>(blk.
data);
727 data +
usize(rhs.len()),
735 Copy == mem::CopyAvailable::yes_nothrow) ->
VecImpl&
738 if (
this != mem::addressof(rhs)) {
741 _detail::_collections::clone_from(this->alloc_mut(unsafe),
743 this->raw_mut(unsafe).get(),
745 rhs.raw_ref().get());
753 if (new_cap > capacity()) {
754 this->_reserve_grow_exact(unsafe, new_cap);
760 auto cap = capacity();
762 this->reserve_exact(
isize(
763 _detail::_collections::vector_grow_choose(
usize(cap),
usize(new_cap))));
777 _detail::_collections::backward_destroy(
785 pop_several_unchecked(unsafe, n);
792 T* last = raw_ref().get().end - 1;
793 T t =
static_cast<T&&
>(*last);
794 --raw_mut(unsafe).get().end;
795 mem::destroy_at(last);
803 T* elem = raw_ref().get().data + i;
804 T t =
static_cast<T&&
>(*elem);
808 mem::destroy_at(elem);
809 _detail::_collections::relocate<T>(
812 sizeof(T) *
usize(len() - i - 1));
814 --raw_mut(unsafe).get().end;
822 return pop_unchecked(unsafe);
829 return pop_mid_unchecked(unsafe, i);
834 pop_several_unchecked(unsafe, len());
851 ::new (
static_cast<void*
>(ptr_mut() + len())) T[
usize(n - len())]{};
855 pop_several_unchecked(unsafe, len() - n);
861 void resize_for_overwrite,
873 ::new (
static_cast<void*
>(ptr_mut() + len())) T[
usize(n - len())];
877 pop_several_unchecked(unsafe, len() - n);
889 static_assert(
VEG_CONCEPT(nothrow_fn_once<Fn, T>),
".");
897 T* elem = raw.
data + i;
898 _detail::_collections::relocate_backward<T>(
902 mem::construct_with(elem,
VEG_FWD(fn));
937 this->_reserve_one_more(unsafe);
939 this->push_with_unchecked(unsafe,
VEG_FWD(fn));
955 return { unsafe, from_raw_parts, ptr(), len() };
959 return { unsafe, from_raw_parts, ptr_mut(), len() };
964 return this->raw_ref().get().data;
968 return const_cast<T*
>(this->ptr());
972 auto& raw = this->raw_ref().get();
977 auto& raw = this->raw_ref().get();
982 auto& raw = this->raw_ref().get();
983 return meta::is_consteval()
985 : (
reinterpret_cast<char const*
>(raw.
end_alloc) -
986 reinterpret_cast<char const*
>(raw.
data));
991 return this->ptr()[i];
995 return const_cast<T&
>(
static_cast<VecImpl const*
>(
this)->operator[](i));
1003 typename A = mem::SystemAlloc,
1004 mem::DtorAvailable Dtor = mem::DtorAvailableFor<T>::value,
1005 mem::CopyAvailable Copy = mem::CopyAvailableFor<T>::value>
1008 Copy == mem::CopyAvailable::no,
1019template<
typename T,
typename A>
1023template<
typename T,
typename A>
1031#undef __VEG_ASAN_ANNOTATE
#define VEG_DEBUG_ASSERT_ALL_OF(...)
#define VEG_DEBUG_ASSERT(...)
#define VEG_ASSERT_ALL_OF(...)
#define HEDLEY_UNLIKELY(expr)
void slice_clone(RefMut< A > alloc, RefMut< C > cloner, T *out, T *out_end, T const *in)
VEG_INLINE constexpr auto vector_grow_choose(usize current_cap, usize new_cap) noexcept -> usize
auto relocate_backward(void *out, void const *in, usize nbytes) noexcept -> void *
void slice_clone_from(RefMut< A > alloc, RefMut< C > cloner, T *out, T *out_end, T const *in) VEG_NOEXCEPT_IF(true)
VEG_INLINE void clone_from(RefMut< A > lhs_alloc, RefMut< C > cloner, vector::RawVector< T > &lhs_raw, Ref< A > rhs_alloc, vector::RawVector< T > const rhs_raw) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_copy_assignable< A >) &&VEG_CONCEPT(alloc
auto relocate(void *out, void const *in, usize nbytes) noexcept -> void *
VEG_INLINE constexpr auto vector_grow_compute(usize current_cap) noexcept -> usize
VEG_INLINE constexpr auto max2(T a, T b) noexcept -> T
VEG_INLINE constexpr auto min2(T a, T b) noexcept -> T
auto memmove(void *dest, void const *src, usize nbytes) noexcept -> void *
_detail::_meta::make_signed< usize >::Type isize
decltype(sizeof(0)) usize
#define VEG_NOEXCEPT_IF(...)
VEG_INLINE VEG_CPP14(constexpr) void operator()()
static void fn(RefMut< A > lhs_alloc, RefMut< C > cloner, vector::RawVector< T > &lhs_raw, Ref< A > rhs_alloc, vector::RawVector< T > const rhs_raw) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_copy_assignable< A >) &&VEG_CONCEPT(alloc
static void fn(RefMut< A > lhs_alloc, RefMut< C > cloner, vector::RawVector< T > &lhs_raw, Ref< A > rhs_alloc, vector::RawVector< T > const rhs_raw) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_copy_assignable< A >) &&VEG_CONCEPT(alloc
static void fn(RefMut< A > alloc, RefMut< C > cloner, T *out, T *out_end, T const *in) VEG_NOEXCEPT_IF(false)
static VEG_CPP14(constexpr) void fn(RefMut< A > alloc
VEG_NODISCARD VEG_INLINE auto operator[](isize i) const VEG_NOEXCEPT -> T const &
VEG_INLINE auto pop() VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >)) -> T
VEG_TEMPLATE(typename U=T, requires(VEG_CONCEPT(constructible< U >)), void resize_for_overwrite,(n, isize)) VEG_NOEXCEPT_IF(VEG_CONCEPT(alloc
VEG_INLINE ~VecImpl() VEG_NOEXCEPT_IF(Dtor
VEG_INLINE auto pop_mid_unchecked(Unsafe, isize i) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >)) -> T
VEG_NODISCARD VEG_INLINE auto capacity() const VEG_NOEXCEPT -> isize
VEG_INLINE void pop_several_unchecked(Unsafe unsafe, isize n)
VEG_TEMPLATE(typename Fn, requires(VEG_CONCEPT(fn_once< Fn, T >)), VEG_INLINE void push_mid_with,(fn, Fn),(i, isize)) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_fn_once< Fn
VEG_INLINE VecImpl(Unsafe, FromRawParts, vector::RawVector< T > rawvec, A alloc) VEG_NOEXCEPT
VEG_INLINE VecImpl(VecImpl &&)=default
VEG_NODISCARD VEG_INLINE auto ptr_mut() VEG_NOEXCEPT -> T *
VEG_INLINE void push_unchecked(Unsafe, T value)
VEG_INLINE void push_mid(T value, isize i) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >) &&VEG_CONCEPT(alloc
VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto alloc_mut(Unsafe) VEG_NOEXCEPT -> RefMut< A >
VEG_NODISCARD VEG_INLINE auto operator[](isize i) VEG_NOEXCEPT -> T &
VEG_NODISCARD VEG_INLINE auto as_mut() VEG_NOEXCEPT -> SliceMut< T >
VEG_NODISCARD VEG_INLINE auto ptr() const VEG_NOEXCEPT -> T const *
VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto raw_ref() const VEG_NOEXCEPT -> Ref< vector::RawVector< T > >
VEG_INLINE auto operator=(VecImpl &&rhs) -> VecImpl &
VEG_NODISCARD VEG_INLINE auto byte_capacity() const VEG_NOEXCEPT -> isize
T && VEG_CONCEPT(alloc::nothrow_alloc< A >))
VEG_INLINE void pop_several(isize n)
VEG_TEMPLATE(typename U=T, requires(VEG_CONCEPT(constructible< U >)), void resize,(n, isize)) VEG_NOEXCEPT_IF(VEG_CONCEPT(alloc
VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto raw_mut(Unsafe) VEG_NOEXCEPT -> RefMut< vector::RawVector< T > >
auto operator=(VecImpl const &rhs) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_copy_assignable< A >) &&VEG_CONCEPT(alloc
VecImpl(VecImpl const &rhs) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_copyable< A >) &&VEG_CONCEPT(alloc
VEG_NODISCARD VEG_INLINE auto as_ref() const VEG_NOEXCEPT -> Slice< T >
VEG_NODISCARD VEG_INLINE auto len() const VEG_NOEXCEPT -> isize
VEG_INLINE auto pop_unchecked(Unsafe) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >)) -> T
VEG_INLINE void reserve(isize new_cap)
VEG_TEMPLATE(typename Fn, requires(VEG_CONCEPT(fn_once< Fn, T >)), VEG_INLINE void push_with_unchecked,(, Unsafe),(fn, Fn)) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_fn_once< Fn
VEG_INLINE void push(T value) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >) &&VEG_CONCEPT(alloc
VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto alloc_ref() const VEG_NOEXCEPT -> Ref< A >
VEG_INLINE auto pop_mid(isize i) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_movable< T >)) -> T
VEG_TEMPLATE(typename Fn, requires(VEG_CONCEPT(fn_once< Fn, T >)), VEG_INLINE void push_with,(fn, Fn)) VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_fn_once< Fn
VEG_INLINE void reserve_exact(isize new_cap)
VEG_INLINE void clear() VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_destructible< T >))
RawVectorMoveRaii(FromRawParts, vector::RawVector< T > inner) VEG_NOEXCEPT
RawVectorMoveRaii()=default
VEG_INLINE VEG_CPP14(constexpr) RawVectorMoveRaii(RawVectorMoveRaii &&rhs) VEG_NOEXCEPT
VEG_INLINE VEG_CPP14(constexpr) RawVectorMoveRaii(RawVectorMoveRaii const &) VEG_NOEXCEPT
auto operator=(VecAlloc const &) -> VecAlloc &=default
auto operator=(VecAlloc &&) -> VecAlloc &=default
VEG_INLINE ~VecAlloc() VEG_NOEXCEPT_IF(VEG_CONCEPT(alloc
VecAlloc(VecAlloc &&)=default
VecAlloc(VecAlloc const &)=default
VEG_INLINE constexpr auto cap() const noexcept -> usize
VEG_INLINE constexpr auto len() const noexcept -> usize
#define __VEG_ASAN_ANNOTATE()