-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] implement std::flat_set #125241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++] implement std::flat_set #125241
Changes from all commits
14799d6
fce5f1e
b75a650
1904742
21a228f
b19cb68
248ec63
83dcac7
e5fc970
5b429a8
7ae2ab1
d2fe5c4
8405724
401cfd2
87103f9
5a92ff8
5bbfd3e
2f94a34
8bfed5d
b6484f0
0b4c958
f313aba
1f465d1
db18909
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// -*- C++ -*- | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef _LIBCPP___FLAT_SET_RA_ITERATOR_H | ||
#define _LIBCPP___FLAT_SET_RA_ITERATOR_H | ||
|
||
#include "__type_traits/is_same.h" | ||
#include <__compare/three_way_comparable.h> | ||
#include <__config> | ||
#include <__iterator/incrementable_traits.h> | ||
#include <__iterator/iterator_traits.h> | ||
#include <__type_traits/is_constructible.h> | ||
#include <__utility/move.h> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
_LIBCPP_PUSH_MACROS | ||
#include <__undef_macros> | ||
|
||
#if _LIBCPP_STD_VER >= 23 | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
/** | ||
* __ra_iterator is a random access iterator that wraps an underlying iterator. | ||
* It also stores the underlying container type in its type so that algorithms | ||
* can optimize based on the underlying container type, and to avoid inadvertently | ||
* mixing iterators coming from different containers.. | ||
*/ | ||
template <class _Container, class _Iterator> | ||
struct __ra_iterator { | ||
private: | ||
_Iterator __iter_; | ||
|
||
friend _Container; | ||
|
||
// note: checking the concept random_access_iterator does not work for incomplete types | ||
static_assert(_IsSame<typename iterator_traits<_Iterator>::iterator_category, random_access_iterator_tag>::value, | ||
"Underlying iterator must be a random access iterator"); | ||
|
||
public: | ||
using iterator_concept = random_access_iterator_tag; // deliberately lower contiguous_iterator | ||
using iterator_category = random_access_iterator_tag; | ||
using value_type = iter_value_t<_Iterator>; | ||
using difference_type = iter_difference_t<_Iterator>; | ||
|
||
_LIBCPP_HIDE_FROM_ABI __ra_iterator() | ||
huixie90 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
requires is_default_constructible_v<_Iterator> | ||
= default; | ||
|
||
_LIBCPP_HIDE_FROM_ABI explicit constexpr __ra_iterator(_Iterator __iter) : __iter_(std::move(__iter)) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr _Iterator __base() const noexcept(noexcept(_Iterator(__iter_))) { return __iter_; } | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__iter_; } | ||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator->() const | ||
requires requires { __iter_.operator->(); } | ||
{ | ||
return __iter_.operator->(); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator++() { | ||
++__iter_; | ||
return *this; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator++(int) { | ||
__ra_iterator __tmp(*this); | ||
++*this; | ||
return __tmp; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator--() { | ||
--__iter_; | ||
return *this; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator--(int) { | ||
__ra_iterator __tmp(*this); | ||
--*this; | ||
return __tmp; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator+=(difference_type __x) { | ||
__iter_ += __x; | ||
return *this; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator-=(difference_type __x) { | ||
__iter_ -= __x; | ||
return *this; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const { return *(*this + __n); } | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return __x.__iter_ == __y.__iter_; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return __x.__iter_ < __y.__iter_; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return __y < __x; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return !(__y < __x); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return !(__x < __y); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y) | ||
requires three_way_comparable<_Iterator> | ||
{ | ||
return __x.__iter_ <=> __y.__iter_; | ||
} | ||
Comment on lines
+124
to
+128
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As Hui was explaining to me just now, these requirements are added by containers. But if we want to reuse this iterator type in other contexts, these requirements might not apply and so we are probably better off with the more general implementation. |
||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(const __ra_iterator& __i, difference_type __n) { | ||
auto __tmp = __i; | ||
__tmp += __n; | ||
return __tmp; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(difference_type __n, const __ra_iterator& __i) { | ||
return __i + __n; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator-(const __ra_iterator& __i, difference_type __n) { | ||
auto __tmp = __i; | ||
__tmp -= __n; | ||
return __tmp; | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __ra_iterator& __x, const __ra_iterator& __y) { | ||
return __x.__iter_ - __y.__iter_; | ||
} | ||
}; | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP_STD_VER >= 23 | ||
|
||
_LIBCPP_POP_MACROS | ||
|
||
#endif // _LIBCPP___FLAT_SET_RA_ITERATOR_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// -*- C++ -*- | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef _LIBCPP_FLAT_SET | ||
#define _LIBCPP_FLAT_SET | ||
|
||
/* | ||
Header <flat_set> synopsis | ||
|
||
#include <compare> // see [compare.syn] | ||
#include <initializer_list> // see [initializer.list.syn] | ||
|
||
namespace std { | ||
// [flat.set], class template flat_set | ||
template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>> | ||
class flat_set; | ||
|
||
struct sorted_unique_t { explicit sorted_unique_t() = default; }; | ||
inline constexpr sorted_unique_t sorted_unique{}; | ||
|
||
template<class Key, class Compare, class KeyContainer, class Allocator> | ||
struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>; | ||
|
||
// [flat.set.erasure], erasure for flat_set | ||
template<class Key, class Compare, class KeyContainer, class Predicate> | ||
typename flat_set<Key, Compare, KeyContainer>::size_type | ||
erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred); | ||
} | ||
*/ | ||
|
||
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) | ||
# include <__cxx03/__config> | ||
#else | ||
# include <__config> | ||
|
||
# if _LIBCPP_STD_VER >= 23 | ||
# include <__flat_map/sorted_unique.h> | ||
# include <__flat_set/flat_set.h> | ||
# endif | ||
|
||
// for feature-test macros | ||
# include <version> | ||
|
||
// standard required includes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this touches |
||
# include <compare> | ||
# include <initializer_list> | ||
|
||
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
# endif | ||
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) | ||
|
||
#endif // _LIBCPP_FLAT_SET |
Uh oh!
There was an error while loading. Please reload this page.