I couldn't figure out how to make construct_at work with an aggregate. I checked the libstdc++ sources and they call placement new directly, so I'm giving up on that. Changed node over to manual constructors and it seems to work much better. Also made it so list constructors don't call 'assign' because that required stored types to implement assignment operators during construction.
This commit is contained in:
parent
b6a8c83e0b
commit
11d64d12a0
@ -193,15 +193,18 @@ namespace rexy{
|
|||||||
template<class Comp>
|
template<class Comp>
|
||||||
REXY_CPP20_CONSTEXPR void sort(Comp comp);
|
REXY_CPP20_CONSTEXPR void sort(Comp comp);
|
||||||
private:
|
private:
|
||||||
|
template<class InputIt>
|
||||||
|
REXY_CPP20_CONSTEXPR void iterator_initialize_(InputIt first, InputIt last);
|
||||||
|
REXY_CPP20_CONSTEXPR void constant_initialize_(size_type count, const_reference value);
|
||||||
|
REXY_CPP20_CONSTEXPR void default_initialize_(size_type count);
|
||||||
|
|
||||||
template<class Comp>
|
template<class Comp>
|
||||||
iterator mergesort(iterator first, size_type firstlen, Comp comp);
|
static iterator mergesort(iterator first, size_type firstlen, Comp comp);
|
||||||
std::pair<iterator,size_type> ms_split(iterator it, size_type len);
|
static std::pair<iterator,size_type> ms_split(iterator it, size_type len);
|
||||||
|
|
||||||
static void insert_node_(detail::node_base* prev, detail::node_base* n);
|
static void insert_node_(detail::node_base* prev, detail::node_base* n);
|
||||||
static void remove_node_(detail::node_base* rm);
|
static void remove_node_(detail::node_base* rm);
|
||||||
static detail::node_base* get_next_then_move_node_(detail::node_base* dest, detail::node_base* n);
|
static detail::node_base* get_next_then_move_node_(detail::node_base* dest, detail::node_base* n);
|
||||||
constexpr auto& sentinel(void){return this->m_sentinel;}
|
|
||||||
constexpr const auto& sentinel(void)const{return this->m_sentinel;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,8 +33,25 @@ namespace rexy{
|
|||||||
struct node : public node_base{
|
struct node : public node_base{
|
||||||
T data;
|
T data;
|
||||||
|
|
||||||
node* next(void)const{return static_cast<node*>(node_base::next);}
|
constexpr node(node_base* next, node_base* prev, const T& d):
|
||||||
node* prev(void)const{return static_cast<node*>(node_base::prev);}
|
node_base{next, prev},
|
||||||
|
data(d){}
|
||||||
|
constexpr node(node_base* next, node_base* prev, T&& d):
|
||||||
|
node_base{next, prev},
|
||||||
|
data(std::move(d)){}
|
||||||
|
template<class... Args>
|
||||||
|
constexpr node(node_base* next, node_base* prev, Args&&... args):
|
||||||
|
node_base{next, prev},
|
||||||
|
data(std::forward<Args>(args)...){}
|
||||||
|
constexpr node(const node& n):
|
||||||
|
node_base(n),
|
||||||
|
data(n.data){}
|
||||||
|
constexpr node(node&& n):
|
||||||
|
node_base(std::move(n)),
|
||||||
|
data(std::move(n.data)){}
|
||||||
|
|
||||||
|
constexpr node* next(void)const{return static_cast<node*>(node_base::next);}
|
||||||
|
constexpr node* prev(void)const{return static_cast<node*>(node_base::prev);}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -162,26 +179,26 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(size_type count, const_reference value, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(size_type count, const_reference value, const allocator_type& alloc):
|
||||||
node_allocator_type(alloc)
|
node_allocator_type(alloc)
|
||||||
{
|
{
|
||||||
assign(count, value);
|
constant_initialize_(count, value);
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(size_type count, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(size_type count, const allocator_type& alloc):
|
||||||
node_allocator_type(alloc)
|
node_allocator_type(alloc)
|
||||||
{
|
{
|
||||||
assign(count, value_type());
|
default_initialize_(count);
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(InputIt first, InputIt last, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(InputIt first, InputIt last, const allocator_type& alloc):
|
||||||
node_allocator_type(alloc)
|
node_allocator_type(alloc)
|
||||||
{
|
{
|
||||||
assign(first, last);
|
iterator_initialize_(first, last);
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(const list& other, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(const list& other, const allocator_type& alloc):
|
||||||
node_allocator_type(alloc)
|
node_allocator_type(alloc)
|
||||||
{
|
{
|
||||||
assign(other.begin(), other.end());
|
iterator_initialize_(other.begin(), other.end());
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(list&& other, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(list&& other, const allocator_type& alloc):
|
||||||
@ -193,7 +210,7 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(std::initializer_list<value_type> l, const allocator_type& alloc):
|
REXY_CPP20_CONSTEXPR list<T,Alloc>::list(std::initializer_list<value_type> l, const allocator_type& alloc):
|
||||||
node_allocator_type(alloc)
|
node_allocator_type(alloc)
|
||||||
{
|
{
|
||||||
assign(l);
|
iterator_initialize_(l.begin(), l.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
@ -253,6 +270,26 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR void list<T,Alloc>::assign(size_type count, const_reference value){
|
REXY_CPP20_CONSTEXPR void list<T,Alloc>::assign(size_type count, const_reference value){
|
||||||
assign(sized_constant_iterator{value, count}, sized_constant_iterator<value_type>{{}, 0});
|
assign(sized_constant_iterator{value, count}, sized_constant_iterator<value_type>{{}, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, class Alloc>
|
||||||
|
template<class InputIt>
|
||||||
|
REXY_CPP20_CONSTEXPR void list<T,Alloc>::iterator_initialize_(InputIt first, InputIt last){
|
||||||
|
for(;first != last;++first){
|
||||||
|
emplace_back(*first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
REXY_CPP20_CONSTEXPR void list<T,Alloc>::constant_initialize_(size_type count, const_reference value){
|
||||||
|
for(;count > 0;--count){
|
||||||
|
emplace_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
REXY_CPP20_CONSTEXPR void list<T,Alloc>::default_initialize_(size_type count){
|
||||||
|
for(;count > 0;--count){
|
||||||
|
emplace_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
REXY_CPP20_CONSTEXPR void list<T,Alloc>::assign(InputIt first, InputIt last){
|
REXY_CPP20_CONSTEXPR void list<T,Alloc>::assign(InputIt first, InputIt last){
|
||||||
@ -347,12 +384,7 @@ namespace rexy{
|
|||||||
auto* next = prev->next;
|
auto* next = prev->next;
|
||||||
prev->next = this->allocate(1);
|
prev->next = this->allocate(1);
|
||||||
next->prev = prev->next;
|
next->prev = prev->next;
|
||||||
#ifdef __clang__
|
std::construct_at(static_cast<node*>(prev->next), next, prev, std::move(value));
|
||||||
//clang won't let construct at emplace without creating a temporary here...
|
|
||||||
std::construct_at(static_cast<node*>(prev->next), node{{next, prev}, std::move(value)});
|
|
||||||
#else
|
|
||||||
std::construct_at(static_cast<node*>(prev->next), detail::node_base{next, prev}, std::move(value));
|
|
||||||
#endif
|
|
||||||
++m_size;
|
++m_size;
|
||||||
return iterator{prev->next};
|
return iterator{prev->next};
|
||||||
}
|
}
|
||||||
@ -385,11 +417,7 @@ namespace rexy{
|
|||||||
auto* next = prev->next;
|
auto* next = prev->next;
|
||||||
prev->next = this->allocate(1);
|
prev->next = this->allocate(1);
|
||||||
next->prev = prev->next;
|
next->prev = prev->next;
|
||||||
#ifdef __clang__
|
std::construct_at(static_cast<node*>(prev->next), next, prev, std::forward<Args>(args)...);
|
||||||
std::construct_at(static_cast<node*>(prev->next), node{{next, prev}, value_type{std::forward<Args>(args)...}});
|
|
||||||
#else
|
|
||||||
std::construct_at(static_cast<node*>(prev->next), detail::node_base{next, prev}, value_type{std::forward<Args>(args)...});
|
|
||||||
#endif
|
|
||||||
++m_size;
|
++m_size;
|
||||||
return iterator{prev->next};
|
return iterator{prev->next};
|
||||||
}
|
}
|
||||||
@ -415,16 +443,16 @@ namespace rexy{
|
|||||||
|
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::push_back(const_reference value) -> reference{
|
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::push_back(const_reference value) -> reference{
|
||||||
return insert(cend(), value);
|
return *insert(cend(), value);
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::push_back(value_type&& value) -> reference{
|
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::push_back(value_type&& value) -> reference{
|
||||||
return insert(cend(), std::move(value));
|
return *insert(cend(), std::move(value));
|
||||||
}
|
}
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::emplace_back(Args&&... args) -> reference{
|
REXY_CPP20_CONSTEXPR auto list<T,Alloc>::emplace_back(Args&&... args) -> reference{
|
||||||
return emplace(cend(), std::forward<Args>(args)...);
|
return *emplace(cend(), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user