diff --git a/.appveyor.yml b/.appveyor.yml index 62edb10..27089cb 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,6 +3,7 @@ shallow_clone: true image: - Visual Studio 2015 - Visual Studio 2017 + - Visual Studio 2019 Preview platform: - Win32 - x64 diff --git a/.travis.yml b/.travis.yml index 5ea4d0f..6a22839 100644 --- a/.travis.yml +++ b/.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 diff --git a/CMakeLists.txt b/CMakeLists.txt index c62b32d..01df7af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 52e75b5..8840b64 100644 --- a/README.md +++ b/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 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 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 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 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 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 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); diff --git a/headers/flat_hpp/flat_map.hpp b/headers/flat_hpp/flat_map.hpp index 191e310..54baa50 100644 --- a/headers/flat_hpp/flat_map.hpp +++ b/headers/flat_hpp/flat_map.hpp @@ -99,8 +99,8 @@ namespace flat_hpp }; public: flat_map() - noexcept(std::is_nothrow_default_constructible::value - && std::is_nothrow_default_constructible::value) {} + noexcept(std::is_nothrow_default_constructible_v + && std::is_nothrow_default_constructible_v) {} 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().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().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().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().end())) { + return data_.end(); + } - bool empty() const noexcept { + const_iterator end() const + noexcept(noexcept(std::declval().end())) { + return data_.end(); + } + + const_iterator cend() const + noexcept(noexcept(std::declval().cend())) { + return data_.cend(); + } + + reverse_iterator rbegin() + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator rbegin() const + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator crbegin() const + noexcept(noexcept(std::declval().crbegin())) { + return data_.crbegin(); + } + + reverse_iterator rend() + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator rend() const + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator crend() const + noexcept(noexcept(std::declval().crend())) { + return data_.crend(); + } + + bool empty() const + noexcept(noexcept(std::declval().empty())) { return data_.empty(); } - size_type size() const noexcept { + size_type size() const + noexcept(noexcept(std::declval().size())) { return data_.size(); } - size_type max_size() const noexcept { + size_type max_size() const + noexcept(noexcept(std::declval().max_size())) { return data_.max_size(); } - size_type capacity() const noexcept { + size_type capacity() const + noexcept(noexcept(std::declval().capacity())) { return data_.capacity(); } @@ -300,7 +348,8 @@ namespace flat_hpp return insert(hint, value_type(std::forward(args)...)); } - void clear() noexcept { + void clear() + noexcept(noexcept(std::declval().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 + && std::is_nothrow_swappable_v) + { using std::swap; swap( static_cast(*this), @@ -397,6 +449,7 @@ namespace flat_hpp void swap( flat_map& l, flat_map& r) + noexcept(noexcept(l.swap(r))) { l.swap(r); } diff --git a/headers/flat_hpp/flat_multimap.hpp b/headers/flat_hpp/flat_multimap.hpp index f6b5b7b..c20d395 100644 --- a/headers/flat_hpp/flat_multimap.hpp +++ b/headers/flat_hpp/flat_multimap.hpp @@ -99,8 +99,8 @@ namespace flat_hpp }; public: flat_multimap() - noexcept(std::is_nothrow_default_constructible::value - && std::is_nothrow_default_constructible::value) {} + noexcept(std::is_nothrow_default_constructible_v + && std::is_nothrow_default_constructible_v) {} 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().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().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().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().end())) { + return data_.end(); + } - bool empty() const noexcept { + const_iterator end() const + noexcept(noexcept(std::declval().end())) { + return data_.end(); + } + + const_iterator cend() const + noexcept(noexcept(std::declval().cend())) { + return data_.cend(); + } + + reverse_iterator rbegin() + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator rbegin() const + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator crbegin() const + noexcept(noexcept(std::declval().crbegin())) { + return data_.crbegin(); + } + + reverse_iterator rend() + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator rend() const + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator crend() const + noexcept(noexcept(std::declval().crend())) { + return data_.crend(); + } + + bool empty() const + noexcept(noexcept(std::declval().empty())) { return data_.empty(); } - size_type size() const noexcept { + size_type size() const + noexcept(noexcept(std::declval().size())) { return data_.size(); } - size_type max_size() const noexcept { + size_type max_size() const + noexcept(noexcept(std::declval().max_size())) { return data_.max_size(); } - size_type capacity() const noexcept { + size_type capacity() const + noexcept(noexcept(std::declval().capacity())) { return data_.capacity(); } @@ -296,7 +344,8 @@ namespace flat_hpp return insert(hint, value_type(std::forward(args)...)); } - void clear() noexcept { + void clear() + noexcept(noexcept(std::declval().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 + && std::is_nothrow_swappable_v) + { using std::swap; swap( static_cast(*this), @@ -393,6 +445,7 @@ namespace flat_hpp void swap( flat_multimap& l, flat_multimap& r) + noexcept(noexcept(l.swap(r))) { l.swap(r); } diff --git a/headers/flat_hpp/flat_multiset.hpp b/headers/flat_hpp/flat_multiset.hpp index a3b9c17..e6e9111 100644 --- a/headers/flat_hpp/flat_multiset.hpp +++ b/headers/flat_hpp/flat_multiset.hpp @@ -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::value - && std::is_nothrow_default_constructible::value) {} + noexcept(std::is_nothrow_default_constructible_v + && std::is_nothrow_default_constructible_v) {} 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().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().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().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().end())) { + return data_.end(); + } - bool empty() const noexcept { + const_iterator end() const + noexcept(noexcept(std::declval().end())) { + return data_.end(); + } + + const_iterator cend() const + noexcept(noexcept(std::declval().cend())) { + return data_.cend(); + } + + reverse_iterator rbegin() + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator rbegin() const + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator crbegin() const + noexcept(noexcept(std::declval().crbegin())) { + return data_.crbegin(); + } + + reverse_iterator rend() + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator rend() const + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator crend() const + noexcept(noexcept(std::declval().crend())) { + return data_.crend(); + } + + bool empty() const + noexcept(noexcept(std::declval().empty())) { return data_.empty(); } - size_type size() const noexcept { + size_type size() const + noexcept(noexcept(std::declval().size())) { return data_.size(); } - size_type max_size() const noexcept { + size_type max_size() const + noexcept(noexcept(std::declval().max_size())) { return data_.max_size(); } - size_type capacity() const noexcept { + size_type capacity() const + noexcept(noexcept(std::declval().capacity())) { return data_.capacity(); } @@ -211,7 +259,8 @@ namespace flat_hpp return insert(hint, value_type(std::forward(args)...)); } - void clear() noexcept { + void clear() + noexcept(noexcept(std::declval().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 + && std::is_nothrow_swappable_v) + { using std::swap; swap( static_cast(*this), @@ -301,6 +353,7 @@ namespace flat_hpp void swap( flat_multiset& l, flat_multiset& r) + noexcept(noexcept(l.swap(r))) { l.swap(r); } diff --git a/headers/flat_hpp/flat_set.hpp b/headers/flat_hpp/flat_set.hpp index 7d53d76..d5cf454 100644 --- a/headers/flat_hpp/flat_set.hpp +++ b/headers/flat_hpp/flat_set.hpp @@ -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::value - && std::is_nothrow_default_constructible::value) {} + noexcept(std::is_nothrow_default_constructible_v + && std::is_nothrow_default_constructible_v) {} 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().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().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().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().end())) { + return data_.end(); + } - bool empty() const noexcept { + const_iterator end() const + noexcept(noexcept(std::declval().end())) { + return data_.end(); + } + + const_iterator cend() const + noexcept(noexcept(std::declval().cend())) { + return data_.cend(); + } + + reverse_iterator rbegin() + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator rbegin() const + noexcept(noexcept(std::declval().rbegin())) { + return data_.rbegin(); + } + + const_reverse_iterator crbegin() const + noexcept(noexcept(std::declval().crbegin())) { + return data_.crbegin(); + } + + reverse_iterator rend() + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator rend() const + noexcept(noexcept(std::declval().rend())) { + return data_.rend(); + } + + const_reverse_iterator crend() const + noexcept(noexcept(std::declval().crend())) { + return data_.crend(); + } + + bool empty() const + noexcept(noexcept(std::declval().empty())) { return data_.empty(); } - size_type size() const noexcept { + size_type size() const + noexcept(noexcept(std::declval().size())) { return data_.size(); } - size_type max_size() const noexcept { + size_type max_size() const + noexcept(noexcept(std::declval().max_size())) { return data_.max_size(); } - size_type capacity() const noexcept { + size_type capacity() const + noexcept(noexcept(std::declval().capacity())) { return data_.capacity(); } @@ -215,7 +263,8 @@ namespace flat_hpp return insert(hint, value_type(std::forward(args)...)); } - void clear() noexcept { + void clear() + noexcept(noexcept(std::declval().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 + && std::is_nothrow_swappable_v) + { using std::swap; swap( static_cast(*this), @@ -305,6 +357,7 @@ namespace flat_hpp void swap( flat_set& l, flat_set& r) + noexcept(noexcept(l.swap(r))) { l.swap(r); } diff --git a/untests/flat_map_tests.cpp b/untests/flat_map_tests.cpp index 8c59382..b880656 100644 --- a/untests/flat_map_tests.cpp +++ b/untests/flat_map_tests.cpp @@ -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; }; - - dummy_allocator() = default; - dummy_allocator(int i) : i(i) {} - - template < typename U > - dummy_allocator(const dummy_allocator& o) noexcept { - i = o.i; - } - - T* allocate(std::size_t n) noexcept { - return static_cast(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)...); - } - - void destroy(pointer p) { - p->~T(); - } - - int i = 0; - }; - - template < typename T, typename U > - bool operator==(const dummy_allocator&, const dummy_allocator&) noexcept { - return true; - } - - template < typename T, typename U > - bool operator!=(const dummy_allocator& l, const dummy_allocator& 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&, dummy_less2&) 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& 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>; + using alloc_t = std::allocator>; using map_t = flat_map, std::vector, alloc_t>>; + using map2_t = flat_map>; + using map3_t = flat_map>; - static_assert( - std::is_nothrow_default_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_assignable::value, - "unit test static error"); + STATIC_REQUIRE(std::is_nothrow_default_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_assignable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(!std::is_nothrow_swappable_v); + + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().cbegin())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().cend())); + + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().crbegin())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().crend())); + + STATIC_REQUIRE(noexcept(std::declval().empty())); + STATIC_REQUIRE(noexcept(std::declval().size())); + STATIC_REQUIRE(noexcept(std::declval().max_size())); + STATIC_REQUIRE(noexcept(std::declval().capacity())); + + STATIC_REQUIRE(noexcept(std::declval().clear())); } SECTION("types") { using map_t = flat_map; - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v>); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same&>::value, - "unit test static error"); - static_assert( - std::is_same&>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v&>); + STATIC_REQUIRE(std::is_same_v&>); - static_assert( - std::is_same*>::value, - "unit test static error"); - static_assert( - std::is_same*>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v*>); + STATIC_REQUIRE(std::is_same_v*>); } SECTION("ctors") { - using alloc_t = dummy_allocator< + using alloc_t = std::allocator< std::pair>; 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>; using map2_t = flat_map< diff --git a/untests/flat_multimap_tests.cpp b/untests/flat_multimap_tests.cpp index 9f23252..3247874 100644 --- a/untests/flat_multimap_tests.cpp +++ b/untests/flat_multimap_tests.cpp @@ -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; }; - - dummy_allocator() = default; - dummy_allocator(int i) : i(i) {} - - template < typename U > - dummy_allocator(const dummy_allocator& o) noexcept { - i = o.i; - } - - T* allocate(std::size_t n) noexcept { - return static_cast(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)...); - } - - void destroy(pointer p) { - p->~T(); - } - - int i = 0; - }; - - template < typename T, typename U > - bool operator==(const dummy_allocator&, const dummy_allocator&) noexcept { - return true; - } - - template < typename T, typename U > - bool operator!=(const dummy_allocator& l, const dummy_allocator& 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&, dummy_less2&) 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& 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>; + using alloc_t = std::allocator>; using map_t = flat_multimap, std::vector, alloc_t>>; + using map2_t = flat_multimap>; + using map3_t = flat_multimap>; - static_assert( - std::is_nothrow_default_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_assignable::value, - "unit test static error"); + STATIC_REQUIRE(std::is_nothrow_default_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_assignable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(!std::is_nothrow_swappable_v); + + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().cbegin())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().cend())); + + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().crbegin())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().crend())); + + STATIC_REQUIRE(noexcept(std::declval().empty())); + STATIC_REQUIRE(noexcept(std::declval().size())); + STATIC_REQUIRE(noexcept(std::declval().max_size())); + STATIC_REQUIRE(noexcept(std::declval().capacity())); + + STATIC_REQUIRE(noexcept(std::declval().clear())); } SECTION("types") { using map_t = flat_multimap; - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v>); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same&>::value, - "unit test static error"); - static_assert( - std::is_same&>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v&>); + STATIC_REQUIRE(std::is_same_v&>); - static_assert( - std::is_same*>::value, - "unit test static error"); - static_assert( - std::is_same*>::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v*>); + STATIC_REQUIRE(std::is_same_v*>); } SECTION("ctors") { - using alloc_t = dummy_allocator< + using alloc_t = std::allocator< std::pair>; 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>; using map2_t = flat_multimap< diff --git a/untests/flat_multiset_tests.cpp b/untests/flat_multiset_tests.cpp index b3e6bb2..db7725b 100644 --- a/untests/flat_multiset_tests.cpp +++ b/untests/flat_multiset_tests.cpp @@ -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; }; - - dummy_allocator() = default; - dummy_allocator(int i) : i(i) {} - - template < typename U > - dummy_allocator(const dummy_allocator& o) noexcept { - i = o.i; - } - - T* allocate(std::size_t n) noexcept { - return static_cast(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)...); - } - - void destroy(pointer p) { - p->~T(); - } - - int i = 0; - }; - - template < typename T, typename U > - bool operator==(const dummy_allocator&, const dummy_allocator&) noexcept { - return true; - } - - template < typename T, typename U > - bool operator!=(const dummy_allocator& l, const dummy_allocator& 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&, dummy_less2&) 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& 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; + using alloc_t = std::allocator; using set_t = flat_multiset, std::vector>; + using set2_t = flat_multiset>; + using set3_t = flat_multiset>; - static_assert( - std::is_nothrow_default_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_assignable::value, - "unit test static error"); + STATIC_REQUIRE(std::is_nothrow_default_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_assignable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(!std::is_nothrow_swappable_v); + + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().cbegin())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().cend())); + + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().crbegin())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().crend())); + + STATIC_REQUIRE(noexcept(std::declval().empty())); + STATIC_REQUIRE(noexcept(std::declval().size())); + STATIC_REQUIRE(noexcept(std::declval().max_size())); + STATIC_REQUIRE(noexcept(std::declval().capacity())); + + STATIC_REQUIRE(noexcept(std::declval().clear())); } SECTION("types") { using set_t = flat_multiset; - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); } SECTION("ctors") { - using alloc_t = dummy_allocator; + using alloc_t = std::allocator; using set_t = flat_multiset, std::vector>; using set2_t = flat_multiset, std::vector>; using vec_t = std::vector; @@ -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; + using alloc2_t = std::allocator; using set2_t = flat_multiset< int, diff --git a/untests/flat_set_tests.cpp b/untests/flat_set_tests.cpp index 18f1e80..480dbeb 100644 --- a/untests/flat_set_tests.cpp +++ b/untests/flat_set_tests.cpp @@ -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; }; - - dummy_allocator() = default; - dummy_allocator(int i) : i(i) {} - - template < typename U > - dummy_allocator(const dummy_allocator& o) noexcept { - i = o.i; - } - - T* allocate(std::size_t n) noexcept { - return static_cast(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)...); - } - - void destroy(pointer p) { - p->~T(); - } - - int i = 0; - }; - - template < typename T, typename U > - bool operator==(const dummy_allocator&, const dummy_allocator&) noexcept { - return true; - } - - template < typename T, typename U > - bool operator!=(const dummy_allocator& l, const dummy_allocator& 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&, dummy_less2&) 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& 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; + using alloc_t = std::allocator; using set_t = flat_set, std::vector>; + using set2_t = flat_set>; + using set3_t = flat_set>; - static_assert( - std::is_nothrow_default_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_constructible::value, - "unit test static error"); - static_assert( - std::is_nothrow_move_assignable::value, - "unit test static error"); + STATIC_REQUIRE(std::is_nothrow_default_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_assignable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(std::is_nothrow_swappable_v); + STATIC_REQUIRE(!std::is_nothrow_swappable_v); + + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().begin())); + STATIC_REQUIRE(noexcept(std::declval().cbegin())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().end())); + STATIC_REQUIRE(noexcept(std::declval().cend())); + + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().rbegin())); + STATIC_REQUIRE(noexcept(std::declval().crbegin())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().rend())); + STATIC_REQUIRE(noexcept(std::declval().crend())); + + STATIC_REQUIRE(noexcept(std::declval().empty())); + STATIC_REQUIRE(noexcept(std::declval().size())); + STATIC_REQUIRE(noexcept(std::declval().max_size())); + STATIC_REQUIRE(noexcept(std::declval().capacity())); + + STATIC_REQUIRE(noexcept(std::declval().clear())); } SECTION("types") { using set_t = flat_set; - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); - static_assert( - std::is_same::value, - "unit test static error"); - static_assert( - std::is_same::value, - "unit test static error"); + STATIC_REQUIRE(std::is_same_v); + STATIC_REQUIRE(std::is_same_v); } SECTION("ctors") { - using alloc_t = dummy_allocator; + using alloc_t = std::allocator; using set_t = flat_set, std::vector>; using set2_t = flat_set, std::vector>; using vec_t = std::vector; @@ -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; + using alloc2_t = std::allocator; using set2_t = flat_set< int,