mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-13 01:36:27 +07:00
Merge pull request #24 from BlackMATov/dev
This commit is contained in:
100
README.md
100
README.md
@@ -95,25 +95,53 @@ flat_set(const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_set(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_set(sorted_range_t, InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_set(sorted_unique_range_t, InputIter first, InputIter last);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_set(InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_set(sorted_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(sorted_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_set(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
|
||||
flat_set(std::initializer_list<value_type> ilist);
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
flat_set(std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(flat_set&& other, const Allocator& a);
|
||||
@@ -172,7 +200,11 @@ iterator insert(const_iterator hint, const value_type& value);
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist);
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
template < typename... Args >
|
||||
std::pair<iterator, bool> emplace(Args&&... args);
|
||||
@@ -329,25 +361,53 @@ flat_map(const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_map(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_map(sorted_unique_range_t, InputIter first, InputIter last);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_map(InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_map(InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
|
||||
template < typename InputIter , typename Allocator >
|
||||
flat_map(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter , typename Allocator >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter , typename Allocator >
|
||||
flat_map(sorted_unique_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
|
||||
flat_map(std::initializer_list<value_type> ilist);
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
flat_map(std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(flat_map&& other, const Allocator& a);
|
||||
@@ -419,7 +479,11 @@ iterator insert(const_iterator hint, const value_type& value);
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist);
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
template < typename... Args >
|
||||
std::pair<iterator, bool> emplace(Args&&... args);
|
||||
@@ -576,25 +640,39 @@ flat_multiset(const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_multiset(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_multiset(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_multiset(InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_multiset(sorted_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multiset(InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multiset(sorted_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multiset(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multiset(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
|
||||
flat_multiset(std::initializer_list<value_type> ilist);
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
flat_multiset(std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multiset(std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multiset(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multiset(flat_multiset&& other, const Allocator& a);
|
||||
@@ -653,7 +731,11 @@ iterator insert(const_iterator hint, const value_type& value);
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist);
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
template < typename... Args >
|
||||
iterator emplace(Args&&... args);
|
||||
@@ -810,25 +892,39 @@ flat_multimap(const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_multimap(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
template < typename InputIter >
|
||||
flat_multimap(InputIter first, InputIter last, const Compare& c);
|
||||
template < typename InputIter >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last, const Compare& c);
|
||||
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multimap(InputIter first, InputIter last, const Allocator& a);
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last, const Allocator& a);
|
||||
|
||||
template < typename InputIter , typename Allocator >
|
||||
flat_multimap(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
template < typename InputIter , typename Allocator >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||
|
||||
flat_multimap(std::initializer_list<value_type> ilist);
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
flat_multimap(std::initializer_list<value_type> ilist, const Compare& c);
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multimap(std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multimap(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
template < typename Allocator >
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multimap(flat_multimap&& other, const Allocator& a);
|
||||
@@ -900,7 +996,11 @@ iterator insert(const_iterator hint, const value_type& value);
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last);
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last);
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist);
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist);
|
||||
|
||||
template < typename... Args >
|
||||
iterator emplace(Args&&... args);
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
38
headers/flat.hpp/detail/is_sorted.hpp
Normal file
38
headers/flat.hpp/detail/is_sorted.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* 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 Iter, typename Compare >
|
||||
bool is_sorted(Iter first, Iter last, Compare comp) {
|
||||
if ( first != last ) {
|
||||
Iter next = first;
|
||||
while ( ++next != last ) {
|
||||
if ( comp(*next, *first) ) {
|
||||
return false;
|
||||
}
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename Iter, typename Compare >
|
||||
bool is_sorted_unique(Iter first, Iter last, Compare comp) {
|
||||
if ( first != last ){
|
||||
Iter next = first;
|
||||
while ( ++next != last ) {
|
||||
if ( !comp(*first, *next) ) {
|
||||
return false;
|
||||
}
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
51
headers/flat.hpp/flat_fwd.hpp
Normal file
51
headers/flat.hpp/flat_fwd.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/is_sorted.hpp"
|
||||
#include "detail/eq_compare.hpp"
|
||||
#include "detail/pair_compare.hpp"
|
||||
#include "detail/is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
struct sorted_range_t {};
|
||||
inline constexpr sorted_range_t sorted_range = sorted_range_t();
|
||||
|
||||
struct sorted_unique_range_t : public sorted_range_t {};
|
||||
inline constexpr sorted_unique_range_t sorted_unique_range = sorted_unique_range_t();
|
||||
|
||||
template < typename Key
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<Key> >
|
||||
class flat_set;
|
||||
|
||||
template < typename Key
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<Key> >
|
||||
class flat_multiset;
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
class flat_map;
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
class flat_multimap;
|
||||
}
|
||||
@@ -6,24 +6,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/pair_compare.hpp"
|
||||
#include "detail/is_transparent.hpp"
|
||||
#include "flat_fwd.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
, typename Compare
|
||||
, typename Container >
|
||||
class flat_map
|
||||
: private detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
@@ -82,48 +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) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
flat_map(sorted_unique_range_t, InputIter first, InputIter 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) {
|
||||
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) {
|
||||
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 >
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last, const Allocator& a)
|
||||
: data_(a) {
|
||||
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) {
|
||||
from_range_(sorted_unique_range, first, last);
|
||||
}
|
||||
|
||||
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 >
|
||||
flat_map(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
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) {
|
||||
from_range_(sorted_unique_range, first, last);
|
||||
}
|
||||
|
||||
flat_map(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_map(std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_map(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(std::initializer_list<value_type> 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<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(std::initializer_list<value_type> 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<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_map(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
@@ -319,13 +401,20 @@ namespace flat_hpp
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last) {
|
||||
while ( first != last ) {
|
||||
insert(*first++);
|
||||
}
|
||||
insert_range_(first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last) {
|
||||
insert_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist.begin(), ilist.end());
|
||||
insert_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
insert_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
@@ -510,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_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_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(), value_comp());
|
||||
data_.erase(
|
||||
std::unique(data_.begin(), data_.end(),
|
||||
detail::eq_compare<value_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(), value_comp());
|
||||
data_.erase(
|
||||
std::unique(data_.begin(), data_.end(),
|
||||
detail::eq_compare<value_compare>(value_comp())),
|
||||
data_.end());
|
||||
}
|
||||
private:
|
||||
container_type data_;
|
||||
};
|
||||
|
||||
@@ -6,24 +6,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/pair_compare.hpp"
|
||||
#include "detail/is_transparent.hpp"
|
||||
#include "flat_fwd.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
, typename Compare
|
||||
, typename Container >
|
||||
class flat_multimap
|
||||
: private detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
@@ -82,48 +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) {
|
||||
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) {
|
||||
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 >
|
||||
template < typename InputIter, typename Allocator >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
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 >
|
||||
flat_multimap(sorted_range_t, InputIter first, InputIter last, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
flat_multimap(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multimap(std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multimap(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multimap(std::initializer_list<value_type> 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<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multimap(std::initializer_list<value_type> 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<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
@@ -315,13 +351,20 @@ namespace flat_hpp
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last) {
|
||||
while ( first != last ) {
|
||||
insert(*first++);
|
||||
}
|
||||
insert_range_(first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last) {
|
||||
insert_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist.begin(), ilist.end());
|
||||
insert_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
insert_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
@@ -506,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(), value_comp());
|
||||
}
|
||||
|
||||
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(), value_comp());
|
||||
}
|
||||
private:
|
||||
container_type data_;
|
||||
};
|
||||
|
||||
@@ -6,22 +6,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/is_transparent.hpp"
|
||||
#include "flat_fwd.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<Key> >
|
||||
, typename Compare
|
||||
, typename Container >
|
||||
class flat_multiset : private Compare {
|
||||
using base_type = Compare;
|
||||
public:
|
||||
@@ -63,48 +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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
flat_multiset(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multiset(std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_multiset(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multiset(std::initializer_list<value_type> 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<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_multiset(std::initializer_list<value_type> 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<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
@@ -242,13 +279,20 @@ namespace flat_hpp
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last) {
|
||||
while ( first != last ) {
|
||||
insert(*first++);
|
||||
}
|
||||
insert_range_(first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last) {
|
||||
insert_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist.begin(), ilist.end());
|
||||
insert_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
insert_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
@@ -421,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(), key_comp());
|
||||
}
|
||||
|
||||
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(), key_comp());
|
||||
}
|
||||
private:
|
||||
container_type data_;
|
||||
};
|
||||
|
||||
@@ -6,22 +6,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/is_transparent.hpp"
|
||||
#include "flat_fwd.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<Key> >
|
||||
, typename Compare
|
||||
, typename Container >
|
||||
class flat_set : private Compare {
|
||||
using base_type = Compare;
|
||||
public:
|
||||
@@ -63,48 +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) {
|
||||
from_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
flat_set(sorted_unique_range_t, InputIter first, InputIter 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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
from_range_(sorted_unique_range, first, last);
|
||||
}
|
||||
|
||||
flat_set(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_set(std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
insert(ilist);
|
||||
from_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_set(sorted_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c)
|
||||
: base_type(c) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(std::initializer_list<value_type> 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<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Allocator& a)
|
||||
: data_(a) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(std::initializer_list<value_type> 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<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
flat_set(sorted_unique_range_t, std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a)
|
||||
: base_type(c)
|
||||
, data_(a) {
|
||||
from_range_(sorted_unique_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename Allocator >
|
||||
@@ -246,13 +329,20 @@ namespace flat_hpp
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(InputIter first, InputIter last) {
|
||||
while ( first != last ) {
|
||||
insert(*first++);
|
||||
}
|
||||
insert_range_(first, last);
|
||||
}
|
||||
|
||||
template < typename InputIter >
|
||||
void insert(sorted_range_t, InputIter first, InputIter last) {
|
||||
insert_range_(sorted_range, first, last);
|
||||
}
|
||||
|
||||
void insert(std::initializer_list<value_type> ilist) {
|
||||
insert(ilist.begin(), ilist.end());
|
||||
insert_range_(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
void insert(sorted_range_t, std::initializer_list<value_type> ilist) {
|
||||
insert_range_(sorted_range, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
@@ -425,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_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_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(), key_comp());
|
||||
data_.erase(
|
||||
std::unique(data_.begin(), data_.end(),
|
||||
detail::eq_compare<key_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(), key_comp());
|
||||
data_.erase(
|
||||
std::unique(data_.begin(), data_.end(),
|
||||
detail::eq_compare<key_compare>(key_comp())),
|
||||
data_.end());
|
||||
}
|
||||
private:
|
||||
container_type data_;
|
||||
};
|
||||
|
||||
@@ -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<int, unsigned>;
|
||||
@@ -209,13 +218,13 @@ TEST_CASE("flat_map") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
|
||||
s0.insert({2,42});
|
||||
|
||||
REQUIRE_FALSE(s0.empty());
|
||||
REQUIRE(s0.size() == 1u);
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
|
||||
s0.insert({2,84});
|
||||
REQUIRE(s0.size() == 1u);
|
||||
@@ -227,7 +236,7 @@ TEST_CASE("flat_map") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -342,6 +351,24 @@ TEST_CASE("flat_map") {
|
||||
REQUIRE(i6 == s0.end() - 1);
|
||||
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}});
|
||||
}
|
||||
|
||||
{
|
||||
map_t s0;
|
||||
s0.insert(sorted_unique_range, {{1,3},{2,2},{3,1}});
|
||||
REQUIRE(s0 == map_t{{1,3},{2,2},{3,1}});
|
||||
|
||||
map_t s1;
|
||||
s1.insert(sorted_range, {{1,3},{2,2},{2,2},{3,1}});
|
||||
REQUIRE(s1 == map_t{{1,3},{2,2},{3,1}});
|
||||
}
|
||||
}
|
||||
SECTION("erasers") {
|
||||
using map_t = flat_map<int, unsigned>;
|
||||
|
||||
@@ -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<int, unsigned>;
|
||||
@@ -209,13 +218,13 @@ TEST_CASE("flat_multimap") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
|
||||
s0.insert({2,42});
|
||||
|
||||
REQUIRE_FALSE(s0.empty());
|
||||
REQUIRE(s0.size() == 1u);
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
|
||||
s0.insert({2,84});
|
||||
REQUIRE(s0.size() == 2u);
|
||||
@@ -227,7 +236,7 @@ TEST_CASE("flat_multimap") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<std::pair<int,unsigned>>().max_size());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -342,6 +351,24 @@ TEST_CASE("flat_multimap") {
|
||||
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}});
|
||||
}
|
||||
|
||||
{
|
||||
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}});
|
||||
}
|
||||
|
||||
{
|
||||
map_t s0;
|
||||
s0.insert(sorted_unique_range, {{1,3},{2,2},{3,1}});
|
||||
REQUIRE(s0 == map_t{{1,3},{2,2},{3,1}});
|
||||
|
||||
map_t s1;
|
||||
s1.insert(sorted_range, {{1,3},{2,2},{2,2},{3,1}});
|
||||
REQUIRE(s1 == map_t{{1,3},{2,2},{2,2},{3,1}});
|
||||
}
|
||||
}
|
||||
SECTION("erasers") {
|
||||
using map_t = flat_multimap<int, unsigned>;
|
||||
|
||||
@@ -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<int>;
|
||||
@@ -195,13 +204,13 @@ TEST_CASE("flat_multiset") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
|
||||
s0.insert(42);
|
||||
|
||||
REQUIRE_FALSE(s0.empty());
|
||||
REQUIRE(s0.size() == 1u);
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
|
||||
s0.insert(42);
|
||||
REQUIRE(s0.size() == 2u);
|
||||
@@ -213,7 +222,7 @@ TEST_CASE("flat_multiset") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -318,6 +327,24 @@ TEST_CASE("flat_multiset") {
|
||||
s0.emplace_hint(s0.cend(), 6); // 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});
|
||||
}
|
||||
|
||||
{
|
||||
set_t s0;
|
||||
s0.insert(sorted_unique_range, {1,2,3});
|
||||
REQUIRE(s0 == set_t{1,2,3});
|
||||
|
||||
set_t s1;
|
||||
s1.insert(sorted_range, {1,2,2,3});
|
||||
REQUIRE(s1 == set_t{1,2,2,3});
|
||||
}
|
||||
}
|
||||
SECTION("erasers") {
|
||||
using set_t = flat_multiset<int>;
|
||||
|
||||
@@ -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<int>;
|
||||
@@ -195,13 +204,13 @@ TEST_CASE("flat_set") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
|
||||
s0.insert(42);
|
||||
|
||||
REQUIRE_FALSE(s0.empty());
|
||||
REQUIRE(s0.size() == 1u);
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
|
||||
s0.insert(42);
|
||||
REQUIRE(s0.size() == 1u);
|
||||
@@ -213,7 +222,7 @@ TEST_CASE("flat_set") {
|
||||
|
||||
REQUIRE(s0.empty());
|
||||
REQUIRE_FALSE(s0.size());
|
||||
REQUIRE(s0.max_size() == std::allocator<int>().max_size());
|
||||
REQUIRE(s0.max_size() == std::vector<int>().max_size());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -318,6 +327,24 @@ TEST_CASE("flat_set") {
|
||||
s0.emplace_hint(s0.cend(), 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});
|
||||
}
|
||||
|
||||
{
|
||||
set_t s0;
|
||||
s0.insert(sorted_unique_range, {1,2,3});
|
||||
REQUIRE(s0 == set_t{1,2,3});
|
||||
|
||||
set_t s1;
|
||||
s1.insert(sorted_range, {1,2,2,3});
|
||||
REQUIRE(s1 == set_t{1,2,3});
|
||||
}
|
||||
}
|
||||
SECTION("erasers") {
|
||||
using set_t = flat_set<int>;
|
||||
|
||||
46
untests/flat_tests.cpp
Normal file
46
untests/flat_tests.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************
|
||||
* 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)
|
||||
******************************************************************************/
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <flat.hpp/detail/is_sorted.hpp>
|
||||
using namespace flat_hpp;
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("flat_map_detail") {
|
||||
SECTION("is_sorted") {
|
||||
auto i1 = {1,2,3,4};
|
||||
REQUIRE(detail::is_sorted(i1.begin(), i1.end(), std::less<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted(i1.begin(), i1.end(), std::greater<int>()));
|
||||
|
||||
auto i2 = {4,3,2,1};
|
||||
REQUIRE(detail::is_sorted(i2.begin(), i2.end(), std::greater<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted(i2.begin(), i2.end(), std::less<int>()));
|
||||
|
||||
auto i3 = {2,1,3,4};
|
||||
REQUIRE_FALSE(detail::is_sorted(i3.begin(), i3.end(), std::less<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted(i3.begin(), i3.end(), std::greater<int>()));
|
||||
}
|
||||
SECTION("is_sorted_unique") {
|
||||
auto i1 = {1,2,3,4};
|
||||
auto i1d = {1,2,2,3,4};
|
||||
REQUIRE(detail::is_sorted_unique(i1.begin(), i1.end(), std::less<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i1d.begin(), i1d.end(), std::less<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i1.begin(), i1.end(), std::greater<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i1d.begin(), i1d.end(), std::greater<int>()));
|
||||
|
||||
auto i2 = {4,3,2,1};
|
||||
auto i2d = {4,3,2,1,1};
|
||||
REQUIRE(detail::is_sorted_unique(i2.begin(), i2.end(), std::greater<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i2d.begin(), i2d.end(), std::greater<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i2.begin(), i2.end(), std::less<int>()));
|
||||
REQUIRE_FALSE(detail::is_sorted_unique(i2d.begin(), i2d.end(), std::less<int>()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user