mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-13 01:36:27 +07:00
heterogeneous find, lower_bound and upper_bound
This commit is contained in:
@@ -35,7 +35,6 @@ before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == 'osx' ]; then
|
||||
brew update;
|
||||
brew upgrade cmake;
|
||||
brew install git-lfs;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" == 'linux' ]; then
|
||||
mkdir $HOME/cmake;
|
||||
|
||||
36
README.md
36
README.md
@@ -195,14 +195,23 @@ size_type count(const key_type& key) const;
|
||||
iterator find(const key_type& key);
|
||||
const_iterator find(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator find(const K& key);
|
||||
template < typename K > const_iterator find(const K& key) const;
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key);
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
|
||||
|
||||
iterator lower_bound(const key_type& key);
|
||||
const_iterator lower_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator lower_bound(const K& key);
|
||||
template < typename K > const_iterator lower_bound(const K& key) const;
|
||||
|
||||
iterator upper_bound(const key_type& key);
|
||||
const_iterator upper_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator upper_bound(const K& key);
|
||||
template < typename K > const_iterator upper_bound(const K& key) const;
|
||||
```
|
||||
|
||||
### Observers
|
||||
@@ -426,14 +435,23 @@ size_type count(const key_type& key) const;
|
||||
iterator find(const key_type& key);
|
||||
const_iterator find(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator find(const K& key);
|
||||
template < typename K > const_iterator find(const K& key) const;
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key);
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
|
||||
|
||||
iterator lower_bound(const key_type& key);
|
||||
const_iterator lower_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator lower_bound(const K& key);
|
||||
template < typename K > const_iterator lower_bound(const K& key) const;
|
||||
|
||||
iterator upper_bound(const key_type& key);
|
||||
const_iterator upper_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator upper_bound(const K& key);
|
||||
template < typename K > const_iterator upper_bound(const K& key) const;
|
||||
```
|
||||
|
||||
### Observers
|
||||
@@ -647,14 +665,23 @@ size_type count(const key_type& key) const;
|
||||
iterator find(const key_type& key);
|
||||
const_iterator find(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator find(const K& key);
|
||||
template < typename K > const_iterator find(const K& key) const;
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key);
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
|
||||
|
||||
iterator lower_bound(const key_type& key);
|
||||
const_iterator lower_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator lower_bound(const K& key);
|
||||
template < typename K > const_iterator lower_bound(const K& key) const;
|
||||
|
||||
iterator upper_bound(const key_type& key);
|
||||
const_iterator upper_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator upper_bound(const K& key);
|
||||
template < typename K > const_iterator upper_bound(const K& key) const;
|
||||
```
|
||||
|
||||
### Observers
|
||||
@@ -878,14 +905,23 @@ size_type count(const key_type& key) const;
|
||||
iterator find(const key_type& key);
|
||||
const_iterator find(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator find(const K& key);
|
||||
template < typename K > const_iterator find(const K& key) const;
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key);
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
|
||||
|
||||
iterator lower_bound(const key_type& key);
|
||||
const_iterator lower_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator lower_bound(const K& key);
|
||||
template < typename K > const_iterator lower_bound(const K& key) const;
|
||||
|
||||
iterator upper_bound(const key_type& key);
|
||||
const_iterator upper_bound(const key_type& key) const;
|
||||
|
||||
template < typename K > iterator upper_bound(const K& key);
|
||||
template < typename K > const_iterator upper_bound(const K& key) const;
|
||||
```
|
||||
|
||||
### Observers
|
||||
|
||||
23
headers/flat.hpp/detail/is_transparent.hpp
Normal file
23
headers/flat.hpp/detail/is_transparent.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/flat.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace flat_hpp::detail
|
||||
{
|
||||
template < typename T, typename U, typename = void >
|
||||
struct is_transparent
|
||||
: std::false_type {};
|
||||
|
||||
template < typename T, typename U >
|
||||
struct is_transparent<T, U, std::void_t<typename T::is_transparent>>
|
||||
: std::true_type {};
|
||||
|
||||
template < typename T, typename U >
|
||||
inline constexpr bool is_transparent_v = is_transparent<T, U>::value;
|
||||
}
|
||||
62
headers/flat.hpp/detail/pair_compare.hpp
Normal file
62
headers/flat.hpp/detail/pair_compare.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/flat.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp::detail
|
||||
{
|
||||
template < typename Pair, typename Compare >
|
||||
class pair_compare : public Compare {
|
||||
public:
|
||||
pair_compare() = default;
|
||||
|
||||
pair_compare(const Compare& compare)
|
||||
: Compare(compare) {}
|
||||
|
||||
bool operator()(
|
||||
const typename Pair::first_type& l,
|
||||
const typename Pair::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l, r);
|
||||
}
|
||||
|
||||
bool operator()(const Pair& l, const Pair& r) const {
|
||||
return Compare::operator()(l.first, r.first);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const typename Pair::first_type& l,
|
||||
const Pair& r) const
|
||||
{
|
||||
return Compare::operator()(l, r.first);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const Pair& l,
|
||||
const typename Pair::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l.first, r);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
is_transparent_v<Compare, K>,
|
||||
bool>
|
||||
operator()(const K& l, const Pair& r) const {
|
||||
return Compare::operator()(l, r.first);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
is_transparent_v<Compare, K>,
|
||||
bool>
|
||||
operator()(const Pair& l, const K& r) const {
|
||||
return Compare::operator()(l.first, r);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -15,55 +15,21 @@
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/pair_compare.hpp"
|
||||
#include "detail/is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template < typename Value, typename Compare >
|
||||
class flat_map_compare : public Compare {
|
||||
public:
|
||||
flat_map_compare() = default;
|
||||
|
||||
flat_map_compare(const Compare& compare)
|
||||
: Compare(compare) {}
|
||||
|
||||
bool operator()(
|
||||
const typename Value::first_type& l,
|
||||
const typename Value::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l, r);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const typename Value::first_type& l,
|
||||
const Value& r) const
|
||||
{
|
||||
return Compare::operator()(l, r.first);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const Value& l,
|
||||
const typename Value::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l.first, r);
|
||||
}
|
||||
|
||||
bool operator()(const Value& l, const Value& r) const {
|
||||
return Compare::operator()(l.first, r.first);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
class flat_map
|
||||
: private detail::flat_map_compare<
|
||||
: private detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
Compare>
|
||||
{
|
||||
using base_type = detail::flat_map_compare<
|
||||
using base_type = detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
Compare>;
|
||||
public:
|
||||
@@ -386,14 +352,36 @@ namespace flat_hpp
|
||||
|
||||
iterator find(const key_type& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, iter->first)
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, iter->first)
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
find(const K& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
find(const K& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
@@ -418,6 +406,24 @@ namespace flat_hpp
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
lower_bound(const K& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
lower_bound(const K& key) const {
|
||||
const base_type& comp = *this;
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
iterator upper_bound(const key_type& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
@@ -428,6 +434,24 @@ namespace flat_hpp
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
upper_bound(const K& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
upper_bound(const K& key) const {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
key_compare key_comp() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -15,55 +15,21 @@
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/pair_compare.hpp"
|
||||
#include "detail/is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template < typename Value, typename Compare >
|
||||
class flat_multimap_compare : public Compare {
|
||||
public:
|
||||
flat_multimap_compare() = default;
|
||||
|
||||
flat_multimap_compare(const Compare& compare)
|
||||
: Compare(compare) {}
|
||||
|
||||
bool operator()(
|
||||
const typename Value::first_type& l,
|
||||
const typename Value::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l, r);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const typename Value::first_type& l,
|
||||
const Value& r) const
|
||||
{
|
||||
return Compare::operator()(l, r.first);
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const Value& l,
|
||||
const typename Value::first_type& r) const
|
||||
{
|
||||
return Compare::operator()(l.first, r);
|
||||
}
|
||||
|
||||
bool operator()(const Value& l, const Value& r) const {
|
||||
return Compare::operator()(l.first, r.first);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<Key>
|
||||
, typename Container = std::vector<std::pair<Key, Value>> >
|
||||
class flat_multimap
|
||||
: private detail::flat_multimap_compare<
|
||||
: private detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
Compare>
|
||||
{
|
||||
using base_type = detail::flat_multimap_compare<
|
||||
using base_type = detail::pair_compare<
|
||||
typename Container::value_type,
|
||||
Compare>;
|
||||
public:
|
||||
@@ -382,14 +348,36 @@ namespace flat_hpp
|
||||
|
||||
iterator find(const key_type& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, iter->first)
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, iter->first)
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
find(const K& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
find(const K& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
@@ -414,6 +402,24 @@ namespace flat_hpp
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
lower_bound(const K& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
lower_bound(const K& key) const {
|
||||
const base_type& comp = *this;
|
||||
return std::lower_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
iterator upper_bound(const key_type& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
@@ -424,6 +430,24 @@ namespace flat_hpp
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
upper_bound(const K& key) {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
upper_bound(const K& key) const {
|
||||
const base_type& comp = *this;
|
||||
return std::upper_bound(begin(), end(), key, comp);
|
||||
}
|
||||
|
||||
key_compare key_comp() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
@@ -309,6 +311,28 @@ namespace flat_hpp
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
find(const K& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
find(const K& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return std::equal_range(begin(), end(), key, key_comp());
|
||||
}
|
||||
@@ -325,6 +349,22 @@ namespace flat_hpp
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
lower_bound(const K& key) {
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
lower_bound(const K& key) const {
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
iterator upper_bound(const key_type& key) {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
@@ -333,6 +373,22 @@ namespace flat_hpp
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
upper_bound(const K& key) {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
upper_bound(const K& key) const {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
key_compare key_comp() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "detail/is_transparent.hpp"
|
||||
|
||||
namespace flat_hpp
|
||||
{
|
||||
template < typename Key
|
||||
@@ -313,6 +315,28 @@ namespace flat_hpp
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
find(const K& key) {
|
||||
const iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
find(const K& key) const {
|
||||
const const_iterator iter = lower_bound(key);
|
||||
return iter != end() && !this->operator()(key, *iter)
|
||||
? iter
|
||||
: end();
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return std::equal_range(begin(), end(), key, key_comp());
|
||||
}
|
||||
@@ -329,6 +353,22 @@ namespace flat_hpp
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
lower_bound(const K& key) {
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
lower_bound(const K& key) const {
|
||||
return std::lower_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
iterator upper_bound(const key_type& key) {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
@@ -337,6 +377,22 @@ namespace flat_hpp
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
iterator>
|
||||
upper_bound(const K& key) {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
std::enable_if_t<
|
||||
detail::is_transparent_v<Compare, K>,
|
||||
const_iterator>
|
||||
upper_bound(const K& key) const {
|
||||
return std::upper_bound(begin(), end(), key, key_comp());
|
||||
}
|
||||
|
||||
key_compare key_comp() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <flat.hpp/flat_map.hpp>
|
||||
using namespace flat_hpp;
|
||||
|
||||
@@ -54,6 +57,10 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("flat_map") {
|
||||
SECTION("detail") {
|
||||
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
|
||||
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);
|
||||
}
|
||||
SECTION("sizeof") {
|
||||
REQUIRE(sizeof(flat_map<int, unsigned>) == sizeof(std::vector<std::pair<int, unsigned>>));
|
||||
|
||||
@@ -403,6 +410,13 @@ TEST_CASE("flat_map") {
|
||||
REQUIRE(my_as_const(s0).lower_bound(-1) == s0.cbegin());
|
||||
REQUIRE(my_as_const(s0).lower_bound(7) == s0.cbegin() + 3);
|
||||
}
|
||||
{
|
||||
flat_map<std::string, int, std::less<>> s0{{"hello", 42}, {"world", 84}};
|
||||
REQUIRE(s0.find(std::string_view("hello")) == s0.begin());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("world")) == s0.begin() + 1);
|
||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||
}
|
||||
}
|
||||
SECTION("observers") {
|
||||
struct my_less {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <flat.hpp/flat_multimap.hpp>
|
||||
using namespace flat_hpp;
|
||||
|
||||
@@ -54,6 +57,10 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("flat_multimap") {
|
||||
SECTION("detail") {
|
||||
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
|
||||
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);
|
||||
}
|
||||
SECTION("sizeof") {
|
||||
REQUIRE(sizeof(flat_multimap<int, unsigned>) == sizeof(std::vector<std::pair<int, unsigned>>));
|
||||
|
||||
@@ -405,6 +412,13 @@ TEST_CASE("flat_multimap") {
|
||||
REQUIRE(my_as_const(s0).lower_bound(-1) == s0.cbegin());
|
||||
REQUIRE(my_as_const(s0).lower_bound(7) == s0.cbegin() + 4);
|
||||
}
|
||||
{
|
||||
flat_multimap<std::string, int, std::less<>> s0{{"hello", 42}, {"world", 84}};
|
||||
REQUIRE(s0.find(std::string_view("hello")) == s0.begin());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("world")) == s0.begin() + 1);
|
||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||
}
|
||||
}
|
||||
SECTION("observers") {
|
||||
struct my_less {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <flat.hpp/flat_multiset.hpp>
|
||||
using namespace flat_hpp;
|
||||
|
||||
@@ -54,6 +57,10 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("flat_multiset") {
|
||||
SECTION("detail") {
|
||||
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
|
||||
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);
|
||||
}
|
||||
SECTION("sizeof") {
|
||||
REQUIRE(sizeof(flat_multiset<int>) == sizeof(std::vector<int>));
|
||||
|
||||
@@ -381,6 +388,13 @@ TEST_CASE("flat_multiset") {
|
||||
REQUIRE(my_as_const(s0).lower_bound(-1) == s0.cbegin());
|
||||
REQUIRE(my_as_const(s0).lower_bound(7) == s0.cbegin() + 4);
|
||||
}
|
||||
{
|
||||
flat_multiset<std::string, std::less<>> s0{"hello", "world"};
|
||||
REQUIRE(s0.find(std::string_view("hello")) == s0.begin());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("world")) == s0.begin() + 1);
|
||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||
}
|
||||
}
|
||||
SECTION("observers") {
|
||||
struct my_less {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <flat.hpp/flat_set.hpp>
|
||||
using namespace flat_hpp;
|
||||
|
||||
@@ -54,6 +57,10 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("flat_set") {
|
||||
SECTION("detail") {
|
||||
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
|
||||
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);
|
||||
}
|
||||
SECTION("sizeof") {
|
||||
REQUIRE(sizeof(flat_set<int>) == sizeof(std::vector<int>));
|
||||
|
||||
@@ -379,6 +386,13 @@ TEST_CASE("flat_set") {
|
||||
REQUIRE(my_as_const(s0).lower_bound(-1) == s0.cbegin());
|
||||
REQUIRE(my_as_const(s0).lower_bound(7) == s0.cbegin() + 3);
|
||||
}
|
||||
{
|
||||
flat_set<std::string, std::less<>> s0{"hello", "world"};
|
||||
REQUIRE(s0.find(std::string_view("hello")) == s0.begin());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("world")) == s0.begin() + 1);
|
||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||
}
|
||||
}
|
||||
SECTION("observers") {
|
||||
struct my_less {
|
||||
|
||||
Reference in New Issue
Block a user