mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-16 14:09:01 +07:00
@@ -10,9 +10,14 @@ project(flat.hpp)
|
|||||||
add_library(${PROJECT_NAME} INTERFACE)
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
||||||
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
|
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
|
||||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
|
||||||
|
|
||||||
if(BUILD_AS_STANDALONE)
|
if(BUILD_AS_STANDALONE)
|
||||||
|
option(BUILD_WITH_UNBENCH "Build with benchmarks" OFF)
|
||||||
|
if(BUILD_WITH_UNBENCH)
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(unbench)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)
|
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)
|
||||||
if(BUILD_WITH_UNTESTS)
|
if(BUILD_WITH_UNTESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|||||||
192
README.md
192
README.md
@@ -56,8 +56,7 @@ target_link_libraries(your_project_target flat.hpp)
|
|||||||
```cpp
|
```cpp
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare = std::less<Key>
|
, typename Compare = std::less<Key>
|
||||||
, typename Allocator = std::allocator<Key>
|
, typename Container = std::vector<Key> >
|
||||||
, typename Container = std::vector<Key, Allocator> >
|
|
||||||
class flat_set;
|
class flat_set;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -71,57 +70,64 @@ class flat_set;
|
|||||||
| `difference_type` | `Container::difference_type` |
|
| `difference_type` | `Container::difference_type` |
|
||||||
| `key_compare` | `Compare` |
|
| `key_compare` | `Compare` |
|
||||||
| `value_compare` | `Compare` |
|
| `value_compare` | `Compare` |
|
||||||
| `allocator_type` | `Allocator` |
|
|
||||||
| `container_type` | `Container` |
|
| `container_type` | `Container` |
|
||||||
| `reference` | `Container::reference` |
|
| `reference` | `Container::reference` |
|
||||||
| `const_reference` | `Container::const_reference` |
|
| `const_reference` | `Container::const_reference` |
|
||||||
| `pointer` | `Container::pointer` |
|
| `pointer` | `Container::pointer` |
|
||||||
| `const_pointer` | `Container::const_pointer` |
|
| `const_pointer` | `Container::const_pointer` |
|
||||||
| `iterator` | `Container::iterator` |
|
| `iterator` | `Container::const_iterator` |
|
||||||
| `const_iterator` | `Container::const_iterator` |
|
| `const_iterator` | `Container::const_iterator` |
|
||||||
| `reverse_iterator` | `Container::reverse_iterator` |
|
| `reverse_iterator` | `Container::const_reverse_iterator` |
|
||||||
| `const_reverse_iterator` | `Container::const_reverse_iterator` |
|
| `const_reverse_iterator` | `Container::const_reverse_iterator` |
|
||||||
|
|
||||||
### Member functions
|
### Member functions
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
explicit flat_set(
|
flat_set();
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
explicit flat_set(
|
explicit flat_set(const Compare& c);
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
template < typename Allocator >
|
||||||
|
explicit flat_set(const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(const Compare& c, const Allocator& a);
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_set(
|
flat_set(InputIter first, InputIter last);
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_set(
|
flat_set(InputIter first, InputIter last, const Compare& c);
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
|
||||||
|
|
||||||
flat_set(
|
template < typename InputIter, typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_set(InputIter first, InputIter last, const Allocator& a);
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
flat_set(
|
template < typename InputIter, typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_set(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
flat_set(std::initializer_list<value_type> ilist);
|
||||||
|
|
||||||
|
flat_set(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(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(flat_set&& other, const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(const flat_set& other, const Allocator& a);
|
||||||
|
|
||||||
flat_set(flat_set&& other);
|
flat_set(flat_set&& other);
|
||||||
flat_set(const flat_set& other)
|
flat_set(const flat_set& other);
|
||||||
|
|
||||||
flat_set& operator=(flat_set&& other);
|
flat_set& operator=(flat_set&& other);
|
||||||
flat_set& operator=(const flat_set& other);
|
flat_set& operator=(const flat_set& other);
|
||||||
flat_set& operator=(std::initializer_list<value_type> ilist);
|
|
||||||
|
|
||||||
allocator_type get_allocator() const;
|
flat_set& operator=(std::initializer_list<value_type> ilist);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Iterators
|
### Iterators
|
||||||
@@ -211,59 +217,52 @@ value_compare value_comp() const;
|
|||||||
```cpp
|
```cpp
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
void swap(
|
void swap(
|
||||||
flat_set<Key, Compare, Allocator, Container>& l,
|
flat_set<Key, Compare, Container>& l,
|
||||||
flat_set<Key, Compare, Allocator, Container>& r);
|
flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator==(
|
bool operator==(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator!=(
|
bool operator!=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<(
|
bool operator<(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>(
|
bool operator>(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<=(
|
bool operator<=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>=(
|
bool operator>=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r);
|
const flat_set<Key, Compare, Container>& r);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Flat Map
|
## Flat Map
|
||||||
@@ -272,8 +271,7 @@ bool operator>=(
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare = std::less<Key>
|
, typename Compare = std::less<Key>
|
||||||
, typename Allocator = std::allocator<std::pair<Key, Value>>
|
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||||
, typename Container = std::vector<std::pair<Key, Value>, Allocator> >
|
|
||||||
class flat_map;
|
class flat_map;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -287,7 +285,6 @@ class flat_map;
|
|||||||
| `size_type` | `Container::size_type` |
|
| `size_type` | `Container::size_type` |
|
||||||
| `difference_type` | `Container::difference_type` |
|
| `difference_type` | `Container::difference_type` |
|
||||||
| `key_compare` | `Compare` |
|
| `key_compare` | `Compare` |
|
||||||
| `allocator_type` | `Allocator` |
|
|
||||||
| `container_type` | `Container` |
|
| `container_type` | `Container` |
|
||||||
| `reference` | `Container::reference` |
|
| `reference` | `Container::reference` |
|
||||||
| `const_reference` | `Container::const_reference` |
|
| `const_reference` | `Container::const_reference` |
|
||||||
@@ -307,43 +304,51 @@ class value_compare;
|
|||||||
### Member functions
|
### Member functions
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
explicit flat_map(
|
flat_map();
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
explicit flat_map(
|
explicit flat_map(const Compare& c);
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
template < typename Allocator >
|
||||||
|
explicit flat_map(const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(const Compare& c, const Allocator& a);
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_map(
|
flat_map(InputIter first, InputIter last);
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_map(
|
flat_map(InputIter first, InputIter last, const Compare& c);
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
|
||||||
|
|
||||||
flat_map(
|
template < typename InputIter, typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_map(InputIter first, InputIter last, const Allocator& a);
|
||||||
const Allocator& a);
|
|
||||||
|
|
||||||
flat_map(
|
template < typename InputIter , typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_map(InputIter first, InputIter last, const Compare& c, const Allocator& a);
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator());
|
flat_map(std::initializer_list<value_type> ilist);
|
||||||
|
|
||||||
|
flat_map(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(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(flat_map&& other, const Allocator& a);
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(const flat_map& other, const Allocator& a);
|
||||||
|
|
||||||
flat_map(flat_map&& other);
|
flat_map(flat_map&& other);
|
||||||
flat_map(const flat_map& other);
|
flat_map(const flat_map& other);
|
||||||
|
|
||||||
flat_map& operator=(flat_map&& other);
|
flat_map& operator=(flat_map&& other);
|
||||||
flat_map& operator=(const flat_map& other);
|
flat_map& operator=(const flat_map& other);
|
||||||
flat_map& operator=(std::initializer_list<value_type> ilist);
|
|
||||||
|
|
||||||
allocator_type get_allocator() const;
|
flat_map& operator=(std::initializer_list<value_type> ilist);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Iterators
|
### Iterators
|
||||||
@@ -444,65 +449,58 @@ value_compare value_comp() const;
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
void swap(
|
void swap(
|
||||||
flat_map<Key, Value, Compare, Allocator, Container>& l,
|
flat_map<Key, Value, Compare, Container>& l,
|
||||||
flat_map<Key, Value, Compare, Allocator, Container>& r);
|
flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator==(
|
bool operator==(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator!=(
|
bool operator!=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<(
|
bool operator<(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>(
|
bool operator>(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<=(
|
bool operator<=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>=(
|
bool operator>=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r);
|
const flat_map<Key, Value, Compare, Container>& r);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Flat Multiset
|
## Flat Multiset
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare = std::less<Key>
|
, typename Compare = std::less<Key>
|
||||||
, typename Allocator = std::allocator<std::pair<Key, Value>>
|
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||||
, typename Container = std::vector<std::pair<Key, Value>, Allocator> >
|
|
||||||
class flat_map final {
|
class flat_map final {
|
||||||
class uber_comparer_type : public Compare {
|
class uber_comparer_type : public Compare {
|
||||||
public:
|
public:
|
||||||
@@ -39,6 +38,10 @@ namespace flat_hpp
|
|||||||
bool operator()(typename Container::const_reference l, const Key& r) const {
|
bool operator()(typename Container::const_reference l, const Key& r) const {
|
||||||
return Compare::operator()(l.first, r);
|
return Compare::operator()(l.first, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator()(typename Container::const_reference l, typename Container::const_reference r) const {
|
||||||
|
return Compare::operator()(l.first, r.first);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
using key_type = Key;
|
using key_type = Key;
|
||||||
@@ -49,7 +52,6 @@ namespace flat_hpp
|
|||||||
using difference_type = typename Container::difference_type;
|
using difference_type = typename Container::difference_type;
|
||||||
|
|
||||||
using key_compare = Compare;
|
using key_compare = Compare;
|
||||||
using allocator_type = Allocator;
|
|
||||||
using container_type = Container;
|
using container_type = Container;
|
||||||
|
|
||||||
using reference = typename Container::reference;
|
using reference = typename Container::reference;
|
||||||
@@ -67,72 +69,84 @@ namespace flat_hpp
|
|||||||
bool operator()(const value_type& l, const value_type& r) const {
|
bool operator()(const value_type& l, const value_type& r) const {
|
||||||
return compare_(l.first, r.first);
|
return compare_(l.first, r.first);
|
||||||
}
|
}
|
||||||
private:
|
protected:
|
||||||
friend class flat_map;
|
friend class flat_map;
|
||||||
explicit value_compare(const key_compare& compare)
|
explicit value_compare(key_compare compare)
|
||||||
: compare_(compare) {}
|
: compare_(std::move(compare)) {}
|
||||||
private:
|
private:
|
||||||
key_compare compare_;
|
key_compare compare_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename allocator_type::value_type, value_type>::value,
|
|
||||||
"Allocator::value_type must be same type as value_type");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename container_type::value_type, value_type>::value,
|
|
||||||
"Container::value_type must be same type as value_type");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename container_type::allocator_type, allocator_type>::value,
|
|
||||||
"Container::allocator_type must be same type as allocator_type");
|
|
||||||
public:
|
public:
|
||||||
explicit flat_map(
|
flat_map() {}
|
||||||
const Allocator& a)
|
|
||||||
|
explicit flat_map(const Compare& c)
|
||||||
|
: compare_(c) {}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
explicit flat_map(const Allocator& a)
|
||||||
: data_(a) {}
|
: data_(a) {}
|
||||||
|
|
||||||
explicit flat_map(
|
template < typename Allocator >
|
||||||
const Compare& c = Compare(),
|
flat_map(const Compare& c, const Allocator& a)
|
||||||
const Allocator& a = Allocator())
|
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {}
|
, compare_(c) {}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_map(
|
flat_map(InputIter first, InputIter last) {
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Allocator& a)
|
|
||||||
: data_(a) {
|
|
||||||
insert(first, last);
|
insert(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_map(
|
flat_map(InputIter first, InputIter last, const Compare& c)
|
||||||
InputIter first,
|
: compare_(c) {
|
||||||
InputIter last,
|
insert(first, last);
|
||||||
const Compare& c = Compare(),
|
}
|
||||||
const Allocator& a = Allocator())
|
|
||||||
|
template < typename InputIter, typename Allocator >
|
||||||
|
flat_map(InputIter first, InputIter last, const Allocator& a)
|
||||||
|
: data_(a) {
|
||||||
|
insert(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename InputIter , typename Allocator >
|
||||||
|
flat_map(InputIter first, InputIter last, const Compare& c, const Allocator& a)
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {
|
, compare_(c) {
|
||||||
insert(first, last);
|
insert(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
flat_map(
|
flat_map(std::initializer_list<value_type> ilist) {
|
||||||
std::initializer_list<value_type> ilist,
|
insert(ilist);
|
||||||
const Allocator& a)
|
}
|
||||||
|
|
||||||
|
flat_map(std::initializer_list<value_type> ilist, const Compare& c)
|
||||||
|
: compare_(c) {
|
||||||
|
insert(ilist);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(std::initializer_list<value_type> ilist, const Allocator& a)
|
||||||
: data_(a) {
|
: data_(a) {
|
||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
flat_map(
|
template < typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_map(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a)
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator())
|
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {
|
, compare_(c) {
|
||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(flat_map&& other, const Allocator& a)
|
||||||
|
: data_(std::move(other.data_), a)
|
||||||
|
, compare_(std::move(other.compare_)) {}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_map(const flat_map& other, const Allocator& a)
|
||||||
|
: data_(other.data_, a)
|
||||||
|
, compare_(other.compare_) {}
|
||||||
|
|
||||||
flat_map(flat_map&& other) = default;
|
flat_map(flat_map&& other) = default;
|
||||||
flat_map(const flat_map& other) = default;
|
flat_map(const flat_map& other) = default;
|
||||||
|
|
||||||
@@ -144,10 +158,6 @@ namespace flat_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator_type get_allocator() const {
|
|
||||||
return data_.get_allocator();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() noexcept { return data_.begin(); }
|
iterator begin() noexcept { return data_.begin(); }
|
||||||
const_iterator begin() const noexcept { return data_.begin(); }
|
const_iterator begin() const noexcept { return data_.begin(); }
|
||||||
const_iterator cbegin() const noexcept { return data_.cbegin(); }
|
const_iterator cbegin() const noexcept { return data_.cbegin(); }
|
||||||
@@ -220,28 +230,28 @@ namespace flat_hpp
|
|||||||
|
|
||||||
std::pair<iterator, bool> insert(value_type&& value) {
|
std::pair<iterator, bool> insert(value_type&& value) {
|
||||||
const iterator iter = lower_bound(value.first);
|
const iterator iter = lower_bound(value.first);
|
||||||
return iter == end() || compare_(value.first, iter->first)
|
return iter == end() || compare_(value, *iter)
|
||||||
? std::make_pair(data_.insert(iter, std::move(value)), true)
|
? std::make_pair(data_.insert(iter, std::move(value)), true)
|
||||||
: std::make_pair(iter, false);
|
: std::make_pair(iter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<iterator, bool> insert(const value_type& value) {
|
std::pair<iterator, bool> insert(const value_type& value) {
|
||||||
const iterator iter = lower_bound(value.first);
|
const iterator iter = lower_bound(value.first);
|
||||||
return iter == end() || compare_(value.first, iter->first)
|
return iter == end() || compare_(value, *iter)
|
||||||
? std::make_pair(data_.insert(iter, value), true)
|
? std::make_pair(data_.insert(iter, value), true)
|
||||||
: std::make_pair(iter, false);
|
: std::make_pair(iter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, value_type&& value) {
|
iterator insert(const_iterator hint, value_type&& value) {
|
||||||
return (hint == begin() || compare_((hint - 1)->first, value.first))
|
return (hint == begin() || compare_(*(hint - 1), value))
|
||||||
&& (hint == end() || compare_(value.first, hint->first))
|
&& (hint == end() || compare_(value, *hint))
|
||||||
? data_.insert(hint, std::move(value))
|
? data_.insert(hint, std::move(value))
|
||||||
: insert(std::move(value)).first;
|
: insert(std::move(value)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, const value_type& value) {
|
iterator insert(const_iterator hint, const value_type& value) {
|
||||||
return (hint == begin() || compare_((hint - 1)->first, value.first))
|
return (hint == begin() || compare_(*(hint - 1), value))
|
||||||
&& (hint == end() || compare_(value.first, hint->first))
|
&& (hint == end() || compare_(value, *hint))
|
||||||
? data_.insert(hint, value)
|
? data_.insert(hint, value)
|
||||||
: insert(value).first;
|
: insert(value).first;
|
||||||
}
|
}
|
||||||
@@ -293,7 +303,7 @@ namespace flat_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_type count(const key_type& key) const {
|
size_type count(const key_type& key) const {
|
||||||
const auto iter = find(key);
|
const const_iterator iter = find(key);
|
||||||
return iter != end() ? 1 : 0;
|
return iter != end() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,11 +363,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
void swap(
|
void swap(
|
||||||
flat_map<Key, Value, Compare, Allocator, Container>& l,
|
flat_map<Key, Value, Compare, Container>& l,
|
||||||
flat_map<Key, Value, Compare, Allocator, Container>& r)
|
flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
l.swap(r);
|
l.swap(r);
|
||||||
}
|
}
|
||||||
@@ -365,11 +374,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator==(
|
bool operator==(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return l.size() == r.size()
|
return l.size() == r.size()
|
||||||
&& std::equal(l.begin(), l.end(), r.begin());
|
&& std::equal(l.begin(), l.end(), r.begin());
|
||||||
@@ -378,11 +386,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator!=(
|
bool operator!=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(l == r);
|
return !(l == r);
|
||||||
}
|
}
|
||||||
@@ -390,11 +397,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<(
|
bool operator<(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
||||||
}
|
}
|
||||||
@@ -402,11 +408,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>(
|
bool operator>(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return r < l;
|
return r < l;
|
||||||
}
|
}
|
||||||
@@ -414,11 +419,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<=(
|
bool operator<=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(r < l);
|
return !(r < l);
|
||||||
}
|
}
|
||||||
@@ -426,11 +430,10 @@ namespace flat_hpp
|
|||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Value
|
, typename Value
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>=(
|
bool operator>=(
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& l,
|
const flat_map<Key, Value, Compare, Container>& l,
|
||||||
const flat_map<Key, Value, Compare, Allocator, Container>& r)
|
const flat_map<Key, Value, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(l < r);
|
return !(l < r);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ namespace flat_hpp
|
|||||||
{
|
{
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare = std::less<Key>
|
, typename Compare = std::less<Key>
|
||||||
, typename Allocator = std::allocator<Key>
|
, typename Container = std::vector<Key> >
|
||||||
, typename Container = std::vector<Key, Allocator> >
|
|
||||||
class flat_set final {
|
class flat_set final {
|
||||||
public:
|
public:
|
||||||
using key_type = Key;
|
using key_type = Key;
|
||||||
@@ -31,7 +30,6 @@ namespace flat_hpp
|
|||||||
|
|
||||||
using key_compare = Compare;
|
using key_compare = Compare;
|
||||||
using value_compare = Compare;
|
using value_compare = Compare;
|
||||||
using allocator_type = Allocator;
|
|
||||||
using container_type = Container;
|
using container_type = Container;
|
||||||
|
|
||||||
using reference = typename Container::reference;
|
using reference = typename Container::reference;
|
||||||
@@ -39,69 +37,81 @@ namespace flat_hpp
|
|||||||
using pointer = typename Container::pointer;
|
using pointer = typename Container::pointer;
|
||||||
using const_pointer = typename Container::const_pointer;
|
using const_pointer = typename Container::const_pointer;
|
||||||
|
|
||||||
using iterator = typename Container::iterator;
|
using iterator = typename Container::const_iterator;
|
||||||
using const_iterator = typename Container::const_iterator;
|
using const_iterator = typename Container::const_iterator;
|
||||||
using reverse_iterator = typename Container::reverse_iterator;
|
using reverse_iterator = typename Container::const_reverse_iterator;
|
||||||
using const_reverse_iterator = typename Container::const_reverse_iterator;
|
using const_reverse_iterator = typename Container::const_reverse_iterator;
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename allocator_type::value_type, value_type>::value,
|
|
||||||
"Allocator::value_type must be same type as value_type");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename container_type::value_type, value_type>::value,
|
|
||||||
"Container::value_type must be same type as value_type");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<typename container_type::allocator_type, allocator_type>::value,
|
|
||||||
"Container::allocator_type must be same type as allocator_type");
|
|
||||||
public:
|
public:
|
||||||
explicit flat_set(
|
flat_set() {}
|
||||||
const Allocator& a)
|
|
||||||
|
explicit flat_set(const Compare& c)
|
||||||
|
: compare_(c) {}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
explicit flat_set(const Allocator& a)
|
||||||
: data_(a) {}
|
: data_(a) {}
|
||||||
|
|
||||||
explicit flat_set(
|
template < typename Allocator >
|
||||||
const Compare& c = Compare(),
|
flat_set(const Compare& c, const Allocator& a)
|
||||||
const Allocator& a = Allocator())
|
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {}
|
, compare_(c) {}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_set(
|
flat_set(InputIter first, InputIter last) {
|
||||||
InputIter first,
|
|
||||||
InputIter last,
|
|
||||||
const Allocator& a)
|
|
||||||
: data_(a) {
|
|
||||||
insert(first, last);
|
insert(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
flat_set(
|
flat_set(InputIter first, InputIter last, const Compare& c)
|
||||||
InputIter first,
|
: compare_(c) {
|
||||||
InputIter last,
|
insert(first, last);
|
||||||
const Compare& c = Compare(),
|
}
|
||||||
const Allocator& a = Allocator())
|
|
||||||
|
template < typename InputIter, typename Allocator >
|
||||||
|
flat_set(InputIter first, InputIter last, const Allocator& a)
|
||||||
|
: data_(a) {
|
||||||
|
insert(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename InputIter, typename Allocator >
|
||||||
|
flat_set(InputIter first, InputIter last, const Compare& c, const Allocator& a)
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {
|
, compare_(c) {
|
||||||
insert(first, last);
|
insert(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
flat_set(
|
flat_set(std::initializer_list<value_type> ilist) {
|
||||||
std::initializer_list<value_type> ilist,
|
insert(ilist);
|
||||||
const Allocator& a)
|
}
|
||||||
|
|
||||||
|
flat_set(std::initializer_list<value_type> ilist, const Compare& c)
|
||||||
|
: compare_(c) {
|
||||||
|
insert(ilist);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(std::initializer_list<value_type> ilist, const Allocator& a)
|
||||||
: data_(a) {
|
: data_(a) {
|
||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
flat_set(
|
template < typename Allocator >
|
||||||
std::initializer_list<value_type> ilist,
|
flat_set(std::initializer_list<value_type> ilist, const Compare& c, const Allocator& a)
|
||||||
const Compare& c = Compare(),
|
|
||||||
const Allocator& a = Allocator())
|
|
||||||
: data_(a)
|
: data_(a)
|
||||||
, compare_(c) {
|
, compare_(c) {
|
||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(flat_set&& other, const Allocator& a)
|
||||||
|
: data_(std::move(other.data_), a)
|
||||||
|
, compare_(std::move(other.compare_)) {}
|
||||||
|
|
||||||
|
template < typename Allocator >
|
||||||
|
flat_set(const flat_set& other, const Allocator& a)
|
||||||
|
: data_(other.data_, a)
|
||||||
|
, compare_(other.compare_) {}
|
||||||
|
|
||||||
flat_set(flat_set&& other) = default;
|
flat_set(flat_set&& other) = default;
|
||||||
flat_set(const flat_set& other) = default;
|
flat_set(const flat_set& other) = default;
|
||||||
|
|
||||||
@@ -113,10 +123,6 @@ namespace flat_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator_type get_allocator() const {
|
|
||||||
return data_.get_allocator();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() noexcept { return data_.begin(); }
|
iterator begin() noexcept { return data_.begin(); }
|
||||||
const_iterator begin() const noexcept { return data_.begin(); }
|
const_iterator begin() const noexcept { return data_.begin(); }
|
||||||
const_iterator cbegin() const noexcept { return data_.cbegin(); }
|
const_iterator cbegin() const noexcept { return data_.cbegin(); }
|
||||||
@@ -291,22 +297,20 @@ namespace flat_hpp
|
|||||||
{
|
{
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
void swap(
|
void swap(
|
||||||
flat_set<Key, Compare, Allocator, Container>& l,
|
flat_set<Key, Compare, Container>& l,
|
||||||
flat_set<Key, Compare, Allocator, Container>& r)
|
flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
l.swap(r);
|
l.swap(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator==(
|
bool operator==(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return l.size() == r.size()
|
return l.size() == r.size()
|
||||||
&& std::equal(l.begin(), l.end(), r.begin());
|
&& std::equal(l.begin(), l.end(), r.begin());
|
||||||
@@ -314,55 +318,50 @@ namespace flat_hpp
|
|||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator!=(
|
bool operator!=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(l == r);
|
return !(l == r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<(
|
bool operator<(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>(
|
bool operator>(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return r < l;
|
return r < l;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator<=(
|
bool operator<=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(r < l);
|
return !(r < l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Key
|
template < typename Key
|
||||||
, typename Compare
|
, typename Compare
|
||||||
, typename Allocator
|
|
||||||
, typename Container >
|
, typename Container >
|
||||||
bool operator>=(
|
bool operator>=(
|
||||||
const flat_set<Key, Compare, Allocator, Container>& l,
|
const flat_set<Key, Compare, Container>& l,
|
||||||
const flat_set<Key, Compare, Allocator, Container>& r)
|
const flat_set<Key, Compare, Container>& r)
|
||||||
{
|
{
|
||||||
return !(l < r);
|
return !(l < r);
|
||||||
}
|
}
|
||||||
|
|||||||
116
scripts/bench_drawer.py
Executable file
116
scripts/bench_drawer.py
Executable file
@@ -0,0 +1,116 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Script to visualize google-benchmark output"""
|
||||||
|
from __future__ import print_function
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
logging.basicConfig(format='[%(levelname)s] %(message)s')
|
||||||
|
|
||||||
|
METRICS = ['real_time', 'cpu_time', 'bytes_per_second', 'items_per_second']
|
||||||
|
TRANSFORMS = {
|
||||||
|
'': lambda x: x,
|
||||||
|
'inverse': lambda x: 1.0 / x
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_ylabel(args):
|
||||||
|
"""Compute default ylabel for commandline args"""
|
||||||
|
label = ''
|
||||||
|
if args.transform == '':
|
||||||
|
label = args.metric
|
||||||
|
else:
|
||||||
|
label = args.transform + '(' + args.metric + ')'
|
||||||
|
if args.relative_to is not None:
|
||||||
|
label += ' relative to %s' % args.relative_to
|
||||||
|
return label
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
"""Parse commandline arguments"""
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Visualize google-benchmark output')
|
||||||
|
parser.add_argument(
|
||||||
|
'-f', metavar='FILE', type=argparse.FileType('r'), default=sys.stdin,
|
||||||
|
dest='file', help='path to file containing the csv benchmark data')
|
||||||
|
parser.add_argument(
|
||||||
|
'-m', metavar='METRIC', choices=METRICS, default=METRICS[0], dest='metric',
|
||||||
|
help='metric to plot on the y-axis, valid choices are: %s' % ', '.join(METRICS))
|
||||||
|
parser.add_argument(
|
||||||
|
'-t', metavar='TRANSFORM', choices=TRANSFORMS.keys(), default='',
|
||||||
|
help='transform to apply to the chosen metric, valid choices are: %s'
|
||||||
|
% ', '.join(list(TRANSFORMS)), dest='transform')
|
||||||
|
parser.add_argument(
|
||||||
|
'-r', metavar='RELATIVE_TO', type=str, default=None,
|
||||||
|
dest='relative_to', help='plot metrics relative to this label')
|
||||||
|
parser.add_argument(
|
||||||
|
'--xlabel', type=str, default='input size', help='label of the x-axis')
|
||||||
|
parser.add_argument(
|
||||||
|
'--ylabel', type=str, help='label of the y-axis')
|
||||||
|
parser.add_argument(
|
||||||
|
'--title', type=str, default='', help='title of the plot')
|
||||||
|
parser.add_argument(
|
||||||
|
'--logx', action='store_true', help='plot x-axis on a logarithmic scale')
|
||||||
|
parser.add_argument(
|
||||||
|
'--logy', action='store_true', help='plot y-axis on a logarithmic scale')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.ylabel is None:
|
||||||
|
args.ylabel = get_default_ylabel(args)
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
def read_data(args):
|
||||||
|
"""Read and process dataframe using commandline args"""
|
||||||
|
try:
|
||||||
|
data = pd.read_csv(args.file, usecols=['name', args.metric])
|
||||||
|
except ValueError:
|
||||||
|
msg = 'Could not parse the benchmark data. Did you forget "--benchmark_format=csv"?'
|
||||||
|
logging.error(msg)
|
||||||
|
exit(1)
|
||||||
|
data['label'] = data['name'].apply(lambda x: x.split('/')[0])
|
||||||
|
data['input'] = data['name'].apply(lambda x: int(x.split('/')[1]))
|
||||||
|
data[args.metric] = data[args.metric].apply(TRANSFORMS[args.transform])
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def plot_groups(label_groups, args):
|
||||||
|
"""Display the processed data"""
|
||||||
|
for label, group in label_groups.items():
|
||||||
|
plt.plot(group['input'], group[args.metric], label=label)
|
||||||
|
if args.logx:
|
||||||
|
plt.xscale('log')
|
||||||
|
if args.logy:
|
||||||
|
plt.yscale('log')
|
||||||
|
plt.xlabel(args.xlabel)
|
||||||
|
plt.ylabel(args.ylabel)
|
||||||
|
plt.title(args.title)
|
||||||
|
plt.legend()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Entry point of the program"""
|
||||||
|
args = parse_args()
|
||||||
|
data = read_data(args)
|
||||||
|
label_groups = {}
|
||||||
|
for label, group in data.groupby('label'):
|
||||||
|
label_groups[label] = group.set_index('input', drop=False)
|
||||||
|
if args.relative_to is not None:
|
||||||
|
try:
|
||||||
|
baseline = label_groups[args.relative_to][args.metric].copy()
|
||||||
|
except KeyError, key:
|
||||||
|
msg = 'Key %s is not present in the benchmark output'
|
||||||
|
logging.error(msg, str(key))
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if args.relative_to is not None:
|
||||||
|
for label in label_groups:
|
||||||
|
label_groups[label][args.metric] /= baseline
|
||||||
|
plot_groups(label_groups, args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
8
scripts/bench_map_foreach.sh
Executable file
8
scripts/bench_map_foreach.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_map_foreach --benchmark_format=csv > benchmark_map_foreach.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_map_foreach.csv
|
||||||
8
scripts/bench_map_insert.sh
Executable file
8
scripts/bench_map_insert.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_map_insert --benchmark_format=csv > benchmark_map_insert.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_map_insert.csv
|
||||||
8
scripts/bench_map_lookup.sh
Executable file
8
scripts/bench_map_lookup.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_map_lookup --benchmark_format=csv > benchmark_map_lookup.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_map_lookup.csv
|
||||||
8
scripts/bench_set_foreach.sh
Executable file
8
scripts/bench_set_foreach.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_set_foreach --benchmark_format=csv > benchmark_set_foreach.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_set_foreach.csv
|
||||||
8
scripts/bench_set_insert.sh
Executable file
8
scripts/bench_set_insert.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_set_insert --benchmark_format=csv > benchmark_set_insert.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_set_insert.csv
|
||||||
8
scripts/bench_set_lookup.sh
Executable file
8
scripts/bench_set_lookup.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
./unbench/flat.hpp.unbench --benchmark_filter=_set_lookup --benchmark_format=csv > benchmark_set_lookup.csv
|
||||||
|
../scripts/bench_drawer.py -f benchmark_set_lookup.csv
|
||||||
48
unbench/CMakeLists.txt
Normal file
48
unbench/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# 3.11 version is required for `FetchContent`
|
||||||
|
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(flat.hpp.unbench)
|
||||||
|
|
||||||
|
#
|
||||||
|
# boost
|
||||||
|
#
|
||||||
|
|
||||||
|
find_package(Boost
|
||||||
|
OPTIONAL_COMPONENTS container)
|
||||||
|
|
||||||
|
#
|
||||||
|
# google benchmark
|
||||||
|
#
|
||||||
|
|
||||||
|
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
gbench
|
||||||
|
GIT_REPOSITORY https://github.com/google/benchmark)
|
||||||
|
|
||||||
|
FetchContent_GetProperties(gbench)
|
||||||
|
if(NOT gbench_POPULATED)
|
||||||
|
FetchContent_Populate(gbench)
|
||||||
|
add_subdirectory(${gbench_SOURCE_DIR} ${gbench_BINARY_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
# benchmark executable
|
||||||
|
#
|
||||||
|
|
||||||
|
file(GLOB UNBENCH_SOURCES "*.cpp" "*.hpp")
|
||||||
|
add_executable(${PROJECT_NAME} ${UNBENCH_SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
benchmark_main
|
||||||
|
flat.hpp)
|
||||||
|
|
||||||
|
if(Boost_CONTAINER_FOUND)
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
Boost::container)
|
||||||
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
|
PRIVATE BOOST_CONTAINER_FOUND)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_test(${PROJECT_NAME} ${PROJECT_NAME})
|
||||||
131
unbench/bench_base.hpp
Normal file
131
unbench/bench_base.hpp
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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 <set>
|
||||||
|
#include <map>
|
||||||
|
#include <deque>
|
||||||
|
#include <vector>
|
||||||
|
#include <random>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
|
||||||
|
namespace flat_hpp_unbench
|
||||||
|
{
|
||||||
|
struct vec2 {
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
vec2(int v) noexcept
|
||||||
|
: x(v), y(v) {}
|
||||||
|
|
||||||
|
bool operator<(const vec2& o) const noexcept {
|
||||||
|
return
|
||||||
|
(x < o.x) ||
|
||||||
|
(x == o.x && y < o.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const vec2& o) const noexcept {
|
||||||
|
return x == o.x
|
||||||
|
&& y == o.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t hash() const noexcept {
|
||||||
|
std::hash<int> hasher;
|
||||||
|
std::size_t seed = hasher(x);
|
||||||
|
seed ^= hasher(y) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vec4 {
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int z = 0;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
vec4(int v) noexcept
|
||||||
|
: x(v), y(v), z(v), w(v) {}
|
||||||
|
|
||||||
|
bool operator<(const vec4& o) const noexcept {
|
||||||
|
return
|
||||||
|
(x < o.x) ||
|
||||||
|
(x == o.x && y < o.y) ||
|
||||||
|
(x == o.x && y == o.y && z < o.z) ||
|
||||||
|
(x == o.x && y == o.y && z == o.z && w < o.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const vec4& o) const noexcept {
|
||||||
|
return x == o.x
|
||||||
|
&& y == o.y
|
||||||
|
&& z == o.z
|
||||||
|
&& w == o.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t hash() const noexcept {
|
||||||
|
std::hash<int> hasher;
|
||||||
|
std::size_t seed = hasher(x);
|
||||||
|
seed ^= hasher(y) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
seed ^= hasher(z) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
seed ^= hasher(w) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void generate_random_vector(std::size_t n, std::vector<int>& v) {
|
||||||
|
std::mt19937 engine(n);
|
||||||
|
std::uniform_int_distribution<int> dist;
|
||||||
|
|
||||||
|
std::vector<int> nv(n);
|
||||||
|
for ( std::size_t i = 0; i < n; ++i ) {
|
||||||
|
nv[i] = dist(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
v = std::move(nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void generate_random_vector(std::size_t n, std::vector<std::pair<int,int>>& v) {
|
||||||
|
std::mt19937 engine(n);
|
||||||
|
std::uniform_int_distribution<int> dist;
|
||||||
|
|
||||||
|
std::vector<std::pair<int,int>> nv(n);
|
||||||
|
for ( std::size_t i = 0; i < n; ++i ) {
|
||||||
|
nv[i] = std::make_pair(dist(engine), dist(engine));
|
||||||
|
}
|
||||||
|
|
||||||
|
v = std::move(nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double min_bench_statistics(const std::vector<double>& v) {
|
||||||
|
return v.empty()
|
||||||
|
? 0.0
|
||||||
|
: *(std::min_element(v.begin(), v.end()));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
struct hash<flat_hpp_unbench::vec2> {
|
||||||
|
size_t operator()(const flat_hpp_unbench::vec2& v) const {
|
||||||
|
return v.hash();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<flat_hpp_unbench::vec4> {
|
||||||
|
size_t operator()(const flat_hpp_unbench::vec4& v) const {
|
||||||
|
return v.hash();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
94
unbench/map_foreach_bench.cpp
Normal file
94
unbench/map_foreach_bench.cpp
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_map.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_map.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Value >
|
||||||
|
void flat_map_foreach(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
flat_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.second.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Value >
|
||||||
|
void boost_flat_map_foreach(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
boost::container::flat_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.second.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_map_foreach(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.second.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_unordered_map_foreach(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::unordered_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.second.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_map_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_map_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_map_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_map_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
86
unbench/map_insert_bench.cpp
Normal file
86
unbench/map_insert_bench.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_map.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_map.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Value >
|
||||||
|
void flat_map_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
flat_map<int, Value> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Value >
|
||||||
|
void boost_flat_map_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
boost::container::flat_map<int, Value> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_map_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
std::map<int, Value> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_unordered_map_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
std::unordered_map<int, Value> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_map_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_map_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_map_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_map_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
90
unbench/map_lookup_bench.cpp
Normal file
90
unbench/map_lookup_bench.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_map.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_map.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Value >
|
||||||
|
void flat_map_lookup(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
flat_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e.first));
|
||||||
|
benchmark::DoNotOptimize(s.find(e.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Value >
|
||||||
|
void boost_flat_map_lookup(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
boost::container::flat_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e.first));
|
||||||
|
benchmark::DoNotOptimize(s.find(e.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_map_lookup(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e.first));
|
||||||
|
benchmark::DoNotOptimize(s.find(e.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_unordered_map_lookup(benchmark::State& state) {
|
||||||
|
std::vector<std::pair<int,int>> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::unordered_map<int, Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e.first));
|
||||||
|
benchmark::DoNotOptimize(s.find(e.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_map_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_map_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_map_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_map_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
94
unbench/set_foreach_bench.cpp
Normal file
94
unbench/set_foreach_bench.cpp
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_set.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_set.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Value >
|
||||||
|
void flat_set_foreach(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
flat_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Value >
|
||||||
|
void boost_flat_set_foreach(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
boost::container::flat_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_set_foreach(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_unordered_set_foreach(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::unordered_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
int acc = 0;
|
||||||
|
for ( const auto& e : s ) {
|
||||||
|
acc += e.x;
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_set_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_set_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_set_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_set_foreach, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
86
unbench/set_insert_bench.cpp
Normal file
86
unbench/set_insert_bench.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_set.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_set.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Key >
|
||||||
|
void flat_set_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
flat_set<Key> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Key >
|
||||||
|
void boost_flat_set_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
boost::container::flat_set<Key> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Key >
|
||||||
|
void std_set_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
std::set<Key> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Key >
|
||||||
|
void std_unordered_set_insert(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
std::unordered_set<Key> s;
|
||||||
|
for ( auto e : v ) {
|
||||||
|
s.emplace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_set_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_set_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_set_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_set_insert, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
90
unbench/set_lookup_bench.cpp
Normal file
90
unbench/set_lookup_bench.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "bench_base.hpp"
|
||||||
|
using namespace flat_hpp_unbench;
|
||||||
|
|
||||||
|
#include <flat_hpp/flat_set.hpp>
|
||||||
|
using namespace flat_hpp;
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
# include <boost/container/flat_set.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template < typename Value >
|
||||||
|
void flat_set_lookup(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
flat_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e));
|
||||||
|
benchmark::DoNotOptimize(s.find(e * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
template < typename Value >
|
||||||
|
void boost_flat_set_lookup(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
boost::container::flat_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e));
|
||||||
|
benchmark::DoNotOptimize(s.find(e * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_set_lookup(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e));
|
||||||
|
benchmark::DoNotOptimize(s.find(e * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Value >
|
||||||
|
void std_unordered_set_lookup(benchmark::State& state) {
|
||||||
|
std::vector<int> v;
|
||||||
|
generate_random_vector(state.range(), v);
|
||||||
|
std::unordered_set<Value> s(v.begin(), v.end());
|
||||||
|
for ( auto _ : state ) {
|
||||||
|
for ( auto e : v ) {
|
||||||
|
benchmark::DoNotOptimize(s.find(e));
|
||||||
|
benchmark::DoNotOptimize(s.find(e * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(flat_set_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
#ifdef BOOST_CONTAINER_FOUND
|
||||||
|
BENCHMARK_TEMPLATE(boost_flat_set_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_set_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(std_unordered_set_lookup, vec4)
|
||||||
|
->ComputeStatistics("min", min_bench_statistics)
|
||||||
|
->DenseRange(1,401,50);
|
||||||
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
|
|||||||
|
|
||||||
project(flat.hpp.untests)
|
project(flat.hpp.untests)
|
||||||
|
|
||||||
|
set(CATCH_BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
catch2
|
catch2
|
||||||
@@ -17,6 +19,6 @@ endif()
|
|||||||
file(GLOB UNTESTS_SOURCES "*.cpp" "*.hpp")
|
file(GLOB UNTESTS_SOURCES "*.cpp" "*.hpp")
|
||||||
add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES})
|
add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES})
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
Catch2::Catch2
|
Catch2
|
||||||
flat.hpp::flat.hpp)
|
flat.hpp)
|
||||||
add_test(${PROJECT_NAME} ${PROJECT_NAME})
|
add_test(${PROJECT_NAME} ${PROJECT_NAME})
|
||||||
|
|||||||
@@ -119,16 +119,16 @@ TEST_CASE("flat_map") {
|
|||||||
int,
|
int,
|
||||||
unsigned,
|
unsigned,
|
||||||
std::less<int>,
|
std::less<int>,
|
||||||
alloc_t>;
|
std::vector<std::pair<int,unsigned>, alloc_t>>;
|
||||||
|
|
||||||
using map2_t = flat_map<
|
using map2_t = flat_map<
|
||||||
int,
|
int,
|
||||||
unsigned,
|
unsigned,
|
||||||
std::greater<int>,
|
std::greater<int>,
|
||||||
alloc_t>;
|
std::vector<std::pair<int,unsigned>, alloc_t>>;
|
||||||
|
|
||||||
using vec_t = std::vector<
|
using vec_t = std::vector<
|
||||||
std::pair<int,unsigned>>;
|
std::pair<int,unsigned>, alloc_t>;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto s0 = map_t();
|
auto s0 = map_t();
|
||||||
@@ -162,13 +162,6 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(vec_t(s3.begin(), s3.end()) == vec_t({{0,1},{1,2}}));
|
REQUIRE(vec_t(s3.begin(), s3.end()) == vec_t({{0,1},{1,2}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
auto s0 = map_t();
|
|
||||||
auto s1 = map_t(alloc_t(42));
|
|
||||||
REQUIRE(s0.get_allocator().i == 0);
|
|
||||||
REQUIRE(s1.get_allocator().i == 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto s0 = map_t{{0,1}, {1,2}};
|
auto s0 = map_t{{0,1}, {1,2}};
|
||||||
auto s1 = s0;
|
auto s1 = s0;
|
||||||
@@ -177,6 +170,11 @@ TEST_CASE("flat_map") {
|
|||||||
auto s2 = std::move(s1);
|
auto s2 = std::move(s1);
|
||||||
REQUIRE(s1.empty());
|
REQUIRE(s1.empty());
|
||||||
REQUIRE(s2 == map_t{{0,1}, {1,2}});
|
REQUIRE(s2 == map_t{{0,1}, {1,2}});
|
||||||
|
auto s3 = map_t(s2, alloc_t(42));
|
||||||
|
REQUIRE(s2 == s3);
|
||||||
|
auto s4 = map_t(std::move(s3), alloc_t(21));
|
||||||
|
REQUIRE(s3.empty());
|
||||||
|
REQUIRE(s4 == map_t{{0,1}, {1,2}});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -244,7 +242,6 @@ TEST_CASE("flat_map") {
|
|||||||
int,
|
int,
|
||||||
unsigned,
|
unsigned,
|
||||||
std::less<int>,
|
std::less<int>,
|
||||||
alloc2_t,
|
|
||||||
std::deque<std::pair<int, unsigned>, alloc2_t>>;
|
std::deque<std::pair<int, unsigned>, alloc2_t>>;
|
||||||
|
|
||||||
map2_t s1;
|
map2_t s1;
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ TEST_CASE("flat_set") {
|
|||||||
}
|
}
|
||||||
SECTION("ctors") {
|
SECTION("ctors") {
|
||||||
using alloc_t = dummy_allocator<int>;
|
using alloc_t = dummy_allocator<int>;
|
||||||
using set_t = flat_set<int, std::less<int>, alloc_t>;
|
using set_t = flat_set<int, std::less<int>, std::vector<int, alloc_t>>;
|
||||||
using set2_t = flat_set<int, std::greater<int>, alloc_t>;
|
using set2_t = flat_set<int, std::greater<int>, std::vector<int, alloc_t>>;
|
||||||
using vec_t = std::vector<int>;
|
using vec_t = std::vector<int>;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -146,13 +146,6 @@ TEST_CASE("flat_set") {
|
|||||||
REQUIRE(vec_t(s3.begin(), s3.end()) == vec_t({2,1,0}));
|
REQUIRE(vec_t(s3.begin(), s3.end()) == vec_t({2,1,0}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
auto s0 = set_t();
|
|
||||||
auto s1 = set_t(alloc_t(42));
|
|
||||||
REQUIRE(s0.get_allocator().i == 0);
|
|
||||||
REQUIRE(s1.get_allocator().i == 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto s0 = set_t{0,1,2};
|
auto s0 = set_t{0,1,2};
|
||||||
auto s1 = s0;
|
auto s1 = s0;
|
||||||
@@ -161,6 +154,11 @@ TEST_CASE("flat_set") {
|
|||||||
auto s2 = std::move(s1);
|
auto s2 = std::move(s1);
|
||||||
REQUIRE(s1.empty());
|
REQUIRE(s1.empty());
|
||||||
REQUIRE(s2 == set_t{0,1,2});
|
REQUIRE(s2 == set_t{0,1,2});
|
||||||
|
auto s3 = set_t(s2, alloc_t(42));
|
||||||
|
REQUIRE(s2 == s3);
|
||||||
|
auto s4 = set_t(std::move(s3), alloc_t(21));
|
||||||
|
REQUIRE(s3.empty());
|
||||||
|
REQUIRE(s4 == set_t{0,1,2});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -226,7 +224,6 @@ TEST_CASE("flat_set") {
|
|||||||
using set2_t = flat_set<
|
using set2_t = flat_set<
|
||||||
int,
|
int,
|
||||||
std::less<int>,
|
std::less<int>,
|
||||||
alloc2_t,
|
|
||||||
std::deque<int, alloc2_t>>;
|
std::deque<int, alloc2_t>>;
|
||||||
|
|
||||||
set2_t s1;
|
set2_t s1;
|
||||||
|
|||||||
Reference in New Issue
Block a user