@@ -221,6 +221,13 @@ class flat_map
221221 [[nodiscard]] bool batch_open () const noexcept { return _batch_start != no_batch; }
222222 [[nodiscard]] const Compare& key_comp () const noexcept { return _compare; }
223223
224+ [[nodiscard]] friend bool operator ==(const flat_map& left, const flat_map& right)
225+ {
226+ left.assert_not_batching ();
227+ right.assert_not_batching ();
228+ return left._keys == right._keys && left._values == right._values ;
229+ }
230+
224231 [[nodiscard]] iterator begin () noexcept { assert_not_batching (); return iterator (this , 0 ); }
225232 [[nodiscard]] const_iterator begin () const noexcept { assert_not_batching (); return const_iterator (this , 0 ); }
226233 [[nodiscard]] const_iterator cbegin () const noexcept { return begin (); }
@@ -399,11 +406,15 @@ class flat_map
399406 assert (batch_open ());
400407 const auto batch_start = _batch_start;
401408 _batch_start = no_batch;
409+ if (batch_start == 0 ) {
410+ sort_and_deduplicate ();
411+ return ;
412+ }
402413
403414 std::vector<size_type> order (size () - batch_start);
404415 for (size_type index = 0 ; index < order.size (); ++index)
405416 order[index] = batch_start + index;
406- std::stable_sort (order. begin (), order. end (), [ this ](size_type left, size_type right) { return _compare (_keys[left], _keys[right]); } );
417+ sort_indices_by_key (order);
407418
408419 std::vector<Key> incoming_keys;
409420 std::vector<Mapped> incoming_values;
@@ -462,6 +473,14 @@ class flat_map
462473 assert (incoming_keys.size () == incoming_values.size ());
463474 if (incoming_keys.empty ())
464475 return ;
476+ if (empty ()) {
477+ const auto unique_size = deduplicate_sorted (incoming_keys, incoming_values);
478+ incoming_keys.resize (unique_size);
479+ incoming_values.resize (unique_size);
480+ _keys = std::move (incoming_keys);
481+ _values = std::move (incoming_values);
482+ return ;
483+ }
465484
466485 std::vector<Key> merged_keys;
467486 std::vector<Mapped> merged_values;
@@ -512,6 +531,70 @@ class flat_map
512531 _values = std::move (merged_values);
513532 }
514533
534+ [[nodiscard]] size_type deduplicate_sorted (std::vector<Key>& keys, std::vector<Mapped>& values) const
535+ {
536+ assert (keys.size () == values.size ());
537+ auto unique_size = size_type{ 0 };
538+ for (size_type index = 0 ; index < keys.size (); ++index) {
539+ if (unique_size != 0 && FlatContainerInternal::sorted_keys_equal (keys[unique_size - 1 ], keys[index], _compare))
540+ continue ;
541+ if (unique_size != index) {
542+ keys[unique_size] = std::move (keys[index]);
543+ values[unique_size] = std::move (values[index]);
544+ }
545+ ++unique_size;
546+ }
547+ return unique_size;
548+ }
549+
550+ void sort_indices_by_key (std::vector<size_type>& indices) const
551+ {
552+ std::sort (indices.begin (), indices.end (), [this ](size_type left, size_type right) {
553+ if constexpr (FlatContainerInternal::EqualityComparable<Key, Key>) {
554+ return _keys[left] == _keys[right] ? left < right : _compare (_keys[left], _keys[right]);
555+ } else {
556+ if (_compare (_keys[left], _keys[right]))
557+ return true ;
558+ if (_compare (_keys[right], _keys[left]))
559+ return false ;
560+ return left < right;
561+ }
562+ });
563+ }
564+
565+ void sort_and_deduplicate ()
566+ {
567+ std::vector<size_type> order (size ());
568+ for (size_type index = 0 ; index < order.size (); ++index)
569+ order[index] = index;
570+ sort_indices_by_key (order);
571+
572+ for (size_type start = 0 ; start < order.size (); ++start) {
573+ if (order[start] == start)
574+ continue ;
575+
576+ Key key = std::move (_keys[start]);
577+ Mapped value = std::move (_values[start]);
578+ auto destination = start;
579+ for (;;) {
580+ const auto source = order[destination];
581+ order[destination] = destination;
582+ if (source == start) {
583+ _keys[destination] = std::move (key);
584+ _values[destination] = std::move (value);
585+ break ;
586+ }
587+ _keys[destination] = std::move (_keys[source]);
588+ _values[destination] = std::move (_values[source]);
589+ destination = source;
590+ }
591+ }
592+
593+ const auto unique_size = deduplicate_sorted (_keys, _values);
594+ _keys.resize (unique_size);
595+ _values.resize (unique_size);
596+ }
597+
515598 std::vector<Key> _keys;
516599 std::vector<Mapped> _values;
517600 [[no_unique_address]] Compare _compare{};
@@ -551,6 +634,13 @@ class flat_set
551634 [[nodiscard]] const Compare& key_comp () const noexcept { return _compare; }
552635 [[nodiscard]] const Compare& value_comp () const noexcept { return _compare; }
553636
637+ [[nodiscard]] friend bool operator ==(const flat_set& left, const flat_set& right)
638+ {
639+ left.assert_not_batching ();
640+ right.assert_not_batching ();
641+ return left._keys == right._keys ;
642+ }
643+
554644 [[nodiscard]] const_iterator begin () const noexcept { assert_not_batching (); return _keys.begin (); }
555645 [[nodiscard]] const_iterator cbegin () const noexcept { return begin (); }
556646 [[nodiscard]] const_iterator end () const noexcept { assert_not_batching (); return _keys.end (); }
@@ -640,7 +730,12 @@ class flat_set
640730 assert (batch_open ());
641731 const auto batch_start = _batch_start;
642732 _batch_start = no_batch;
643- std::stable_sort (_keys.begin () + static_cast <difference_type>(batch_start), _keys.end (), _compare);
733+ std::sort (_keys.begin () + static_cast <difference_type>(batch_start), _keys.end (), _compare);
734+ if (batch_start == 0 ) {
735+ _keys.erase (std::unique (_keys.begin (), _keys.end (),
736+ [this ](const Key& left, const Key& right) { return FlatContainerInternal::sorted_keys_equal (left, right, _compare); }), _keys.end ());
737+ return ;
738+ }
644739
645740 std::vector<Key> incoming_keys (std::make_move_iterator (_keys.begin () + static_cast <difference_type>(batch_start)), std::make_move_iterator (_keys.end ()));
646741 _keys.erase (_keys.begin () + static_cast <difference_type>(batch_start), _keys.end ());
@@ -689,6 +784,12 @@ class flat_set
689784 {
690785 if (incoming_keys.empty ())
691786 return ;
787+ if (empty ()) {
788+ incoming_keys.erase (std::unique (incoming_keys.begin (), incoming_keys.end (),
789+ [this ](const Key& left, const Key& right) { return FlatContainerInternal::sorted_keys_equal (left, right, _compare); }), incoming_keys.end ());
790+ _keys = std::move (incoming_keys);
791+ return ;
792+ }
692793
693794 std::vector<Key> merged_keys;
694795 merged_keys.reserve (size () + incoming_keys.size ());
0 commit comments