mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-13 01:36:27 +07:00
@@ -3,6 +3,7 @@ shallow_clone: true
|
||||
image:
|
||||
- Visual Studio 2015
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2019 Preview
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
35
.travis.yml
35
.travis.yml
@@ -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
|
||||
|
||||
@@ -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
140
README.md
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user