diff --git a/headers/flat.hpp/flat_map.hpp b/headers/flat.hpp/flat_map.hpp index 6e285d0..27152f9 100644 --- a/headers/flat.hpp/flat_map.hpp +++ b/headers/flat.hpp/flat_map.hpp @@ -72,140 +72,140 @@ namespace flat_hpp template < typename InputIter > flat_map(InputIter first, InputIter last) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_map(sorted_range_t, InputIter first, InputIter last) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_map(sorted_unique_range_t, InputIter first, InputIter last) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } template < typename InputIter > flat_map(InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_map(sorted_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } template < typename InputIter, typename Allocator > flat_map(InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_map(sorted_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } - template < typename InputIter , typename Allocator > + template < typename InputIter, typename Allocator > flat_map(InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(first, last); + from_range_(first, last); } - template < typename InputIter , typename Allocator > + template < typename InputIter, typename Allocator > flat_map(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } - template < typename InputIter , typename Allocator > + template < typename InputIter, typename Allocator > flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } flat_map(std::initializer_list ilist) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_map(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_map(sorted_unique_range_t, std::initializer_list ilist) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } flat_map(std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_map(sorted_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_map(sorted_unique_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(sorted_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(sorted_unique_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(sorted_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_map(sorted_unique_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > @@ -401,32 +401,20 @@ namespace flat_hpp template < typename InputIter > void insert(InputIter first, InputIter last) { - const auto mid_iter = data_.insert(data_.end(), first, last); - std::sort(mid_iter, data_.end(), value_comp()); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); - data_.erase( - std::unique(data_.begin(), data_.end(), - detail::eq_compare(value_comp())), - data_.end()); + insert_range_(first, last); } template < typename InputIter > void insert(sorted_range_t, InputIter first, InputIter last) { - assert(detail::is_sorted(first, last, value_comp())); - const auto mid_iter = data_.insert(data_.end(), first, last); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); - data_.erase( - std::unique(data_.begin(), data_.end(), - detail::eq_compare(value_comp())), - data_.end()); + insert_range_(sorted_range, first, last); } void insert(std::initializer_list ilist) { - insert(ilist.begin(), ilist.end()); + insert_range_(ilist.begin(), ilist.end()); } void insert(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist.begin(), ilist.end()); + insert_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename... Args > @@ -611,6 +599,57 @@ namespace flat_hpp value_compare value_comp() const { return value_compare(key_comp()); } + private: + template < typename Iter > + void from_range_(Iter first, Iter last) { + assert(data_.empty()); + data_.insert(data_.end(), first, last); + std::sort(data_.begin(), data_.end(), value_comp()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(value_comp())), + data_.end()); + } + + template < typename Iter > + void from_range_(sorted_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted(first, last, value_comp())); + data_.insert(data_.end(), first, last); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(value_comp())), + data_.end()); + } + + template < typename Iter > + void from_range_(sorted_unique_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted_unique(first, last, value_comp())); + data_.insert(data_.end(), first, last); + } + private: + template < typename Iter > + void insert_range_(Iter first, Iter last) { + const auto mid_iter = data_.insert(data_.end(), first, last); + std::sort(mid_iter, data_.end(), value_comp()); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(value_comp())), + data_.end()); + } + + template < typename Iter > + void insert_range_(sorted_range_t, Iter first, Iter last) { + assert(detail::is_sorted(first, last, value_comp())); + const auto mid_iter = data_.insert(data_.end(), first, last); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(value_comp())), + data_.end()); + } private: container_type data_; }; diff --git a/headers/flat.hpp/flat_multimap.hpp b/headers/flat.hpp/flat_multimap.hpp index 3220571..3ef707f 100644 --- a/headers/flat.hpp/flat_multimap.hpp +++ b/headers/flat.hpp/flat_multimap.hpp @@ -72,94 +72,94 @@ namespace flat_hpp template < typename InputIter > flat_multimap(InputIter first, InputIter last) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_multimap(sorted_range_t, InputIter first, InputIter last) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_multimap(InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_multimap(sorted_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_multimap(InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_multimap(sorted_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } - template < typename InputIter , typename Allocator > + template < typename InputIter, typename Allocator > flat_multimap(InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(first, last); + from_range_(first, last); } - template < typename InputIter , typename Allocator > + template < typename InputIter, typename Allocator > flat_multimap(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } flat_multimap(std::initializer_list ilist) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_multimap(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_multimap(std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_multimap(sorted_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_multimap(std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_multimap(sorted_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_multimap(std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_multimap(sorted_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > @@ -351,24 +351,20 @@ namespace flat_hpp template < typename InputIter > void insert(InputIter first, InputIter last) { - const auto mid_iter = data_.insert(data_.end(), first, last); - std::sort(mid_iter, data_.end(), value_comp()); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); + insert_range_(first, last); } template < typename InputIter > void insert(sorted_range_t, InputIter first, InputIter last) { - assert(detail::is_sorted(first, last, value_comp())); - const auto mid_iter = data_.insert(data_.end(), first, last); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); + insert_range_(sorted_range, first, last); } void insert(std::initializer_list ilist) { - insert(ilist.begin(), ilist.end()); + insert_range_(ilist.begin(), ilist.end()); } void insert(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist.begin(), ilist.end()); + insert_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename... Args > @@ -553,6 +549,34 @@ namespace flat_hpp value_compare value_comp() const { return value_compare(key_comp()); } + private: + template < typename Iter > + void from_range_(Iter first, Iter last) { + assert(data_.empty()); + data_.insert(data_.end(), first, last); + std::sort(data_.begin(), data_.end(), value_comp()); + } + + template < typename Iter > + void from_range_(sorted_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted(first, last, value_comp())); + data_.insert(data_.end(), first, last); + } + private: + template < typename Iter > + void insert_range_(Iter first, Iter last) { + const auto mid_iter = data_.insert(data_.end(), first, last); + std::sort(mid_iter, data_.end(), value_comp()); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + } + + template < typename Iter > + void insert_range_(sorted_range_t, Iter first, Iter last) { + assert(detail::is_sorted(first, last, value_comp())); + const auto mid_iter = data_.insert(data_.end(), first, last); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + } private: container_type data_; }; diff --git a/headers/flat.hpp/flat_multiset.hpp b/headers/flat.hpp/flat_multiset.hpp index e493603..085e897 100644 --- a/headers/flat.hpp/flat_multiset.hpp +++ b/headers/flat.hpp/flat_multiset.hpp @@ -54,94 +54,94 @@ namespace flat_hpp template < typename InputIter > flat_multiset(InputIter first, InputIter last) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_multiset(sorted_range_t, InputIter first, InputIter last) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_multiset(InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_multiset(sorted_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_multiset(InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_multiset(sorted_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_multiset(InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_multiset(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } flat_multiset(std::initializer_list ilist) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_multiset(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_multiset(std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_multiset(sorted_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_multiset(std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_multiset(sorted_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_multiset(std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_multiset(sorted_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > @@ -279,24 +279,20 @@ namespace flat_hpp template < typename InputIter > void insert(InputIter first, InputIter last) { - const auto mid_iter = data_.insert(data_.end(), first, last); - std::sort(mid_iter, data_.end(), value_comp()); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); + insert_range_(first, last); } template < typename InputIter > void insert(sorted_range_t, InputIter first, InputIter last) { - assert(detail::is_sorted(first, last, value_comp())); - const auto mid_iter = data_.insert(data_.end(), first, last); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); + insert_range_(sorted_range, first, last); } void insert(std::initializer_list ilist) { - insert(ilist.begin(), ilist.end()); + insert_range_(ilist.begin(), ilist.end()); } void insert(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist.begin(), ilist.end()); + insert_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename... Args > @@ -469,6 +465,34 @@ namespace flat_hpp value_compare value_comp() const { return value_compare(key_comp()); } + private: + template < typename Iter > + void from_range_(Iter first, Iter last) { + assert(data_.empty()); + data_.insert(data_.end(), first, last); + std::sort(data_.begin(), data_.end(), key_comp()); + } + + template < typename Iter > + void from_range_(sorted_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted(first, last, key_comp())); + data_.insert(data_.end(), first, last); + } + private: + template < typename Iter > + void insert_range_(Iter first, Iter last) { + const auto mid_iter = data_.insert(data_.end(), first, last); + std::sort(mid_iter, data_.end(), key_comp()); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + } + + template < typename Iter > + void insert_range_(sorted_range_t, Iter first, Iter last) { + assert(detail::is_sorted(first, last, key_comp())); + const auto mid_iter = data_.insert(data_.end(), first, last); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + } private: container_type data_; }; diff --git a/headers/flat.hpp/flat_set.hpp b/headers/flat.hpp/flat_set.hpp index 9e15a71..ff6c4d6 100644 --- a/headers/flat.hpp/flat_set.hpp +++ b/headers/flat.hpp/flat_set.hpp @@ -54,140 +54,140 @@ namespace flat_hpp template < typename InputIter > flat_set(InputIter first, InputIter last) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_set(sorted_range_t, InputIter first, InputIter last) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_set(sorted_unique_range_t, InputIter first, InputIter last) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } template < typename InputIter > flat_set(InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(first, last); + from_range_(first, last); } template < typename InputIter > flat_set(sorted_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter > flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c) : base_type(c) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } template < typename InputIter, typename Allocator > flat_set(InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_set(sorted_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Allocator& a) : data_(a) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } template < typename InputIter, typename Allocator > flat_set(InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(first, last); + from_range_(first, last); } template < typename InputIter, typename Allocator > flat_set(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, first, last); + from_range_(sorted_range, first, last); } template < typename InputIter, typename Allocator > flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_unique_range, first, last); + from_range_(sorted_unique_range, first, last); } flat_set(std::initializer_list ilist) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_set(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_set(sorted_unique_range_t, std::initializer_list ilist) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } flat_set(std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } flat_set(sorted_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } flat_set(sorted_unique_range_t, std::initializer_list ilist, const Compare& c) : base_type(c) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(sorted_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(sorted_unique_range_t, std::initializer_list ilist, const Allocator& a) : data_(a) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(ilist); + from_range_(ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(sorted_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_range, ilist); + from_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename Allocator > flat_set(sorted_unique_range_t, std::initializer_list ilist, const Compare& c, const Allocator& a) : base_type(c) , data_(a) { - insert(sorted_unique_range, ilist); + from_range_(sorted_unique_range, ilist.begin(), ilist.end()); } template < typename Allocator > @@ -329,32 +329,20 @@ namespace flat_hpp template < typename InputIter > void insert(InputIter first, InputIter last) { - const auto mid_iter = data_.insert(data_.end(), first, last); - std::sort(mid_iter, data_.end(), value_comp()); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); - data_.erase( - std::unique(data_.begin(), data_.end(), - detail::eq_compare(value_comp())), - data_.end()); + insert_range_(first, last); } template < typename InputIter > void insert(sorted_range_t, InputIter first, InputIter last) { - assert(detail::is_sorted(first, last, value_comp())); - const auto mid_iter = data_.insert(data_.end(), first, last); - std::inplace_merge(data_.begin(), mid_iter, data_.end()); - data_.erase( - std::unique(data_.begin(), data_.end(), - detail::eq_compare(value_comp())), - data_.end()); + insert_range_(sorted_range, first, last); } void insert(std::initializer_list ilist) { - insert(ilist.begin(), ilist.end()); + insert_range_(ilist.begin(), ilist.end()); } void insert(sorted_range_t, std::initializer_list ilist) { - insert(sorted_range, ilist.begin(), ilist.end()); + insert_range_(sorted_range, ilist.begin(), ilist.end()); } template < typename... Args > @@ -527,6 +515,57 @@ namespace flat_hpp value_compare value_comp() const { return value_compare(key_comp()); } + private: + template < typename Iter > + void from_range_(Iter first, Iter last) { + assert(data_.empty()); + data_.insert(data_.end(), first, last); + std::sort(data_.begin(), data_.end(), key_comp()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(key_comp())), + data_.end()); + } + + template < typename Iter > + void from_range_(sorted_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted(first, last, key_comp())); + data_.insert(data_.end(), first, last); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(key_comp())), + data_.end()); + } + + template < typename Iter > + void from_range_(sorted_unique_range_t, Iter first, Iter last) { + assert(data_.empty()); + assert(detail::is_sorted_unique(first, last, key_comp())); + data_.insert(data_.end(), first, last); + } + private: + template < typename Iter > + void insert_range_(Iter first, Iter last) { + const auto mid_iter = data_.insert(data_.end(), first, last); + std::sort(mid_iter, data_.end(), key_comp()); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(key_comp())), + data_.end()); + } + + template < typename Iter > + void insert_range_(sorted_range_t, Iter first, Iter last) { + assert(detail::is_sorted(first, last, key_comp())); + const auto mid_iter = data_.insert(data_.end(), first, last); + std::inplace_merge(data_.begin(), mid_iter, data_.end()); + data_.erase( + std::unique(data_.begin(), data_.end(), + detail::eq_compare(key_comp())), + data_.end()); + } private: container_type data_; }; diff --git a/untests/flat_map_tests.cpp b/untests/flat_map_tests.cpp index 0cbbb4d..7ad0dc8 100644 --- a/untests/flat_map_tests.cpp +++ b/untests/flat_map_tests.cpp @@ -200,6 +200,15 @@ TEST_CASE("flat_map") { s3 = {{0,1}, {1,2}}; REQUIRE(s3 == map_t{{0,1}, {1,2}}); } + + { + auto s0 = map_t(sorted_range, {{1,4},{2,3},{2,2},{3,1}}); + REQUIRE(s0 == map_t{{1,4},{2,3},{3,1}}); + + vec_t v1({{1,4},{2,3},{2,2},{3,1}}); + auto s1 = map_t(sorted_range, v1.begin(), v1.end()); + REQUIRE(s1 == map_t{{1,4},{2,3},{3,1}}); + } } SECTION("capacity") { using map_t = flat_map; diff --git a/untests/flat_multimap_tests.cpp b/untests/flat_multimap_tests.cpp index e37cd0a..461a22b 100644 --- a/untests/flat_multimap_tests.cpp +++ b/untests/flat_multimap_tests.cpp @@ -200,6 +200,15 @@ TEST_CASE("flat_multimap") { s3 = {{0,1}, {1,2}}; REQUIRE(s3 == map_t{{0,1}, {1,2}}); } + + { + auto s0 = map_t(sorted_range, {{1,4},{2,3},{2,2},{3,1}}); + REQUIRE(s0 == map_t{{1,4},{2,3},{2,2},{3,1}}); + + vec_t v1({{1,4},{2,3},{2,2},{3,1}}); + auto s1 = map_t(sorted_range, v1.begin(), v1.end()); + REQUIRE(s1 == map_t{{1,4},{2,3},{2,2},{3,1}}); + } } SECTION("capacity") { using map_t = flat_multimap; diff --git a/untests/flat_multiset_tests.cpp b/untests/flat_multiset_tests.cpp index efe483d..2470283 100644 --- a/untests/flat_multiset_tests.cpp +++ b/untests/flat_multiset_tests.cpp @@ -186,6 +186,15 @@ TEST_CASE("flat_multiset") { s3 = {1,2,3}; REQUIRE(s3 == set_t{1,2,3}); } + + { + auto s0 = set_t(sorted_range, {1,2,2,3}); + REQUIRE(s0 == set_t{1,2,2,3}); + + vec_t v1({1,2,3,3}); + auto s1 = set_t(sorted_range, v1.begin(), v1.end()); + REQUIRE(s1 == set_t{1,2,3,3}); + } } SECTION("capacity") { using set_t = flat_multiset; diff --git a/untests/flat_set_tests.cpp b/untests/flat_set_tests.cpp index b2f4a7f..8b521b8 100644 --- a/untests/flat_set_tests.cpp +++ b/untests/flat_set_tests.cpp @@ -186,6 +186,15 @@ TEST_CASE("flat_set") { s3 = {1,2,3}; REQUIRE(s3 == set_t{1,2,3}); } + + { + auto s0 = set_t(sorted_unique_range, {1,2,3}); + REQUIRE(s0 == set_t{1,2,3}); + + vec_t v1({1,2,3}); + auto s1 = set_t(sorted_unique_range, v1.begin(), v1.end()); + REQUIRE(s1 == set_t{1,2,3}); + } } SECTION("capacity") { using set_t = flat_set;