Merge pull request #16 from BlackMATov/dev

Dev
This commit is contained in:
2019-05-12 21:05:52 +07:00
committed by GitHub
12 changed files with 631 additions and 561 deletions

View File

@@ -3,6 +3,7 @@ shallow_clone: true
image:
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019 Preview
platform:
- Win32
- x64

View File

@@ -1,18 +1,6 @@
language: cpp
matrix:
include:
- os: linux
dist: trusty
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-4.9"] } }
env: MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
- os: linux
dist: trusty
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-5"] } }
env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
- os: linux
dist: trusty
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-6"] } }
env: MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
- os: linux
dist: trusty
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-7"] } }
@@ -21,18 +9,6 @@ matrix:
dist: trusty
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-8"] } }
env: MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["xorg-dev", "clang-3.8", "g++-5"] } }
env: MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8"
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.9"], packages: ["xorg-dev", "clang-3.9", "g++-5"] } }
env: MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-4.0"], packages: ["xorg-dev", "clang-4.0", "g++-5"] } }
env: MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-5.0"], packages: ["xorg-dev", "clang-5.0", "g++-7"] } }
@@ -41,9 +17,14 @@ matrix:
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-6.0"], packages: ["xorg-dev", "clang-6.0", "g++-7"] } }
env: MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0"
- os: osx
osx_image: xcode8.3
compiler: clang
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-7"], packages: ["xorg-dev", "clang-7", "g++-7"] } }
env: MATRIX_EVAL="CC=clang-7 && CXX=clang++-7"
- os: linux
dist: trusty
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-8"], packages: ["xorg-dev", "clang-8", "g++-7"] } }
env: MATRIX_EVAL="CC=clang-8 && CXX=clang++-8"
- os: osx
osx_image: xcode9
compiler: clang

View File

@@ -1,4 +1,4 @@
# 3.8 version is required for `cxx_std_14`
# 3.8 version is required for `cxx_std_17`
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
if(NOT DEFINED PROJECT_NAME)
@@ -9,7 +9,7 @@ project(flat.hpp)
add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE headers)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
if(BUILD_AS_STANDALONE)
option(BUILD_WITH_UNBENCH "Build with benchmarks" OFF)

140
README.md
View File

@@ -10,14 +10,14 @@
[badge.travis]: https://img.shields.io/travis/BlackMATov/flat.hpp/master.svg?logo=travis
[badge.appveyor]: https://img.shields.io/appveyor/ci/BlackMATov/flat-hpp/master.svg?logo=appveyor
[badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/flat.hpp/master.svg?logo=codecov
[badge.language]: https://img.shields.io/badge/language-C%2B%2B14-red.svg
[badge.language]: https://img.shields.io/badge/language-C%2B%2B17-yellow.svg
[badge.license]: https://img.shields.io/badge/license-MIT-blue.svg
[badge.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C
[travis]: https://travis-ci.org/BlackMATov/flat.hpp
[appveyor]: https://ci.appveyor.com/project/BlackMATov/flat-hpp
[codecov]: https://codecov.io/gh/BlackMATov/flat.hpp
[language]: https://en.wikipedia.org/wiki/C%2B%2B14
[language]: https://en.wikipedia.org/wiki/C%2B%2B17
[license]: https://en.wikipedia.org/wiki/MIT_License
[paypal]: https://www.paypal.me/matov
@@ -133,30 +133,30 @@ flat_set& operator=(std::initializer_list<value_type> ilist);
### Iterators
```cpp
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
iterator end();
const_iterator end() const;
const_iterator cend() const;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
const_reverse_iterator crbegin() const;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
reverse_iterator rend();
const_reverse_iterator rend() const;
const_reverse_iterator crend() const;
```
### Capacity
```cpp
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
size_type capacity() const noexcept;
bool empty() const;
size_type size() const;
size_type max_size() const;
size_type capacity() const;
void reserve(size_type ncapacity);
void shrink_to_fit();
```
@@ -179,7 +179,7 @@ std::pair<iterator, bool> emplace(Args&&... args);
template < typename... Args >
iterator emplace_hint(const_iterator hint, Args&&... args);
void clear() noexcept;
void clear();
iterator erase(const_iterator iter);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);
@@ -354,30 +354,30 @@ flat_map& operator=(std::initializer_list<value_type> ilist);
### Iterators
```cpp
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
iterator end();
const_iterator end() const;
const_iterator cend() const;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
const_reverse_iterator crbegin() const;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
reverse_iterator rend();
const_reverse_iterator rend() const;
const_reverse_iterator crend() const;
```
### Capacity
```cpp
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
size_type capacity() const noexcept;
bool empty() const;
size_type size() const;
size_type max_size() const;
size_type capacity() const;
void reserve(size_type ncapacity);
void shrink_to_fit();
```
@@ -410,7 +410,7 @@ std::pair<iterator, bool> emplace(Args&&... args);
template < typename... Args >
iterator emplace_hint(const_iterator hint, Args&&... args);
void clear() noexcept;
void clear();
iterator erase(const_iterator iter);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);
@@ -585,30 +585,30 @@ flat_multiset& operator=(std::initializer_list<value_type> ilist);
### Iterators
```cpp
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
iterator end();
const_iterator end() const;
const_iterator cend() const;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
const_reverse_iterator crbegin() const;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
reverse_iterator rend();
const_reverse_iterator rend() const;
const_reverse_iterator crend() const;
```
### Capacity
```cpp
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
size_type capacity() const noexcept;
bool empty() const;
size_type size() const;
size_type max_size() const;
size_type capacity() const;
void reserve(size_type ncapacity);
void shrink_to_fit();
```
@@ -631,7 +631,7 @@ iterator emplace(Args&&... args);
template < typename... Args >
iterator emplace_hint(const_iterator hint, Args&&... args);
void clear() noexcept;
void clear();
iterator erase(const_iterator iter);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);
@@ -806,30 +806,30 @@ flat_multimap& operator=(std::initializer_list<value_type> ilist);
### Iterators
```cpp
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
iterator end();
const_iterator end() const;
const_iterator cend() const;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
const_reverse_iterator crbegin() const;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
reverse_iterator rend();
const_reverse_iterator rend() const;
const_reverse_iterator crend() const;
```
### Capacity
```cpp
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
size_type capacity() const noexcept;
bool empty() const;
size_type size() const;
size_type max_size() const;
size_type capacity() const;
void reserve(size_type ncapacity);
void shrink_to_fit();
```
@@ -862,7 +862,7 @@ iterator emplace(Args&&... args);
template < typename... Args >
iterator emplace_hint(const_iterator hint, Args&&... args);
void clear() noexcept;
void clear();
iterator erase(const_iterator iter);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const key_type& key);

