diff --git a/include/rexy/list.hpp b/include/rexy/list.hpp index 62fb2a0..c96d2dc 100644 --- a/include/rexy/list.hpp +++ b/include/rexy/list.hpp @@ -193,15 +193,18 @@ namespace rexy{ template REXY_CPP20_CONSTEXPR void sort(Comp comp); private: + template + 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 - iterator mergesort(iterator first, size_type firstlen, Comp comp); - std::pair ms_split(iterator it, size_type len); + static iterator mergesort(iterator first, size_type firstlen, Comp comp); + static std::pair ms_split(iterator it, size_type len); static void insert_node_(detail::node_base* prev, detail::node_base* n); 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); - constexpr auto& sentinel(void){return this->m_sentinel;} - constexpr const auto& sentinel(void)const{return this->m_sentinel;} }; } diff --git a/include/rexy/list.tpp b/include/rexy/list.tpp index f4ec3fd..2141d64 100644 --- a/include/rexy/list.tpp +++ b/include/rexy/list.tpp @@ -33,8 +33,25 @@ namespace rexy{ struct node : public node_base{ T data; - node* next(void)const{return static_cast(node_base::next);} - node* prev(void)const{return static_cast(node_base::prev);} + constexpr node(node_base* next, node_base* prev, const T& d): + 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 + constexpr node(node_base* next, node_base* prev, Args&&... args): + node_base{next, prev}, + data(std::forward(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_base::next);} + constexpr node* prev(void)const{return static_cast(node_base::prev);} }; template @@ -162,26 +179,26 @@ namespace rexy{ REXY_CPP20_CONSTEXPR list::list(size_type count, const_reference value, const allocator_type& alloc): node_allocator_type(alloc) { - assign(count, value); + constant_initialize_(count, value); } template REXY_CPP20_CONSTEXPR list::list(size_type count, const allocator_type& alloc): node_allocator_type(alloc) { - assign(count, value_type()); + default_initialize_(count); } template template REXY_CPP20_CONSTEXPR list::list(InputIt first, InputIt last, const allocator_type& alloc): node_allocator_type(alloc) { - assign(first, last); + iterator_initialize_(first, last); } template REXY_CPP20_CONSTEXPR list::list(const list& other, const allocator_type& alloc): node_allocator_type(alloc) { - assign(other.begin(), other.end()); + iterator_initialize_(other.begin(), other.end()); } template REXY_CPP20_CONSTEXPR list::list(list&& other, const allocator_type& alloc): @@ -193,7 +210,7 @@ namespace rexy{ REXY_CPP20_CONSTEXPR list::list(std::initializer_list l, const allocator_type& alloc): node_allocator_type(alloc) { - assign(l); + iterator_initialize_(l.begin(), l.end()); } template @@ -253,6 +270,26 @@ namespace rexy{ REXY_CPP20_CONSTEXPR void list::assign(size_type count, const_reference value){ assign(sized_constant_iterator{value, count}, sized_constant_iterator{{}, 0}); } + + template + template + REXY_CPP20_CONSTEXPR void list::iterator_initialize_(InputIt first, InputIt last){ + for(;first != last;++first){ + emplace_back(*first); + } + } + template + REXY_CPP20_CONSTEXPR void list::constant_initialize_(size_type count, const_reference value){ + for(;count > 0;--count){ + emplace_back(value); + } + } + template + REXY_CPP20_CONSTEXPR void list::default_initialize_(size_type count){ + for(;count > 0;--count){ + emplace_back(); + } + } template template REXY_CPP20_CONSTEXPR void list::assign(InputIt first, InputIt last){ @@ -347,12 +384,7 @@ namespace rexy{ auto* next = prev->next; prev->next = this->allocate(1); next->prev = prev->next; -#ifdef __clang__ - //clang won't let construct at emplace without creating a temporary here... - std::construct_at(static_cast(prev->next), node{{next, prev}, std::move(value)}); -#else - std::construct_at(static_cast(prev->next), detail::node_base{next, prev}, std::move(value)); -#endif + std::construct_at(static_cast(prev->next), next, prev, std::move(value)); ++m_size; return iterator{prev->next}; } @@ -385,11 +417,7 @@ namespace rexy{ auto* next = prev->next; prev->next = this->allocate(1); next->prev = prev->next; -#ifdef __clang__ - std::construct_at(static_cast(prev->next), node{{next, prev}, value_type{std::forward(args)...}}); -#else - std::construct_at(static_cast(prev->next), detail::node_base{next, prev}, value_type{std::forward(args)...}); -#endif + std::construct_at(static_cast(prev->next), next, prev, std::forward(args)...); ++m_size; return iterator{prev->next}; } @@ -415,16 +443,16 @@ namespace rexy{ template REXY_CPP20_CONSTEXPR auto list::push_back(const_reference value) -> reference{ - return insert(cend(), value); + return *insert(cend(), value); } template REXY_CPP20_CONSTEXPR auto list::push_back(value_type&& value) -> reference{ - return insert(cend(), std::move(value)); + return *insert(cend(), std::move(value)); } template template REXY_CPP20_CONSTEXPR auto list::emplace_back(Args&&... args) -> reference{ - return emplace(cend(), std::forward(args)...); + return *emplace(cend(), std::forward(args)...); } template