aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-11-20 11:14:58 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-11-20 11:14:58 +0000
commit31773f157bf8164364649b5f470f52dece0a4317 (patch)
tree33d0f7eef45303ab68cf08ab381ce5e5e36c5240 /contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
parent2c7938962d8689e175574fc1e817c05049f27905 (diff)
parenteff600952d5dfe17942f38f510a8ac2b203bb3a5 (diff)
downloadydb-31773f157bf8164364649b5f470f52dece0a4317.tar.gz
Merge branch 'rightlib' into mergelibs-241120-1113
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h')
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h69
1 files changed, 63 insertions, 6 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
index 6c8c7fda35..23a7d3c4dc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
@@ -10,26 +10,83 @@
#ifndef _LIBCPP___ALGORITHM_COUNT_H
#define _LIBCPP___ALGORITHM_COUNT_H
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
+#include <__bit/invert_if.h>
+#include <__bit/popcount.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__fwd/bit_reference.h>
#include <__iterator/iterator_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _InputIterator, class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
- typename iterator_traits<_InputIterator>::difference_type
- count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
- typename iterator_traits<_InputIterator>::difference_type __r(0);
+// generic implementation
+template <class _AlgPolicy, class _Iter, class _Sent, class _Tp, class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>
+__count(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
+ typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> __r(0);
for (; __first != __last; ++__first)
- if (*__first == __value)
+ if (std::__invoke(__proj, *__first) == __value)
++__r;
return __r;
}
+// __bit_iterator implementation
+template <bool _ToCount, class _Cp, bool _IsConst>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bit_iterator<_Cp, _IsConst>::difference_type
+__count_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
+ using _It = __bit_iterator<_Cp, _IsConst>;
+ using __storage_type = typename _It::__storage_type;
+ using difference_type = typename _It::difference_type;
+
+ const int __bits_per_word = _It::__bits_per_word;
+ difference_type __r = 0;
+ // do first partial word
+ if (__first.__ctz_ != 0) {
+ __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+ __storage_type __dn = std::min(__clz_f, __n);
+ __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+ __r = std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
+ __n -= __dn;
+ ++__first.__seg_;
+ }
+ // do middle whole words
+ for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
+ __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_));
+ // do last partial word
+ if (__n > 0) {
+ __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+ __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
+ }
+ return __r;
+}
+
+template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> >
+__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
+ if (__value)
+ return std::__count_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
+ return std::__count_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
+}
+
+template <class _InputIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator>
+count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
+ __identity __proj;
+ return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj);
+}
+
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COUNT_H