View File

@@ -99,8 +99,8 @@ namespace flat_hpp
};
public:
flat_map()
noexcept(std::is_nothrow_default_constructible<base_type>::value
&& std::is_nothrow_default_constructible<container_type>::value) {}
noexcept(std::is_nothrow_default_constructible_v<base_type>
&& std::is_nothrow_default_constructible_v<container_type>) {}
explicit flat_map(const Compare& c)
: base_type(c) {}
@@ -181,35 +181,83 @@ namespace flat_hpp
return *this;
}
iterator begin() noexcept { return data_.begin(); }
const_iterator begin() const noexcept { return data_.begin(); }
const_iterator cbegin() const noexcept { return data_.cbegin(); }
iterator begin()
noexcept(noexcept(std::declval<container_type&>().begin())) {
return data_.begin();
}
iterator end() noexcept { return data_.end(); }
const_iterator end() const noexcept { return data_.end(); }
const_iterator cend() const noexcept { return data_.cend(); }
const_iterator begin() const
noexcept(noexcept(std::declval<const container_type&>().begin())) {
return data_.begin();
}
reverse_iterator rbegin() noexcept { return data_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return data_.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return data_.crbegin(); }
const_iterator cbegin() const
noexcept(noexcept(std::declval<const container_type&>().cbegin())) {
return data_.cbegin();
}
reverse_iterator rend() noexcept { return data_.rend(); }
const_reverse_iterator rend() const noexcept { return data_.rend(); }
const_reverse_iterator crend() const noexcept { return data_.crend(); }
iterator end()
noexcept(noexcept(std::declval<container_type&>().end())) {
return data_.end();
}
bool empty() const noexcept {
const_iterator end() const
noexcept(noexcept(std::declval<const container_type&>().end())) {
return data_.end();
}
const_iterator cend() const
noexcept(noexcept(std::declval<const container_type&>().cend())) {
return data_.cend();
}
reverse_iterator rbegin()
noexcept(noexcept(std::declval<container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator rbegin() const
noexcept(noexcept(std::declval<const container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator crbegin() const
noexcept(noexcept(std::declval<const container_type&>().crbegin())) {
return data_.crbegin();
}
reverse_iterator rend()
noexcept(noexcept(std::declval<container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator rend() const
noexcept(noexcept(std::declval<const container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator crend() const
noexcept(noexcept(std::declval<const container_type&>().crend())) {
return data_.crend();
}
bool empty() const
noexcept(noexcept(std::declval<const container_type&>().empty())) {
return data_.empty();
}
size_type size() const noexcept {
size_type size() const
noexcept(noexcept(std::declval<const container_type&>().size())) {
return data_.size();
}
size_type max_size() const noexcept {
size_type max_size() const
noexcept(noexcept(std::declval<const container_type&>().max_size())) {
return data_.max_size();
}
size_type capacity() const noexcept {
size_type capacity() const
noexcept(noexcept(std::declval<const container_type&>().capacity())) {
return data_.capacity();
}
@@ -300,7 +348,8 @@ namespace flat_hpp
return insert(hint, value_type(std::forward<Args>(args)...));
}
void clear() noexcept {
void clear()
noexcept(noexcept(std::declval<container_type&>().clear())) {
data_.clear();
}
@@ -319,7 +368,10 @@ namespace flat_hpp
: 0;
}
void swap(flat_map& other) {
void swap(flat_map& other)
noexcept(std::is_nothrow_swappable_v<base_type>
&& std::is_nothrow_swappable_v<container_type>)
{
using std::swap;
swap(
static_cast<base_type&>(*this),
@@ -397,6 +449,7 @@ namespace flat_hpp
void swap(
flat_map<Key, Value, Compare, Container>& l,
flat_map<Key, Value, Compare, Container>& r)
noexcept(noexcept(l.swap(r)))
{
l.swap(r);
}

View File

@@ -99,8 +99,8 @@ namespace flat_hpp
};
public:
flat_multimap()
noexcept(std::is_nothrow_default_constructible<base_type>::value
&& std::is_nothrow_default_constructible<container_type>::value) {}
noexcept(std::is_nothrow_default_constructible_v<base_type>
&& std::is_nothrow_default_constructible_v<container_type>) {}
explicit flat_multimap(const Compare& c)
: base_type(c) {}
@@ -181,35 +181,83 @@ namespace flat_hpp
return *this;
}
iterator begin() noexcept { return data_.begin(); }
const_iterator begin() const noexcept { return data_.begin(); }
const_iterator cbegin() const noexcept { return data_.cbegin(); }
iterator begin()
noexcept(noexcept(std::declval<container_type&>().begin())) {
return data_.begin();
}
iterator end() noexcept { return data_.end(); }
const_iterator end() const noexcept { return data_.end(); }
const_iterator cend() const noexcept { return data_.cend(); }
const_iterator begin() const
noexcept(noexcept(std::declval<const container_type&>().begin())) {
return data_.begin();
}
reverse_iterator rbegin() noexcept { return data_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return data_.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return data_.crbegin(); }
const_iterator cbegin() const
noexcept(noexcept(std::declval<const container_type&>().cbegin())) {
return data_.cbegin();
}
reverse_iterator rend() noexcept { return data_.rend(); }
const_reverse_iterator rend() const noexcept { return data_.rend(); }
const_reverse_iterator crend() const noexcept { return data_.crend(); }
iterator end()
noexcept(noexcept(std::declval<container_type&>().end())) {
return data_.end();
}
bool empty() const noexcept {
const_iterator end() const
noexcept(noexcept(std::declval<const container_type&>().end())) {
return data_.end();
}
const_iterator cend() const
noexcept(noexcept(std::declval<const container_type&>().cend())) {
return data_.cend();
}
reverse_iterator rbegin()
noexcept(noexcept(std::declval<container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator rbegin() const
noexcept(noexcept(std::declval<const container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator crbegin() const
noexcept(noexcept(std::declval<const container_type&>().crbegin())) {
return data_.crbegin();
}
reverse_iterator rend()
noexcept(noexcept(std::declval<container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator rend() const
noexcept(noexcept(std::declval<const container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator crend() const
noexcept(noexcept(std::declval<const container_type&>().crend())) {
return data_.crend();
}
bool empty() const
noexcept(noexcept(std::declval<const container_type&>().empty())) {
return data_.empty();
}
size_type size() const noexcept {
size_type size() const
noexcept(noexcept(std::declval<const container_type&>().size())) {
return data_.size();
}
size_type max_size() const noexcept {
size_type max_size() const
noexcept(noexcept(std::declval<const container_type&>().max_size())) {
return data_.max_size();
}
size_type capacity() const noexcept {
size_type capacity() const
noexcept(noexcept(std::declval<const container_type&>().capacity())) {
return data_.capacity();
}
@@ -296,7 +344,8 @@ namespace flat_hpp
return insert(hint, value_type(std::forward<Args>(args)...));
}
void clear() noexcept {
void clear()
noexcept(noexcept(std::declval<container_type&>().clear())) {
data_.clear();
}
@@ -315,7 +364,10 @@ namespace flat_hpp
return r;
}
void swap(flat_multimap& other) {
void swap(flat_multimap& other)
noexcept(std::is_nothrow_swappable_v<base_type>
&& std::is_nothrow_swappable_v<container_type>)
{
using std::swap;
swap(
static_cast<base_type&>(*this),
@@ -393,6 +445,7 @@ namespace flat_hpp
void swap(
flat_multimap<Key, Value, Compare, Container>& l,
flat_multimap<Key, Value, Compare, Container>& r)
noexcept(noexcept(l.swap(r)))
{
l.swap(r);
}

View File

@@ -44,8 +44,8 @@ namespace flat_hpp
using const_reverse_iterator = typename Container::const_reverse_iterator;
public:
flat_multiset()
noexcept(std::is_nothrow_default_constructible<base_type>::value
&& std::is_nothrow_default_constructible<container_type>::value) {}
noexcept(std::is_nothrow_default_constructible_v<base_type>
&& std::is_nothrow_default_constructible_v<container_type>) {}
explicit flat_multiset(const Compare& c)
: base_type(c) {}
@@ -126,35 +126,83 @@ namespace flat_hpp
return *this;
}
iterator begin() noexcept { return data_.begin(); }
const_iterator begin() const noexcept { return data_.begin(); }
const_iterator cbegin() const noexcept { return data_.cbegin(); }
iterator begin()
noexcept(noexcept(std::declval<container_type&>().begin())) {
return data_.begin();
}
iterator end() noexcept { return data_.end(); }
const_iterator end() const noexcept { return data_.end(); }
const_iterator cend() const noexcept { return data_.cend(); }
const_iterator begin() const
noexcept(noexcept(std::declval<const container_type&>().begin())) {
return data_.begin();
}
reverse_iterator rbegin() noexcept { return data_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return data_.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return data_.crbegin(); }
const_iterator cbegin() const
noexcept(noexcept(std::declval<const container_type&>().cbegin())) {
return data_.cbegin();
}
reverse_iterator rend() noexcept { return data_.rend(); }
const_reverse_iterator rend() const noexcept { return data_.rend(); }
const_reverse_iterator crend() const noexcept { return data_.crend(); }
iterator end()
noexcept(noexcept(std::declval<container_type&>().end())) {
return data_.end();
}
bool empty() const noexcept {
const_iterator end() const
noexcept(noexcept(std::declval<const container_type&>().end())) {
return data_.end();
}
const_iterator cend() const
noexcept(noexcept(std::declval<const container_type&>().cend())) {
return data_.cend();
}
reverse_iterator rbegin()
noexcept(noexcept(std::declval<container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator rbegin() const
noexcept(noexcept(std::declval<const container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator crbegin() const
noexcept(noexcept(std::declval<const container_type&>().crbegin())) {
return data_.crbegin();
}
reverse_iterator rend()
noexcept(noexcept(std::declval<container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator rend() const
noexcept(noexcept(std::declval<const container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator crend() const
noexcept(noexcept(std::declval<const container_type&>().crend())) {
return data_.crend();
}
bool empty() const
noexcept(noexcept(std::declval<const container_type&>().empty())) {
return data_.empty();
}
size_type size() const noexcept {
size_type size() const
noexcept(noexcept(std::declval<const container_type&>().size())) {
return data_.size();
}
size_type max_size() const noexcept {
size_type max_size() const
noexcept(noexcept(std::declval<const container_type&>().max_size())) {
return data_.max_size();
}
size_type capacity() const noexcept {
size_type capacity() const
noexcept(noexcept(std::declval<const container_type&>().capacity())) {
return data_.capacity();
}
@@ -211,7 +259,8 @@ namespace flat_hpp
return insert(hint, value_type(std::forward<Args>(args)...));
}
void clear() noexcept {
void clear()
noexcept(noexcept(std::declval<container_type&>().clear())) {
data_.clear();
}
@@ -230,7 +279,10 @@ namespace flat_hpp
return r;
}
void swap(flat_multiset& other) {
void swap(flat_multiset& other)
noexcept(std::is_nothrow_swappable_v<base_type>
&& std::is_nothrow_swappable_v<container_type>)
{
using std::swap;
swap(
static_cast<base_type&>(*this),
@@ -301,6 +353,7 @@ namespace flat_hpp
void swap(
flat_multiset<Key, Compare, Container>& l,
flat_multiset<Key, Compare, Container>& r)
noexcept(noexcept(l.swap(r)))
{
l.swap(r);
}

View File

@@ -44,8 +44,8 @@ namespace flat_hpp
using const_reverse_iterator = typename Container::const_reverse_iterator;
public:
flat_set()
noexcept(std::is_nothrow_default_constructible<base_type>::value
&& std::is_nothrow_default_constructible<container_type>::value) {}
noexcept(std::is_nothrow_default_constructible_v<base_type>
&& std::is_nothrow_default_constructible_v<container_type>) {}
explicit flat_set(const Compare& c)
: base_type(c) {}
@@ -126,35 +126,83 @@ namespace flat_hpp
return *this;
}
iterator begin() noexcept { return data_.begin(); }
const_iterator begin() const noexcept { return data_.begin(); }
const_iterator cbegin() const noexcept { return data_.cbegin(); }
iterator begin()
noexcept(noexcept(std::declval<container_type&>().begin())) {
return data_.begin();
}
iterator end() noexcept { return data_.end(); }
const_iterator end() const noexcept { return data_.end(); }
const_iterator cend() const noexcept { return data_.cend(); }
const_iterator begin() const
noexcept(noexcept(std::declval<const container_type&>().begin())) {
return data_.begin();
}
reverse_iterator rbegin() noexcept { return data_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return data_.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return data_.crbegin(); }
const_iterator cbegin() const
noexcept(noexcept(std::declval<const container_type&>().cbegin())) {
return data_.cbegin();
}
reverse_iterator rend() noexcept { return data_.rend(); }
const_reverse_iterator rend() const noexcept { return data_.rend(); }
const_reverse_iterator crend() const noexcept { return data_.crend(); }
iterator end()
noexcept(noexcept(std::declval<container_type&>().end())) {
return data_.end();
}
bool empty() const noexcept {
const_iterator end() const
noexcept(noexcept(std::declval<const container_type&>().end())) {
return data_.end();
}
const_iterator cend() const
noexcept(noexcept(std::declval<const container_type&>().cend())) {
return data_.cend();
}
reverse_iterator rbegin()
noexcept(noexcept(std::declval<container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator rbegin() const
noexcept(noexcept(std::declval<const container_type&>().rbegin())) {
return data_.rbegin();
}
const_reverse_iterator crbegin() const
noexcept(noexcept(std::declval<const container_type&>().crbegin())) {
return data_.crbegin();
}
reverse_iterator rend()
noexcept(noexcept(std::declval<container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator rend() const
noexcept(noexcept(std::declval<const container_type&>().rend())) {
return data_.rend();
}
const_reverse_iterator crend() const
noexcept(noexcept(std::declval<const container_type&>().crend())) {
return data_.crend();
}
bool empty() const
noexcept(noexcept(std::declval<const container_type&>().empty())) {
return data_.empty();
}
size_type size() const noexcept {
size_type size() const
noexcept(noexcept(std::declval<const container_type&>().size())) {
return data_.size();
}
size_type max_size() const noexcept {
size_type max_size() const
noexcept(noexcept(std::declval<const container_type&>().max_size())) {
return data_.max_size();
}
size_type capacity() const noexcept {
size_type capacity() const
noexcept(noexcept(std::declval<const container_type&>().capacity())) {
return data_.capacity();
}
@@ -215,7 +263,8 @@ namespace flat_hpp
return insert(hint, value_type(std::forward<Args>(args)...));
}
void clear() noexcept {
void clear()
noexcept(noexcept(std::declval<container_type&>().clear())) {
data_.clear();
}
@@ -234,7 +283,10 @@ namespace flat_hpp
: 0;
}
void swap(flat_set& other) {
void swap(flat_set& other)
noexcept(std::is_nothrow_swappable_v<base_type>
&& std::is_nothrow_swappable_v<container_type>)
{
using std::swap;
swap(
static_cast<base_type&>(*this),
@@ -305,6 +357,7 @@ namespace flat_hpp
void swap(
flat_set<Key, Compare, Container>& l,
flat_set<Key, Compare, Container>& r)
noexcept(noexcept(l.swap(r)))
{
l.swap(r);
}

View File

@@ -14,62 +14,6 @@ using namespace flat_hpp;
namespace
{
template < typename T >
class dummy_allocator {
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using value_type = T;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
template < typename U >
struct rebind { using other = dummy_allocator<U>; };
dummy_allocator() = default;
dummy_allocator(int i) : i(i) {}
template < typename U >
dummy_allocator(const dummy_allocator<U>& o) noexcept {
i = o.i;
}
T* allocate(std::size_t n) noexcept {
return static_cast<T*>(std::malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n) noexcept {
(void)n;
std::free(p);
}
template < typename U, typename... Args >
void construct(U* p, Args&&... args) {
::new((void*)p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~T();
}
int i = 0;
};
template < typename T, typename U >
bool operator==(const dummy_allocator<T>&, const dummy_allocator<U>&) noexcept {
return true;
}
template < typename T, typename U >
bool operator!=(const dummy_allocator<T>& l, const dummy_allocator<U>& r) noexcept {
return !(l == r);
}
template < typename T >
class dummy_less {
public:
@@ -81,6 +25,28 @@ namespace
int i = 0;
};
template < typename T >
class dummy_less2 {
dummy_less2() = default;
dummy_less2(dummy_less2&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
void swap(dummy_less2<T>&, dummy_less2<T>&) noexcept {
}
template < typename T >
class dummy_less3 {
dummy_less3() = default;
dummy_less3(dummy_less3&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
constexpr std::add_const_t<T>& my_as_const(T& t) noexcept {
return t;
@@ -97,55 +63,57 @@ TEST_CASE("flat_map") {
REQUIRE(sizeof(vc) == sizeof(int));
}
SECTION("noexcept") {
using alloc_t = dummy_allocator<std::pair<int,unsigned>>;
using alloc_t = std::allocator<std::pair<int,unsigned>>;
using map_t = flat_map<int, unsigned, dummy_less<int>, std::vector<std::pair<int,unsigned>, alloc_t>>;
using map2_t = flat_map<int, unsigned, dummy_less2<int>>;
using map3_t = flat_map<int, unsigned, dummy_less3<int>>;
static_assert(
std::is_nothrow_default_constructible<map_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_constructible<map_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_assignable<map_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_nothrow_default_constructible_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_move_constructible_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_move_assignable_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<map2_t>);
STATIC_REQUIRE(!std::is_nothrow_swappable_v<map3_t>);
STATIC_REQUIRE(noexcept(std::declval<map_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().cbegin()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().cend()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().crbegin()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().crend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().empty()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().size()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().max_size()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().capacity()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().clear()));
}
SECTION("types") {
using map_t = flat_map<int, unsigned>;
static_assert(
std::is_same<map_t::key_type, int>::value,
"unit test static error");
static_assert(
std::is_same<map_t::mapped_type, unsigned>::value,
"unit test static error");
static_assert(
std::is_same<map_t::value_type, std::pair<int, unsigned>>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::key_type, int>);
STATIC_REQUIRE(std::is_same_v<map_t::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<map_t::value_type, std::pair<int, unsigned>>);
static_assert(
std::is_same<map_t::size_type, std::size_t>::value,
"unit test static error");
static_assert(
std::is_same<map_t::difference_type, std::ptrdiff_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::size_type, std::size_t>);
STATIC_REQUIRE(std::is_same_v<map_t::difference_type, std::ptrdiff_t>);
static_assert(
std::is_same<map_t::reference, std::pair<int, unsigned>&>::value,
"unit test static error");
static_assert(
std::is_same<map_t::const_reference, const std::pair<int, unsigned>&>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::reference, std::pair<int, unsigned>&>);
STATIC_REQUIRE(std::is_same_v<map_t::const_reference, const std::pair<int, unsigned>&>);
static_assert(
std::is_same<map_t::pointer, std::pair<int, unsigned>*>::value,
"unit test static error");
static_assert(
std::is_same<map_t::const_pointer, const std::pair<int, unsigned>*>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::pointer, std::pair<int, unsigned>*>);
STATIC_REQUIRE(std::is_same_v<map_t::const_pointer, const std::pair<int, unsigned>*>);
}
SECTION("ctors") {
using alloc_t = dummy_allocator<
using alloc_t = std::allocator<
std::pair<int,unsigned>>;
using map_t = flat_map<
@@ -203,9 +171,9 @@ TEST_CASE("flat_map") {
auto s2 = std::move(s1);
REQUIRE(s1.empty());
REQUIRE(s2 == map_t{{0,1}, {1,2}});
auto s3 = map_t(s2, alloc_t(42));
auto s3 = map_t(s2, alloc_t());
REQUIRE(s2 == s3);
auto s4 = map_t(std::move(s3), alloc_t(21));
auto s4 = map_t(std::move(s3), alloc_t());
REQUIRE(s3.empty());
REQUIRE(s4 == map_t{{0,1}, {1,2}});
}
@@ -268,7 +236,7 @@ TEST_CASE("flat_map") {
REQUIRE(s0.capacity() == 3);
REQUIRE(s0 == map_t{{1,2},{2,3},{3,4}});
using alloc2_t = dummy_allocator<
using alloc2_t = std::allocator<
std::pair<int, unsigned>>;
using map2_t = flat_map<

View File

@@ -14,62 +14,6 @@ using namespace flat_hpp;
namespace
{
template < typename T >
class dummy_allocator {
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using value_type = T;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
template < typename U >
struct rebind { using other = dummy_allocator<U>; };
dummy_allocator() = default;
dummy_allocator(int i) : i(i) {}
template < typename U >
dummy_allocator(const dummy_allocator<U>& o) noexcept {
i = o.i;
}
T* allocate(std::size_t n) noexcept {
return static_cast<T*>(std::malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n) noexcept {
(void)n;
std::free(p);
}
template < typename U, typename... Args >
void construct(U* p, Args&&... args) {
::new((void*)p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~T();
}
int i = 0;
};
template < typename T, typename U >
bool operator==(const dummy_allocator<T>&, const dummy_allocator<U>&) noexcept {
return true;
}
template < typename T, typename U >
bool operator!=(const dummy_allocator<T>& l, const dummy_allocator<U>& r) noexcept {
return !(l == r);
}
template < typename T >
class dummy_less {
public:
@@ -81,6 +25,28 @@ namespace
int i = 0;
};
template < typename T >
class dummy_less2 {
dummy_less2() = default;
dummy_less2(dummy_less2&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
void swap(dummy_less2<T>&, dummy_less2<T>&) noexcept {
}
template < typename T >
class dummy_less3 {
dummy_less3() = default;
dummy_less3(dummy_less3&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
constexpr std::add_const_t<T>& my_as_const(T& t) noexcept {
return t;
@@ -97,55 +63,57 @@ TEST_CASE("flat_multimap") {
REQUIRE(sizeof(vc) == sizeof(int));
}
SECTION("noexcept") {
using alloc_t = dummy_allocator<std::pair<int,unsigned>>;
using alloc_t = std::allocator<std::pair<int,unsigned>>;
using map_t = flat_multimap<int, unsigned, dummy_less<int>, std::vector<std::pair<int,unsigned>, alloc_t>>;
using map2_t = flat_multimap<int, unsigned, dummy_less2<int>>;
using map3_t = flat_multimap<int, unsigned, dummy_less3<int>>;
static_assert(
std::is_nothrow_default_constructible<map_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_constructible<map_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_assignable<map_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_nothrow_default_constructible_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_move_constructible_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_move_assignable_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<map_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<map2_t>);
STATIC_REQUIRE(!std::is_nothrow_swappable_v<map3_t>);
STATIC_REQUIRE(noexcept(std::declval<map_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().cbegin()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().cend()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().crbegin()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().crend()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().empty()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().size()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().max_size()));
STATIC_REQUIRE(noexcept(std::declval<const map_t&>().capacity()));
STATIC_REQUIRE(noexcept(std::declval<map_t&>().clear()));
}
SECTION("types") {
using map_t = flat_multimap<int, unsigned>;
static_assert(
std::is_same<map_t::key_type, int>::value,
"unit test static error");
static_assert(
std::is_same<map_t::mapped_type, unsigned>::value,
"unit test static error");
static_assert(
std::is_same<map_t::value_type, std::pair<int, unsigned>>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::key_type, int>);
STATIC_REQUIRE(std::is_same_v<map_t::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<map_t::value_type, std::pair<int, unsigned>>);
static_assert(
std::is_same<map_t::size_type, std::size_t>::value,
"unit test static error");
static_assert(
std::is_same<map_t::difference_type, std::ptrdiff_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::size_type, std::size_t>);
STATIC_REQUIRE(std::is_same_v<map_t::difference_type, std::ptrdiff_t>);
static_assert(
std::is_same<map_t::reference, std::pair<int, unsigned>&>::value,
"unit test static error");
static_assert(
std::is_same<map_t::const_reference, const std::pair<int, unsigned>&>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::reference, std::pair<int, unsigned>&>);
STATIC_REQUIRE(std::is_same_v<map_t::const_reference, const std::pair<int, unsigned>&>);
static_assert(
std::is_same<map_t::pointer, std::pair<int, unsigned>*>::value,
"unit test static error");
static_assert(
std::is_same<map_t::const_pointer, const std::pair<int, unsigned>*>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<map_t::pointer, std::pair<int, unsigned>*>);
STATIC_REQUIRE(std::is_same_v<map_t::const_pointer, const std::pair<int, unsigned>*>);
}
SECTION("ctors") {
using alloc_t = dummy_allocator<
using alloc_t = std::allocator<
std::pair<int,unsigned>>;
using map_t = flat_multimap<
@@ -203,9 +171,9 @@ TEST_CASE("flat_multimap") {
auto s2 = std::move(s1);
REQUIRE(s1.empty());
REQUIRE(s2 == map_t{{0,1}, {1,2}});
auto s3 = map_t(s2, alloc_t(42));
auto s3 = map_t(s2, alloc_t());
REQUIRE(s2 == s3);
auto s4 = map_t(std::move(s3), alloc_t(21));
auto s4 = map_t(std::move(s3), alloc_t());
REQUIRE(s3.empty());
REQUIRE(s4 == map_t{{0,1}, {1,2}});
}
@@ -268,7 +236,7 @@ TEST_CASE("flat_multimap") {
REQUIRE(s0.capacity() == 3);
REQUIRE(s0 == map_t{{1,2},{2,3},{3,4}});
using alloc2_t = dummy_allocator<
using alloc2_t = std::allocator<
std::pair<int, unsigned>>;
using map2_t = flat_multimap<

View File

@@ -14,62 +14,6 @@ using namespace flat_hpp;
namespace
{
template < typename T >
class dummy_allocator {
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using value_type = T;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
template < typename U >
struct rebind { using other = dummy_allocator<U>; };
dummy_allocator() = default;
dummy_allocator(int i) : i(i) {}
template < typename U >
dummy_allocator(const dummy_allocator<U>& o) noexcept {
i = o.i;
}
T* allocate(std::size_t n) noexcept {
return static_cast<T*>(std::malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n) noexcept {
(void)n;
std::free(p);
}
template < typename U, typename... Args >
void construct(U* p, Args&&... args) {
::new((void*)p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~T();
}
int i = 0;
};
template < typename T, typename U >
bool operator==(const dummy_allocator<T>&, const dummy_allocator<U>&) noexcept {
return true;
}
template < typename T, typename U >
bool operator!=(const dummy_allocator<T>& l, const dummy_allocator<U>& r) noexcept {
return !(l == r);
}
template < typename T >
class dummy_less {
public:
@@ -81,6 +25,28 @@ namespace
int i = 0;
};
template < typename T >
class dummy_less2 {
dummy_less2() = default;
dummy_less2(dummy_less2&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
void swap(dummy_less2<T>&, dummy_less2<T>&) noexcept {
}
template < typename T >
class dummy_less3 {
dummy_less3() = default;
dummy_less3(dummy_less3&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
constexpr std::add_const_t<T>& my_as_const(T& t) noexcept {
return t;
@@ -97,52 +63,56 @@ TEST_CASE("flat_multiset") {
REQUIRE(sizeof(vc) == sizeof(int));
}
SECTION("noexcept") {
using alloc_t = dummy_allocator<int>;
using alloc_t = std::allocator<int>;
using set_t = flat_multiset<int, dummy_less<int>, std::vector<int, alloc_t>>;
using set2_t = flat_multiset<int, dummy_less2<int>>;
using set3_t = flat_multiset<int, dummy_less3<int>>;
static_assert(
std::is_nothrow_default_constructible<set_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_constructible<set_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_assignable<set_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_nothrow_default_constructible_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_move_constructible_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_move_assignable_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<set2_t>);
STATIC_REQUIRE(!std::is_nothrow_swappable_v<set3_t>);
STATIC_REQUIRE(noexcept(std::declval<set_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().cbegin()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().cend()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().crbegin()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().crend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().empty()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().size()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().max_size()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().capacity()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().clear()));
}
SECTION("types") {
using set_t = flat_multiset<int>;
static_assert(
std::is_same<set_t::key_type, int>::value,
"unit test static error");
static_assert(
std::is_same<set_t::value_type, int>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::key_type, int>);
STATIC_REQUIRE(std::is_same_v<set_t::value_type, int>);
static_assert(
std::is_same<set_t::size_type, std::size_t>::value,
"unit test static error");
static_assert(
std::is_same<set_t::difference_type, std::ptrdiff_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::size_type, std::size_t>);
STATIC_REQUIRE(std::is_same_v<set_t::difference_type, std::ptrdiff_t>);
static_assert(
std::is_same<set_t::reference, int&>::value,
"unit test static error");
static_assert(
std::is_same<set_t::const_reference, const int&>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::reference, int&>);
STATIC_REQUIRE(std::is_same_v<set_t::const_reference, const int&>);
static_assert(
std::is_same<set_t::pointer, int*>::value,
"unit test static error");
static_assert(
std::is_same<set_t::const_pointer, const int*>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::pointer, int*>);
STATIC_REQUIRE(std::is_same_v<set_t::const_pointer, const int*>);
}
SECTION("ctors") {
using alloc_t = dummy_allocator<int>;
using alloc_t = std::allocator<int>;
using set_t = flat_multiset<int, std::less<int>, std::vector<int, alloc_t>>;
using set2_t = flat_multiset<int, std::greater<int>, std::vector<int, alloc_t>>;
using vec_t = std::vector<int>;
@@ -187,9 +157,9 @@ TEST_CASE("flat_multiset") {
auto s2 = std::move(s1);
REQUIRE(s1.empty());
REQUIRE(s2 == set_t{0,1,2});
auto s3 = set_t(s2, alloc_t(42));
auto s3 = set_t(s2, alloc_t());
REQUIRE(s2 == s3);
auto s4 = set_t(std::move(s3), alloc_t(21));
auto s4 = set_t(std::move(s3), alloc_t());
REQUIRE(s3.empty());
REQUIRE(s4 == set_t{0,1,2});
}
@@ -252,7 +222,7 @@ TEST_CASE("flat_multiset") {
REQUIRE(s0.capacity() == 3);
REQUIRE(s0 == set_t{1,2,3});
using alloc2_t = dummy_allocator<int>;
using alloc2_t = std::allocator<int>;
using set2_t = flat_multiset<
int,

View File

@@ -14,62 +14,6 @@ using namespace flat_hpp;
namespace
{
template < typename T >
class dummy_allocator {
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using value_type = T;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
template < typename U >
struct rebind { using other = dummy_allocator<U>; };
dummy_allocator() = default;
dummy_allocator(int i) : i(i) {}
template < typename U >
dummy_allocator(const dummy_allocator<U>& o) noexcept {
i = o.i;
}
T* allocate(std::size_t n) noexcept {
return static_cast<T*>(std::malloc(sizeof(T) * n));
}
void deallocate(T* p, std::size_t n) noexcept {
(void)n;
std::free(p);
}
template < typename U, typename... Args >
void construct(U* p, Args&&... args) {
::new((void*)p) U(std::forward<Args>(args)...);
}
void destroy(pointer p) {
p->~T();
}
int i = 0;
};
template < typename T, typename U >
bool operator==(const dummy_allocator<T>&, const dummy_allocator<U>&) noexcept {
return true;
}
template < typename T, typename U >
bool operator!=(const dummy_allocator<T>& l, const dummy_allocator<U>& r) noexcept {
return !(l == r);
}
template < typename T >
class dummy_less {
public:
@@ -81,6 +25,28 @@ namespace
int i = 0;
};
template < typename T >
class dummy_less2 {
dummy_less2() = default;
dummy_less2(dummy_less2&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
void swap(dummy_less2<T>&, dummy_less2<T>&) noexcept {
}
template < typename T >
class dummy_less3 {
dummy_less3() = default;
dummy_less3(dummy_less3&&) noexcept(false) {}
bool operator()(const T& l, const T& r) const {
return l < r;
}
};
template < typename T >
constexpr std::add_const_t<T>& my_as_const(T& t) noexcept {
return t;
@@ -97,52 +63,56 @@ TEST_CASE("flat_set") {
REQUIRE(sizeof(vc) == sizeof(int));
}
SECTION("noexcept") {
using alloc_t = dummy_allocator<int>;
using alloc_t = std::allocator<int>;
using set_t = flat_set<int, dummy_less<int>, std::vector<int, alloc_t>>;
using set2_t = flat_set<int, dummy_less2<int>>;
using set3_t = flat_set<int, dummy_less3<int>>;
static_assert(
std::is_nothrow_default_constructible<set_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_constructible<set_t>::value,
"unit test static error");
static_assert(
std::is_nothrow_move_assignable<set_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_nothrow_default_constructible_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_move_constructible_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_move_assignable_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<set_t>);
STATIC_REQUIRE(std::is_nothrow_swappable_v<set2_t>);
STATIC_REQUIRE(!std::is_nothrow_swappable_v<set3_t>);
STATIC_REQUIRE(noexcept(std::declval<set_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().begin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().cbegin()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().end()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().cend()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().rbegin()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().crbegin()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().rend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().crend()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().empty()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().size()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().max_size()));
STATIC_REQUIRE(noexcept(std::declval<const set_t&>().capacity()));
STATIC_REQUIRE(noexcept(std::declval<set_t&>().clear()));
}
SECTION("types") {
using set_t = flat_set<int>;
static_assert(
std::is_same<set_t::key_type, int>::value,
"unit test static error");
static_assert(
std::is_same<set_t::value_type, int>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::key_type, int>);
STATIC_REQUIRE(std::is_same_v<set_t::value_type, int>);
static_assert(
std::is_same<set_t::size_type, std::size_t>::value,
"unit test static error");
static_assert(
std::is_same<set_t::difference_type, std::ptrdiff_t>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::size_type, std::size_t>);
STATIC_REQUIRE(std::is_same_v<set_t::difference_type, std::ptrdiff_t>);
static_assert(
std::is_same<set_t::reference, int&>::value,
"unit test static error");
static_assert(
std::is_same<set_t::const_reference, const int&>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::reference, int&>);
STATIC_REQUIRE(std::is_same_v<set_t::const_reference, const int&>);
static_assert(
std::is_same<set_t::pointer, int*>::value,
"unit test static error");
static_assert(
std::is_same<set_t::const_pointer, const int*>::value,
"unit test static error");
STATIC_REQUIRE(std::is_same_v<set_t::pointer, int*>);
STATIC_REQUIRE(std::is_same_v<set_t::const_pointer, const int*>);
}
SECTION("ctors") {
using alloc_t = dummy_allocator<int>;
using alloc_t = std::allocator<int>;
using set_t = flat_set<int, std::less<int>, std::vector<int, alloc_t>>;
using set2_t = flat_set<int, std::greater<int>, std::vector<int, alloc_t>>;
using vec_t = std::vector<int>;
@@ -187,9 +157,9 @@ TEST_CASE("flat_set") {
auto s2 = std::move(s1);
REQUIRE(s1.empty());
REQUIRE(s2 == set_t{0,1,2});
auto s3 = set_t(s2, alloc_t(42));
auto s3 = set_t(s2, alloc_t());
REQUIRE(s2 == s3);
auto s4 = set_t(std::move(s3), alloc_t(21));
auto s4 = set_t(std::move(s3), alloc_t());
REQUIRE(s3.empty());
REQUIRE(s4 == set_t{0,1,2});
}
@@ -252,7 +222,7 @@ TEST_CASE("flat_set") {
REQUIRE(s0.capacity() == 3);
REQUIRE(s0 == set_t{1,2,3});
using alloc2_t = dummy_allocator<int>;
using alloc2_t = std::allocator<int>;
using set2_t = flat_set<
int,