mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-14 18:01:41 +07:00
remove O(n^2) complexity from range and initialiser list inserts #7
This commit is contained in:
25
headers/flat.hpp/detail/eq_compare.hpp
Normal file
25
headers/flat.hpp/detail/eq_compare.hpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/flat.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace flat_hpp::detail
|
||||||
|
{
|
||||||
|
template < typename Compare >
|
||||||
|
class eq_compare : public Compare {
|
||||||
|
public:
|
||||||
|
eq_compare() = default;
|
||||||
|
|
||||||
|
eq_compare(const Compare& compare)
|
||||||
|
: Compare(compare) {}
|
||||||
|
|
||||||
|
template < typename L, typename R >
|
||||||
|
bool operator()(const L& l, const R& r) const {
|
||||||
|
return !Compare::operator()(l, r)
|
||||||
|
&& !Compare::operator()(r, l);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#include "detail/eq_compare.hpp"
|
||||||
#include "detail/pair_compare.hpp"
|
#include "detail/pair_compare.hpp"
|
||||||
#include "detail/is_transparent.hpp"
|
#include "detail/is_transparent.hpp"
|
||||||
|
|
||||||
@@ -319,9 +320,13 @@ namespace flat_hpp
|
|||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
while ( first != last ) {
|
const auto mid_iter = data_.insert(data_.end(), first, last);
|
||||||
insert(*first++);
|
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_compare>(value_comp())),
|
||||||
|
data_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(std::initializer_list<value_type> ilist) {
|
void insert(std::initializer_list<value_type> ilist) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#include "detail/eq_compare.hpp"
|
||||||
#include "detail/pair_compare.hpp"
|
#include "detail/pair_compare.hpp"
|
||||||
#include "detail/is_transparent.hpp"
|
#include "detail/is_transparent.hpp"
|
||||||
|
|
||||||
@@ -315,9 +316,9 @@ namespace flat_hpp
|
|||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
while ( first != last ) {
|
const auto mid_iter = data_.insert(data_.end(), first, last);
|
||||||
insert(*first++);
|
std::sort(mid_iter, data_.end(), value_comp());
|
||||||
}
|
std::inplace_merge(data_.begin(), mid_iter, data_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(std::initializer_list<value_type> ilist) {
|
void insert(std::initializer_list<value_type> ilist) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#include "detail/eq_compare.hpp"
|
||||||
#include "detail/is_transparent.hpp"
|
#include "detail/is_transparent.hpp"
|
||||||
|
|
||||||
namespace flat_hpp
|
namespace flat_hpp
|
||||||
@@ -242,9 +243,9 @@ namespace flat_hpp
|
|||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
while ( first != last ) {
|
const auto mid_iter = data_.insert(data_.end(), first, last);
|
||||||
insert(*first++);
|
std::sort(mid_iter, data_.end(), value_comp());
|
||||||
}
|
std::inplace_merge(data_.begin(), mid_iter, data_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(std::initializer_list<value_type> ilist) {
|
void insert(std::initializer_list<value_type> ilist) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#include "detail/eq_compare.hpp"
|
||||||
#include "detail/is_transparent.hpp"
|
#include "detail/is_transparent.hpp"
|
||||||
|
|
||||||
namespace flat_hpp
|
namespace flat_hpp
|
||||||
@@ -246,9 +247,13 @@ namespace flat_hpp
|
|||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
while ( first != last ) {
|
const auto mid_iter = data_.insert(data_.end(), first, last);
|
||||||
insert(*first++);
|
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_compare>(value_comp())),
|
||||||
|
data_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(std::initializer_list<value_type> ilist) {
|
void insert(std::initializer_list<value_type> ilist) {
|
||||||
|
|||||||
@@ -342,6 +342,14 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(i6 == s0.end() - 1);
|
REQUIRE(i6 == s0.end() - 1);
|
||||||
REQUIRE(s0 == map_t{{0,21},{1,42},{2,42},{3,84},{4,84},{5,100500},{6,100500}});
|
REQUIRE(s0 == map_t{{0,21},{1,42},{2,42},{3,84},{4,84},{5,100500},{6,100500}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map_t s0;
|
||||||
|
s0.insert({{6,2},{4,6},{2,4},{4,2}});
|
||||||
|
REQUIRE(s0 == map_t{{2,4},{4,6},{6,2}});
|
||||||
|
s0.insert({{9,3},{7,5},{3,9},{5,3},{5,3}});
|
||||||
|
REQUIRE(s0 == map_t{{2,4},{3,9},{4,6},{5,3},{6,2},{7,5},{9,3}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("erasers") {
|
SECTION("erasers") {
|
||||||
using map_t = flat_map<int, unsigned>;
|
using map_t = flat_map<int, unsigned>;
|
||||||
|
|||||||
@@ -342,6 +342,14 @@ TEST_CASE("flat_multimap") {
|
|||||||
REQUIRE(i6 == s0.end() - 1);
|
REQUIRE(i6 == s0.end() - 1);
|
||||||
REQUIRE(s0 == map_t{{0,21},{1,42},{1,21},{2,42},{3,84},{4,84},{5,100500},{6,100500}});
|
REQUIRE(s0 == map_t{{0,21},{1,42},{1,21},{2,42},{3,84},{4,84},{5,100500},{6,100500}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map_t s0;
|
||||||
|
s0.insert({{6,2},{4,6},{2,4},{4,2}});
|
||||||
|
REQUIRE(s0 == map_t{{2,4},{4,6},{4,2},{6,2}});
|
||||||
|
s0.insert({{9,3},{7,5},{3,9},{5,3},{5,3}});
|
||||||
|
REQUIRE(s0 == map_t{{2,4},{3,9},{4,6},{4,2},{5,3},{5,3},{6,2},{7,5},{9,3}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("erasers") {
|
SECTION("erasers") {
|
||||||
using map_t = flat_multimap<int, unsigned>;
|
using map_t = flat_multimap<int, unsigned>;
|
||||||
|
|||||||
@@ -318,6 +318,14 @@ TEST_CASE("flat_multiset") {
|
|||||||
s0.emplace_hint(s0.cend(), 6); // 1,2,3,3,4,5,6
|
s0.emplace_hint(s0.cend(), 6); // 1,2,3,3,4,5,6
|
||||||
REQUIRE(s0 == set_t{1,2,3,3,4,5,6});
|
REQUIRE(s0 == set_t{1,2,3,3,4,5,6});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
set_t s0;
|
||||||
|
s0.insert({6,4,2,4});
|
||||||
|
REQUIRE(s0 == set_t{2,4,4,6});
|
||||||
|
s0.insert({9,7,3,5,5});
|
||||||
|
REQUIRE(s0 == set_t{2,3,4,4,5,5,6,7,9});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("erasers") {
|
SECTION("erasers") {
|
||||||
using set_t = flat_multiset<int>;
|
using set_t = flat_multiset<int>;
|
||||||
|
|||||||
@@ -318,6 +318,14 @@ TEST_CASE("flat_set") {
|
|||||||
s0.emplace_hint(s0.cend(), 6);
|
s0.emplace_hint(s0.cend(), 6);
|
||||||
REQUIRE(s0 == set_t{1,2,3,4,5,6});
|
REQUIRE(s0 == set_t{1,2,3,4,5,6});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
set_t s0;
|
||||||
|
s0.insert({6,4,2,4});
|
||||||
|
REQUIRE(s0 == set_t{2,4,6});
|
||||||
|
s0.insert({9,7,3,5,5});
|
||||||
|
REQUIRE(s0 == set_t{2,3,4,5,6,7,9});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("erasers") {
|
SECTION("erasers") {
|
||||||
using set_t = flat_set<int>;
|
using set_t = flat_set<int>;
|
||||||
|
|||||||
Reference in New Issue
Block a user