We've been forgetting to add those to most of the <ranges> review.
To avoid forgetting in the future, I added an item in the pre-commit
checklist.
Differential Revision: https://reviews.llvm.org/D106287
- Do you have tests for every public class and/or function you're adding or modifying?
- Did you update the synopsis of the relevant headers?
- Did you update the relevant files to track implementation status (in ``docs/Status/``)?
+- Did you mark all functions and type declarations with the :ref:`proper visibility macro <visibility-macros>`?
- If you added a header:
- Did you add it to ``include/module.modulemap``?
.. contents::
:local:
+.. _visibility-macros:
+
Overview
========
Mark a function as not being part of the ABI of any final linked image that
uses it.
+**_LIBCPP_INLINE_VISIBILITY**
+ Historical predecessor of ``_LIBCPP_HIDE_FROM_ABI`` -- please use
+ ``_LIBCPP_HIDE_FROM_ABI`` instead.
+
**_LIBCPP_HIDE_FROM_ABI_AFTER_V1**
Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`)
when libc++ is built with an ABI version after ABI v1. This macro is used to
struct __advance_fn final : __function_like {
private:
template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI
static constexpr _Tp __abs(_Tp __n) noexcept {
return __n < 0 ? -__n : __n;
}
template <class _Ip>
+ _LIBCPP_HIDE_FROM_ABI
static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) {
while (__n > 0) {
--__n;
}
template <class _Ip>
+ _LIBCPP_HIDE_FROM_ABI
static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) {
while (__n < 0) {
++__n;
// Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative.
template <input_or_output_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
_LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
"If `n < 0`, then `bidirectional_iterator<I>` must be true.");
// Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound) denotes a range.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_Ip& __i, _Sp __bound) const {
// If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound)`.
if constexpr (assignable_from<_Ip&, _Sp>) {
// * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
// Returns: `n - M`, where `M` is the difference between the the ending and starting position.
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const {
_LIBCPP_ASSERT(__n >= 0 || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
"If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Container, class _Predicate>
+_LIBCPP_HIDE_FROM_ABI
typename _Container::size_type
__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
typename _Container::size_type __old_size = __c.size();
// well-formed expression when treated as an unevaluated operand, [...]
template<class _Ip>
requires __class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>
- [[nodiscard]] constexpr decltype(auto) operator()(_Ip&& __i) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i))))
{
return iter_move(_VSTD::forward<_Ip>(__i));
template<class _Ip>
requires (!(__class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>)) &&
requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); }
- [[nodiscard]] constexpr decltype(auto) operator()(_Ip&& __i) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
noexcept(noexcept(*_VSTD::forward<_Ip>(__i)))
{
if constexpr (is_lvalue_reference_v<decltype(*_VSTD::forward<_Ip>(__i))>) {
struct __fn {
template <class _T1, class _T2>
requires __unqualified_iter_swap<_T1, _T2>
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y))))
{
template <class _T1, class _T2>
requires (!__unqualified_iter_swap<_T1, _T2>) &&
__readable_swappable<_T1, _T2>
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y))))
{
!__readable_swappable<_T1, _T2>) &&
indirectly_movable_storable<_T1, _T2> &&
indirectly_movable_storable<_T2, _T1>
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
noexcept(*__y = ranges::iter_move(__x)) &&
namespace ranges {
struct __next_fn final : private __function_like {
+ _LIBCPP_HIDE_FROM_ABI
constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {}
template <input_or_output_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x) const {
++__x;
return __x;
}
template <input_or_output_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
ranges::advance(__x, __n);
return __x;
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, _Sp __bound) const {
ranges::advance(__x, __bound);
return __x;
}
template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const {
ranges::advance(__x, __n, __bound);
return __x;
namespace ranges {
struct __prev_fn final : private __function_like {
+ _LIBCPP_HIDE_FROM_ABI
constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {}
template <bidirectional_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x) const {
--__x;
return __x;
}
template <bidirectional_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
ranges::advance(__x, -__n);
return __x;
}
template <bidirectional_iterator _Ip>
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const {
ranges::advance(__x, -__n, __bound);
return __x;
struct __fn {
template <class _Tp>
requires is_array_v<remove_cv_t<_Tp>>
- [[nodiscard]] constexpr auto operator()(_Tp& __t) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept {
constexpr bool __complete = __is_complete<iter_value_t<_Tp> >;
if constexpr (__complete) { // used to disable cryptic diagnostic
return __t + 0;
template <class _Tp>
requires __member_begin<_Tp>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::__decay_copy(__t.begin())))
{
return __t.begin();
template <class _Tp>
requires __unqualified_begin<_Tp>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::__decay_copy(begin(__t))))
{
return begin(__t);
class __fn {
public:
template <class _Tp, size_t _Np>
- [[nodiscard]] constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept {
constexpr bool __complete = __is_complete<remove_cv_t<_Tp> >;
if constexpr (__complete) { // used to disable cryptic diagnostic
return __t + _Np;
template <class _Tp>
requires __member_end<_Tp>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::__decay_copy(__t.end())))
{
return _VSTD::forward<_Tp>(__t).end();
template <class _Tp>
requires __unqualified_end<_Tp>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::__decay_copy(end(__t))))
{
return end(__t);
struct __fn {
template <class _Tp>
requires invocable<decltype(ranges::begin), _Tp const&>
- [[nodiscard]] constexpr auto operator()(_Tp& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
noexcept(noexcept(ranges::begin(_VSTD::as_const(__t))))
{
return ranges::begin(_VSTD::as_const(__t));
template <class _Tp>
requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t))))
{
return ranges::begin(static_cast<_Tp const&&>(__t));
struct __fn {
template <class _Tp>
requires invocable<decltype(ranges::end), _Tp const&>
- [[nodiscard]] constexpr auto operator()(_Tp& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
noexcept(noexcept(ranges::end(_VSTD::as_const(__t))))
{
return ranges::end(_VSTD::as_const(__t));
template <class _Tp>
requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&>
- [[nodiscard]] constexpr auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t))))
{
return ranges::end(static_cast<_Tp const&&>(__t));
struct __fn {
template<class _Tp>
requires ranges::view<decay_t<_Tp>>
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t))))
{
template<class _Tp>
requires (!ranges::view<decay_t<_Tp>>) &&
requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)}))
{
requires (!ranges::view<decay_t<_Tp>> &&
!requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } &&
requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; })
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)}))
{
struct __fn {
template <__member_data _Tp>
requires __can_borrow<_Tp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr __ptr_to_object auto operator()(_Tp&& __t) const
noexcept(noexcept(__t.data())) {
return __t.data();
template<__ranges_begin_invocable _Tp>
requires __can_borrow<_Tp>
+ _LIBCPP_HIDE_FROM_ABI
constexpr __ptr_to_object auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) {
return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t)));
public:
drop_view() requires default_initializable<_View> = default;
+ _LIBCPP_HIDE_FROM_ABI
constexpr drop_view(_View __base, range_difference_t<_View> __count)
: __cached_begin_()
, __count_(__count)
_LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr drop_view(drop_view const& __other)
: __cached_begin_() // Intentionally not propagating the cached begin iterator.
, __count_(__other.__count_)
, __base_(__other.__base_)
{ }
+ _LIBCPP_HIDE_FROM_ABI
constexpr drop_view(drop_view&& __other)
: __cached_begin_() // Intentionally not propagating the cached begin iterator.
, __count_(_VSTD::move(__other.__count_))
, __base_(_VSTD::move(__other.__base_))
{ }
+ _LIBCPP_HIDE_FROM_ABI
constexpr drop_view& operator=(drop_view const& __other) {
if constexpr (_UseCache) {
__cached_begin_.reset();
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr drop_view& operator=(drop_view&& __other) {
if constexpr (_UseCache) {
__cached_begin_.reset();
return *this;
}
- constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
- constexpr _View base() && { return _VSTD::move(__base_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return _VSTD::move(__base_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto begin()
requires (!(__simple_view<_View> &&
random_access_range<const _View> && sized_range<const _View>))
return __tmp;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto begin() const
requires random_access_range<const _View> && sized_range<const _View>
{
return ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto end()
requires (!__simple_view<_View>)
{ return ranges::end(__base_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto end() const
requires range<const _View>
{ return ranges::end(__base_); }
+ _LIBCPP_HIDE_FROM_ABI
static constexpr auto __size(auto& __self) {
const auto __s = ranges::size(__self.__base_);
const auto __c = static_cast<decltype(__s)>(__self.__count_);
return __s < __c ? 0 : __s - __c;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size()
requires sized_range<_View>
{ return __size(*this); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
requires sized_range<const _View>
{ return __size(*this); }
template<class _Tp>
inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
-
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
struct __fn {
template <__member_empty _Tp>
- [[nodiscard]] constexpr bool operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
noexcept(noexcept(bool(__t.empty()))) {
return __t.empty();
}
template <__can_invoke_size _Tp>
- [[nodiscard]] constexpr bool operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
noexcept(noexcept(ranges::size(_VSTD::forward<_Tp>(__t)))) {
return ranges::size(_VSTD::forward<_Tp>(__t)) == 0;
}
template<__can_compare_begin_end _Tp>
- [[nodiscard]] constexpr bool operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
return ranges::begin(__t) == ranges::end(__t);
}
requires is_object_v<_Tp>
class empty_view : public view_interface<empty_view<_Tp>> {
public:
- static constexpr _Tp* begin() noexcept { return nullptr; }
- static constexpr _Tp* end() noexcept { return nullptr; }
- static constexpr _Tp* data() noexcept { return nullptr; }
- static constexpr size_t size() noexcept { return 0; }
- static constexpr bool empty() noexcept { return true; }
+ _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; }
+ _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; }
+ _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; }
+ _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
};
} // namespace ranges
template<class _Tp>
requires __different_from<_Tp, ref_view> &&
convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr ref_view(_Tp&& __t)
: __range_(_VSTD::addressof(static_cast<_Range&>(_VSTD::forward<_Tp>(__t))))
{}
- constexpr _Range& base() const { return *__range_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
- constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
- constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
+ _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr bool empty() const
requires requires { ranges::empty(*__range_); }
{ return ranges::empty(*__range_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
requires sized_range<_Range>
{ return ranges::size(*__range_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto data() const
requires contiguous_range<_Range>
{ return ranges::data(*__range_); }
struct __fn {
template <class _Tp, size_t _Sz>
- [[nodiscard]] constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
return _Sz;
}
template <class _Tp, size_t _Sz>
- [[nodiscard]] constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
return _Sz;
}
template <__member_size _Tp>
- [[nodiscard]] constexpr __integer_like auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
noexcept(noexcept(_VSTD::forward<_Tp>(__t).size())) {
return _VSTD::forward<_Tp>(__t).size();
}
template <__unqualified_size _Tp>
- [[nodiscard]] constexpr __integer_like auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
noexcept(noexcept(size(_VSTD::forward<_Tp>(__t)))) {
return size(_VSTD::forward<_Tp>(__t));
}
template<__difference _Tp>
- [[nodiscard]] constexpr __integer_like auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) {
return _VSTD::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
}
struct __fn {
template<class _Tp>
requires requires (_Tp&& __t) { ranges::size(__t); }
- [[nodiscard]] constexpr integral auto operator()(_Tp&& __t) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::size(__t))) {
using _Signed = make_signed_t<decltype(ranges::size(__t))>;
if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
_Iter __begin_ = _Iter();
_Sent __end_ = _Sent();
+ _LIBCPP_HIDE_FROM_ABI
constexpr __subrange_base() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
constexpr __subrange_base(_Iter __iter, _Sent __sent, make_unsigned_t<iter_difference_t<_Iter>> = 0)
: __begin_(_VSTD::move(__iter)), __end_(__sent) { }
};
_Sent __end_ = _Sent();
make_unsigned_t<iter_difference_t<_Iter>> __size_ = 0;
+ _LIBCPP_HIDE_FROM_ABI
constexpr __subrange_base() = default;
+
+ _LIBCPP_HIDE_FROM_ABI
constexpr __subrange_base(_Iter __iter, _Sent __sent, decltype(__size_) __size)
: __begin_(_VSTD::move(__iter)), __end_(__sent), __size_(__size) { }
};
using _Base = __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>>;
+ _LIBCPP_HIDE_FROM_ABI
subrange() requires default_initializable<_Iter> = default;
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent)
requires (!_Base::__store_size)
: _Base(_VSTD::move(__iter), __sent) {}
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent,
make_unsigned_t<iter_difference_t<_Iter>> __n)
requires (_Kind == subrange_kind::sized)
requires borrowed_range<_Range> &&
__convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
convertible_to<sentinel_t<_Range>, _Sent>
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange(_Range&& __range)
requires (!_Base::__store_size)
: subrange(ranges::begin(__range), ranges::end(__range)) { }
requires borrowed_range<_Range> &&
__convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
convertible_to<sentinel_t<_Range>, _Sent>
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange(_Range&& __range)
requires _Base::__store_size && sized_range<_Range>
: subrange(__range, ranges::size(__range)) { }
template<borrowed_range _Range>
requires __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
convertible_to<sentinel_t<_Range>, _Sent>
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange(_Range&& __range, make_unsigned_t<iter_difference_t<_Iter>> __n)
requires (_Kind == subrange_kind::sized)
: subrange(ranges::begin(__range), ranges::end(__range), __n) { }
template<__different_from<subrange> _Pair>
requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&>
+ _LIBCPP_HIDE_FROM_ABI
constexpr operator _Pair() const { return _Pair(this->__begin_, this->__end_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Iter begin() const requires copyable<_Iter> {
return this->__begin_;
}
- [[nodiscard]] constexpr _Iter begin() requires (!copyable<_Iter>) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) {
return _VSTD::move(this->__begin_);
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Sent end() const { return this->__end_; }
- [[nodiscard]] constexpr bool empty() const { return this->__begin_ == this->__end_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return this->__begin_ == this->__end_; }
+ _LIBCPP_HIDE_FROM_ABI
constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const
requires (_Kind == subrange_kind::sized)
{
return __to_unsigned_like(this->__end_ - this->__begin_);
}
- [[nodiscard]] constexpr subrange next(iter_difference_t<_Iter> __n = 1) const&
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const&
requires forward_iterator<_Iter> {
auto __tmp = *this;
__tmp.advance(__n);
return __tmp;
}
- [[nodiscard]] constexpr subrange next(iter_difference_t<_Iter> __n = 1) && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && {
advance(__n);
return _VSTD::move(*this);
}
- [[nodiscard]] constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const
requires bidirectional_iterator<_Iter> {
auto __tmp = *this;
__tmp.advance(-__n);
return __tmp;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr subrange& advance(iter_difference_t<_Iter> __n) {
if constexpr (bidirectional_iterator<_Iter>) {
if (__n < 0) {
template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
requires (_Index < 2)
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange) {
if constexpr (_Index == 0)
return __subrange.begin();
template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
requires (_Index < 2)
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange) {
if constexpr (_Index == 0)
return __subrange.begin();
[[no_unique_address]] _View __base_ = _View();
public:
+ _LIBCPP_HIDE_FROM_ABI
transform_view()
requires default_initializable<_View> && default_initializable<_Fn> = default;
+ _LIBCPP_HIDE_FROM_ABI
constexpr transform_view(_View __base, _Fn __func)
: __func_(_VSTD::in_place, _VSTD::move(__func)), __base_(_VSTD::move(__base)) {}
+ _LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+ _LIBCPP_HIDE_FROM_ABI
constexpr _View base() && { return _VSTD::move(__base_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator<false> begin() {
return __iterator<false>{*this, ranges::begin(__base_)};
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator<true> begin() const
requires range<const _View> &&
regular_invocable<const _Fn&, range_reference_t<const _View>>
return __iterator<true>(*this, ranges::begin(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __sentinel<false> end() {
return __sentinel<false>(ranges::end(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator<false> end()
requires common_range<_View>
{
return __iterator<false>(*this, ranges::end(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __sentinel<true> end() const
requires range<const _View> &&
regular_invocable<const _Fn&, range_reference_t<const _View>>
{
return __sentinel<true>(ranges::end(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator<true> end() const
requires common_range<const _View> &&
regular_invocable<const _Fn&, range_reference_t<const _View>>
return __iterator<true>(*this, ranges::end(__base_));
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size() requires sized_range<_View> { return ranges::size(__base_); }
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); }
};
using value_type = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>;
using difference_type = range_difference_t<_Base>;
+ _LIBCPP_HIDE_FROM_ABI
__iterator() requires default_initializable<iterator_t<_Base>> = default;
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
: __parent_(_VSTD::addressof(__parent)), __current_(_VSTD::move(__current)) {}
// Note: `__i` should always be `__iterator<false>`, but directly using
// `__iterator<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator(__iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {}
+ _LIBCPP_HIDE_FROM_ABI
constexpr iterator_t<_Base> base() const&
requires copyable<iterator_t<_Base>>
{
return __current_;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr iterator_t<_Base> base() && {
return _VSTD::move(__current_);
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator*() const
noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, *__current_)))
{
return _VSTD::invoke(*__parent_->__func_, *__current_);
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator& operator++() {
++__current_;
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr void operator++(int) { ++__current_; }
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator operator++(int)
requires forward_range<_Base>
{
return __tmp;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator& operator--()
requires bidirectional_range<_Base>
{
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator operator--(int)
requires bidirectional_range<_Base>
{
return __tmp;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr __iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
return *this;
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](difference_type __n) const
noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, __current_[__n])))
requires random_access_range<_Base>
return _VSTD::invoke(*__parent_->__func_, __current_[__n]);
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
requires equality_comparable<iterator_t<_Base>>
{
return __x.__current_ == __y.__current_;
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ < __y.__current_;
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ > __y.__current_;
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ <= __y.__current_;
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
}
// TODO: Fix this as soon as soon as three_way_comparable is implemented.
+// _LIBCPP_HIDE_FROM_ABI
// friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
// requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
// {
// return __x.__current_ <=> __y.__current_;
// }
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr __iterator operator+(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ + __n};
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr __iterator operator+(difference_type __n, __iterator __i)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ + __n};
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr __iterator operator-(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
return __iterator{*__i.__parent_, __i.__current_ - __n};
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y.__current_;
}
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr decltype(auto) iter_move(const __iterator& __i)
noexcept(noexcept(*__i))
{
friend class transform_view<_View, _Fn>::__sentinel;
public:
+ _LIBCPP_HIDE_FROM_ABI
__sentinel() = default;
+ _LIBCPP_HIDE_FROM_ABI
constexpr explicit __sentinel(sentinel_t<_Base> __end_) : __end_(__end_) {}
// Note: `__i` should always be `__sentinel<false>`, but directly using
// `__sentinel<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
+ _LIBCPP_HIDE_FROM_ABI
constexpr __sentinel(__sentinel<!_Const> __i)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(_VSTD::move(__i.__end_)) {}
+ _LIBCPP_HIDE_FROM_ABI
constexpr sentinel_t<_Base> base() const { return __end_; }
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ == __y.__end_;
}
template<bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ - __y.__end_;
template<bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
return __x.__end_ - __y.__current_;
template<class _Derived>
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
class view_interface : public view_base {
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Derived& __derived() noexcept {
return static_cast<_Derived&>(*this);
}
+ _LIBCPP_HIDE_FROM_ABI
constexpr _Derived const& __derived() const noexcept {
return static_cast<_Derived const&>(*this);
}
public:
template<class _D2 = _Derived>
- [[nodiscard]] constexpr bool empty()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<_D2>
{
}
template<class _D2 = _Derived>
- [[nodiscard]] constexpr bool empty() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<const _D2>
{
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool()
noexcept(noexcept(ranges::empty(declval<_D2>())))
requires __can_empty<_D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const
noexcept(noexcept(ranges::empty(declval<const _D2>())))
requires __can_empty<const _D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto data()
noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
requires contiguous_iterator<iterator_t<_D2>>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto data() const
noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size()
noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
requires forward_range<_D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
requires forward_range<const _D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front()
noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<_D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front() const
noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<const _D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back()
noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<_D2> && common_range<_D2>
}
template<class _D2 = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back() const
noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<const _D2> && common_range<const _D2>
}
template<random_access_range _RARange = _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
noexcept(noexcept(ranges::begin(__derived())[__index]))
{
}
template<random_access_range _RARange = const _Derived>
+ _LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
noexcept(noexcept(ranges::begin(__derived())[__index]))
{