forked from OSchip/llvm-project
[libc++] Implement std::boyer_moore{, _horspool}_searcher
This mostly copys the `<experimental/functional>` stuff and updates the code to current libc++ style. Reviewed By: ldionne, #libc Spies: nlopes, adamdebreceni, arichardson, libcxx-commits, mgorny Differential Revision: https://reviews.llvm.org/D121074
This commit is contained in:
parent
e1f1407beb
commit
971e9c80e9
|
@ -84,7 +84,7 @@ Status
|
|||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bool_constant`` ``201505L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_boyer_moore_searcher`` *unimplemented*
|
||||
``__cpp_lib_boyer_moore_searcher`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_byte`` ``201603L``
|
||||
------------------------------------------------- -----------------
|
||||
|
|
|
@ -142,6 +142,10 @@ API Changes
|
|||
``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS``, this ensures that the members of
|
||||
``allocator<void>`` removed in C++20 can be accessed.
|
||||
|
||||
- The experimental versions of ``boyer_moore_searcher`` and ``boyer_moore_horspool_searcher``
|
||||
will be removed in LLVM 17. You can disable the deprecation warnings by defining
|
||||
``_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS``.
|
||||
|
||||
ABI Changes
|
||||
-----------
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@ set(files
|
|||
__functional/bind_front.h
|
||||
__functional/binder1st.h
|
||||
__functional/binder2nd.h
|
||||
__functional/boyer_moore_searcher.h
|
||||
__functional/compose.h
|
||||
__functional/default_searcher.h
|
||||
__functional/function.h
|
||||
|
|
|
@ -789,13 +789,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
|
|||
# if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
|
||||
# if __has_attribute(deprecated)
|
||||
# define _LIBCPP_DEPRECATED __attribute__((deprecated))
|
||||
# define _LIBCPP_DEPRECATED_(m) __attribute__((deprected(m)))
|
||||
# elif _LIBCPP_STD_VER > 11
|
||||
# define _LIBCPP_DEPRECATED [[deprecated]]
|
||||
# define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]]
|
||||
# else
|
||||
# define _LIBCPP_DEPRECATED
|
||||
# define _LIBCPP_DEPRECATED_(m)
|
||||
# endif
|
||||
# else
|
||||
# define _LIBCPP_DEPRECATED
|
||||
# define _LIBCPP_DEPRECATED_(m)
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_CXX03_LANG)
|
||||
|
@ -895,8 +899,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
|
|||
# endif
|
||||
|
||||
# ifndef _LIBCPP_HAS_NO_ASAN
|
||||
extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(const void*, const void*, const void*,
|
||||
const void*);
|
||||
extern "C" _LIBCPP_FUNC_VIS void
|
||||
__sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*);
|
||||
# endif
|
||||
|
||||
// Try to find out if RTTI is disabled.
|
||||
|
|
|
@ -0,0 +1,313 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
|
||||
#define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#include <__algorithm/fill_n.h>
|
||||
#include <__config>
|
||||
#include <__functional/hash.h>
|
||||
#include <__functional/operations.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/shared_ptr.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Key,
|
||||
class _Value,
|
||||
class _Hash,
|
||||
class _BinaryPredicate,
|
||||
bool /*useArray*/>
|
||||
class _BMSkipTable;
|
||||
|
||||
// General case for BM data searching; use a map
|
||||
template <class _Key,
|
||||
class _Value,
|
||||
class _Hash,
|
||||
class _BinaryPredicate>
|
||||
class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
|
||||
private:
|
||||
using value_type = _Value;
|
||||
using key_type = _Key;
|
||||
|
||||
const value_type __default_value_;
|
||||
unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred)
|
||||
: __default_value_(__default_value),
|
||||
__table_(__sz, __hash, __pred) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) {
|
||||
__table_[__key] = __val;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const {
|
||||
auto __it = __table_.find(__key);
|
||||
return __it == __table_.end() ? __default_value_ : __it->second;
|
||||
}
|
||||
};
|
||||
|
||||
// Special case small numeric values; use an array
|
||||
template <class _Key,
|
||||
class _Value,
|
||||
class _Hash,
|
||||
class _BinaryPredicate>
|
||||
class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
|
||||
private:
|
||||
using value_type = _Value;
|
||||
using key_type = _Key;
|
||||
|
||||
using unsigned_key_type = make_unsigned_t<key_type>;
|
||||
std::array<value_type, 256> __table_;
|
||||
static_assert(numeric_limits<unsigned_key_type>::max() < 256);
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable(size_t, value_type __default_value, _Hash, _BinaryPredicate) {
|
||||
std::fill_n(__table_.data(), __table_.size(), __default_value);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void insert(key_type __key, value_type __val) {
|
||||
__table_[static_cast<unsigned_key_type>(__key)] = __val;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI value_type operator[](key_type __key) const {
|
||||
return __table_[static_cast<unsigned_key_type>(__key)];
|
||||
}
|
||||
};
|
||||
|
||||
template <class _RandomAccessIterator1,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
|
||||
private:
|
||||
using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type;
|
||||
using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type;
|
||||
using __skip_table_type = _BMSkipTable<value_type,
|
||||
difference_type,
|
||||
_Hash,
|
||||
_BinaryPredicate,
|
||||
is_integral_v<value_type>
|
||||
&& sizeof(value_type) == 1
|
||||
&& is_same_v<_Hash, hash<value_type>>
|
||||
&& is_same_v<_BinaryPredicate, equal_to<>>>;
|
||||
|
||||
public:
|
||||
boyer_moore_searcher(_RandomAccessIterator1 __first,
|
||||
_RandomAccessIterator1 __last,
|
||||
_Hash __hash = _Hash(),
|
||||
_BinaryPredicate __pred = _BinaryPredicate())
|
||||
: __first_(__first),
|
||||
__last_(__last),
|
||||
__pred_(__pred),
|
||||
__pattern_length_(__last - __first),
|
||||
__skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)),
|
||||
__suffix_(std::__allocate_shared_unbounded_array<difference_type[]>(
|
||||
allocator<difference_type>(), __pattern_length_ + 1)) {
|
||||
difference_type __i = 0;
|
||||
while (__first != __last) {
|
||||
__skip_table_->insert(*__first, __i);
|
||||
++__first;
|
||||
++__i;
|
||||
}
|
||||
__build_suffix_table(__first_, __last_, __pred_);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator2>
|
||||
pair<_RandomAccessIterator2, _RandomAccessIterator2>
|
||||
operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
|
||||
static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
|
||||
typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
|
||||
"Corpus and Pattern iterators must point to the same type");
|
||||
if (__first == __last)
|
||||
return std::make_pair(__last, __last);
|
||||
if (__first_ == __last_)
|
||||
return std::make_pair(__first, __first);
|
||||
|
||||
if (__pattern_length_ > (__last - __first))
|
||||
return std::make_pair(__last, __last);
|
||||
return __search(__first, __last);
|
||||
}
|
||||
|
||||
private:
|
||||
_RandomAccessIterator1 __first_;
|
||||
_RandomAccessIterator1 __last_;
|
||||
_BinaryPredicate __pred_;
|
||||
difference_type __pattern_length_;
|
||||
shared_ptr<__skip_table_type> __skip_table_;
|
||||
shared_ptr<difference_type[]> __suffix_;
|
||||
|
||||
template <class _RandomAccessIterator2>
|
||||
pair<_RandomAccessIterator2, _RandomAccessIterator2>
|
||||
__search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
|
||||
_RandomAccessIterator2 __current = __f;
|
||||
const _RandomAccessIterator2 __last = __l - __pattern_length_;
|
||||
const __skip_table_type& __skip_table = *__skip_table_;
|
||||
|
||||
while (__current <= __last) {
|
||||
difference_type __j = __pattern_length_;
|
||||
while (__pred_(__first_[__j - 1], __current[__j - 1])) {
|
||||
--__j;
|
||||
if (__j == 0)
|
||||
return std::make_pair(__current, __current + __pattern_length_);
|
||||
}
|
||||
|
||||
difference_type __k = __skip_table[__current[__j - 1]];
|
||||
difference_type __m = __j - __k - 1;
|
||||
if (__k < __j && __m > __suffix_[__j])
|
||||
__current += __m;
|
||||
else
|
||||
__current += __suffix_[__j];
|
||||
}
|
||||
return std::make_pair(__l, __l);
|
||||
}
|
||||
|
||||
template <class _Iterator, class _Container>
|
||||
void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) {
|
||||
const size_t __count = __last - __first;
|
||||
|
||||
__prefix[0] = 0;
|
||||
size_t __k = 0;
|
||||
|
||||
for (size_t __i = 1; __i != __count; ++__i) {
|
||||
while (__k > 0 && !__pred(__first[__k], __first[__i]))
|
||||
__k = __prefix[__k - 1];
|
||||
|
||||
if (__pred(__first[__k], __first[__i]))
|
||||
++__k;
|
||||
__prefix[__i] = __k;
|
||||
}
|
||||
}
|
||||
|
||||
void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) {
|
||||
const size_t __count = __last - __first;
|
||||
|
||||
if (__count == 0)
|
||||
return;
|
||||
|
||||
vector<difference_type> __scratch(__count);
|
||||
|
||||
__compute_bm_prefix(__first, __last, __pred, __scratch);
|
||||
for (size_t __i = 0; __i <= __count; ++__i)
|
||||
__suffix_[__i] = __count - __scratch[__count - 1];
|
||||
|
||||
using _ReverseIter = reverse_iterator<_RandomAccessIterator1>;
|
||||
__compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch);
|
||||
|
||||
for (size_t __i = 0; __i != __count; ++__i) {
|
||||
const size_t __j = __count - __scratch[__i];
|
||||
const difference_type __k = __i - __scratch[__i] + 1;
|
||||
|
||||
if (__suffix_[__j] > __k)
|
||||
__suffix_[__j] = __k;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class _RandomAccessIterator1,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
|
||||
private:
|
||||
using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type;
|
||||
using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type;
|
||||
using __skip_table_type = _BMSkipTable<value_type,
|
||||
difference_type,
|
||||
_Hash,
|
||||
_BinaryPredicate,
|
||||
is_integral_v<value_type>
|
||||
&& sizeof(value_type) == 1
|
||||
&& is_same_v<_Hash, hash<value_type>>
|
||||
&& is_same_v<_BinaryPredicate, equal_to<>>>;
|
||||
public:
|
||||
boyer_moore_horspool_searcher(_RandomAccessIterator1 __first,
|
||||
_RandomAccessIterator1 __last,
|
||||
_Hash __hash = _Hash(),
|
||||
_BinaryPredicate __pred = _BinaryPredicate())
|
||||
: __first_(__first),
|
||||
__last_(__last),
|
||||
__pred_(__pred),
|
||||
__pattern_length_(__last - __first),
|
||||
__skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) {
|
||||
if (__first == __last)
|
||||
return;
|
||||
--__last;
|
||||
difference_type __i = 0;
|
||||
while (__first != __last) {
|
||||
__skip_table_->insert(*__first, __pattern_length_ - 1 - __i);
|
||||
++__first;
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator2>
|
||||
pair<_RandomAccessIterator2, _RandomAccessIterator2>
|
||||
operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const {
|
||||
static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
|
||||
typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
|
||||
"Corpus and Pattern iterators must point to the same type");
|
||||
if (__first == __last)
|
||||
return std::make_pair(__last, __last);
|
||||
if (__first_ == __last_)
|
||||
return std::make_pair(__first, __first);
|
||||
|
||||
if (__pattern_length_ > __last - __first)
|
||||
return std::make_pair(__last, __last);
|
||||
|
||||
return __search(__first, __last);
|
||||
}
|
||||
|
||||
private:
|
||||
_RandomAccessIterator1 __first_;
|
||||
_RandomAccessIterator1 __last_;
|
||||
_BinaryPredicate __pred_;
|
||||
difference_type __pattern_length_;
|
||||
shared_ptr<__skip_table_type> __skip_table_;
|
||||
|
||||
template <class _RandomAccessIterator2>
|
||||
pair<_RandomAccessIterator2, _RandomAccessIterator2>
|
||||
__search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const {
|
||||
_RandomAccessIterator2 __current = __f;
|
||||
const _RandomAccessIterator2 __last = __l - __pattern_length_;
|
||||
const __skip_table_type& __skip_table = *__skip_table_;
|
||||
|
||||
while (__current <= __last) {
|
||||
difference_type __j = __pattern_length_;
|
||||
while (__pred_(__first_[__j - 1], __current[__j - 1])) {
|
||||
--__j;
|
||||
if (__j == 0)
|
||||
return std::make_pair(__current, __current + __pattern_length_);
|
||||
}
|
||||
__current += __skip_table[__current[__pattern_length_ - 1]];
|
||||
}
|
||||
return std::make_pair(__l, __l);
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H
|
|
@ -29,17 +29,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
template<class _Tp, class ..._Args, class = decltype(
|
||||
::new (declval<void*>()) _Tp(declval<_Args>()...)
|
||||
)>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
|
||||
_LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
|
||||
return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
|
||||
template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
|
||||
_LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
|
||||
return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) {
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
return std::construct_at(__location, std::forward<_Args>(__args)...);
|
||||
#else
|
||||
return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
|
||||
#endif
|
||||
}
|
||||
|
||||
// destroy_at
|
||||
|
||||
// The internal functions are available regardless of the language version (with the exception of the `__destroy_at`
|
||||
|
|
|
@ -964,7 +964,7 @@ shared_ptr<_Tp> make_shared(_Args&& ...__args)
|
|||
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
|
||||
template <size_t _Alignment>
|
||||
struct __sp_aligned_storage {
|
||||
|
@ -1042,7 +1042,7 @@ template<class _Array, class _Alloc, class... _Arg>
|
|||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Array> __allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&& ...__arg)
|
||||
{
|
||||
static_assert(is_unbounded_array_v<_Array>);
|
||||
static_assert(__libcpp_is_unbounded_array<_Array>::value);
|
||||
// We compute the number of bytes necessary to hold the control block and the
|
||||
// array elements. Then, we allocate an array of properly-aligned dummy structs
|
||||
// large enough to hold the control block and array. This allows shifting the
|
||||
|
@ -1052,7 +1052,7 @@ shared_ptr<_Array> __allocate_shared_unbounded_array(const _Alloc& __a, size_t _
|
|||
using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
|
||||
__allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage));
|
||||
_ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
|
||||
std::construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
|
||||
std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
|
||||
__guard.__release_ptr();
|
||||
return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
|
||||
}
|
||||
|
@ -1105,17 +1105,21 @@ template<class _Array, class _Alloc, class... _Arg>
|
|||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...__arg)
|
||||
{
|
||||
static_assert(is_bounded_array_v<_Array>);
|
||||
static_assert(__libcpp_is_bounded_array<_Array>::value);
|
||||
using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
|
||||
using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
|
||||
|
||||
__allocation_guard<_ControlBlockAlloc> __guard(__a, 1);
|
||||
_ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
|
||||
std::construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
|
||||
std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
|
||||
__guard.__release_ptr();
|
||||
return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
|
||||
|
|
|
@ -347,10 +347,6 @@ uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir
|
|||
__unreachable_sentinel(), __iter_move);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
// Destroys every element in the range [first, last) FROM RIGHT TO LEFT using allocator
|
||||
// destruction. If elements are themselves C-style arrays, they are recursively destroyed
|
||||
// in the same manner.
|
||||
|
@ -370,7 +366,7 @@ constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter
|
|||
return;
|
||||
|
||||
if constexpr (is_array_v<_ValueType>) {
|
||||
static_assert(!is_unbounded_array_v<_ValueType>,
|
||||
static_assert(!__libcpp_is_unbounded_array<_ValueType>::value,
|
||||
"arrays of unbounded arrays don't exist, but if they did we would mess up here");
|
||||
|
||||
using _Element = remove_extent_t<_ValueType>;
|
||||
|
@ -494,7 +490,7 @@ constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _Bid
|
|||
__guard.__complete();
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {};
|
||||
template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
template <class> struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {};
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {};
|
||||
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
template <class> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {};
|
||||
|
|
|
@ -79,10 +79,20 @@ _LIBCPP_PUSH_MACROS
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_LFTS
|
||||
|
||||
#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER
|
||||
# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER
|
||||
# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER
|
||||
#else
|
||||
# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead")
|
||||
# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead")
|
||||
# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::exprerimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead")
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
// default searcher
|
||||
template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
|
||||
class _LIBCPP_TEMPLATE_VIS default_searcher {
|
||||
class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher {
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
default_searcher(_ForwardIterator __f, _ForwardIterator __l,
|
||||
|
@ -106,7 +116,7 @@ private:
|
|||
};
|
||||
|
||||
template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY
|
||||
default_searcher<_ForwardIterator, _BinaryPredicate>
|
||||
make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
|
||||
{
|
||||
|
@ -152,7 +162,7 @@ private:
|
|||
typedef _Key key_type;
|
||||
|
||||
typedef typename make_unsigned<key_type>::type unsigned_key_type;
|
||||
typedef std::array<value_type, numeric_limits<unsigned_key_type>::max()> skip_map;
|
||||
typedef std::array<value_type, 256> skip_map;
|
||||
skip_map __table;
|
||||
|
||||
public:
|
||||
|
@ -179,7 +189,7 @@ public:
|
|||
template <class _RandomAccessIterator1,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
|
||||
class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
|
||||
private:
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
|
||||
|
@ -291,7 +301,7 @@ private:
|
|||
vector<difference_type> & __suffix = *__suffix_.get();
|
||||
if (__count > 0)
|
||||
{
|
||||
vector<value_type> __scratch(__count);
|
||||
vector<difference_type> __scratch(__count);
|
||||
|
||||
__compute_bm_prefix(__f, __l, __pred, __scratch);
|
||||
for ( size_t __i = 0; __i <= __count; __i++ )
|
||||
|
@ -316,7 +326,7 @@ private:
|
|||
template<class _RandomAccessIterator,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY
|
||||
boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
|
||||
make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
|
||||
_Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
|
||||
|
@ -328,7 +338,7 @@ make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
|
|||
template <class _RandomAccessIterator1,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
|
||||
class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
|
||||
private:
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
|
||||
|
@ -409,7 +419,7 @@ private:
|
|||
template<class _RandomAccessIterator,
|
||||
class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
|
||||
class _BinaryPredicate = equal_to<>>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY
|
||||
boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
|
||||
make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
|
||||
_Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
|
||||
|
|
|
@ -502,6 +502,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
|
|||
#include <__functional/bind_front.h>
|
||||
#include <__functional/binder1st.h>
|
||||
#include <__functional/binder2nd.h>
|
||||
#include <__functional/boyer_moore_searcher.h>
|
||||
#include <__functional/compose.h>
|
||||
#include <__functional/default_searcher.h>
|
||||
#include <__functional/function.h>
|
||||
|
|
|
@ -624,6 +624,7 @@ module std [system] {
|
|||
module bind_front { private header "__functional/bind_front.h" }
|
||||
module binder1st { private header "__functional/binder1st.h" }
|
||||
module binder2nd { private header "__functional/binder2nd.h" }
|
||||
module boyer_moore_searcher { private header "__functional/boyer_moore_searcher.h" }
|
||||
module compose { private header "__functional/compose.h" }
|
||||
module default_searcher { private header "__functional/default_searcher.h" }
|
||||
module function { private header "__functional/function.h" }
|
||||
|
|
|
@ -237,7 +237,7 @@ __cpp_lib_void_t 201411L <type_traits>
|
|||
# define __cpp_lib_as_const 201510L
|
||||
# define __cpp_lib_atomic_is_always_lock_free 201603L
|
||||
# define __cpp_lib_bool_constant 201505L
|
||||
// # define __cpp_lib_boyer_moore_searcher 201603L
|
||||
# define __cpp_lib_boyer_moore_searcher 201603L
|
||||
# define __cpp_lib_byte 201603L
|
||||
# define __cpp_lib_chrono 201611L
|
||||
# define __cpp_lib_clamp 201603L
|
||||
|
|
|
@ -290,6 +290,7 @@ END-SCRIPT
|
|||
#include <__functional/bind_front.h> // expected-error@*:* {{use of private header from outside its module: '__functional/bind_front.h'}}
|
||||
#include <__functional/binder1st.h> // expected-error@*:* {{use of private header from outside its module: '__functional/binder1st.h'}}
|
||||
#include <__functional/binder2nd.h> // expected-error@*:* {{use of private header from outside its module: '__functional/binder2nd.h'}}
|
||||
#include <__functional/boyer_moore_searcher.h> // expected-error@*:* {{use of private header from outside its module: '__functional/boyer_moore_searcher.h'}}
|
||||
#include <__functional/compose.h> // expected-error@*:* {{use of private header from outside its module: '__functional/compose.h'}}
|
||||
#include <__functional/default_searcher.h> // expected-error@*:* {{use of private header from outside its module: '__functional/default_searcher.h'}}
|
||||
#include <__functional/function.h> // expected-error@*:* {{use of private header from outside its module: '__functional/function.h'}}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
@ -34,6 +35,7 @@
|
|||
#include <experimental/algorithm>
|
||||
#include <experimental/functional>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
@ -122,9 +124,32 @@ test2()
|
|||
do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
|
||||
}
|
||||
|
||||
template <class Iter1, class Iter2>
|
||||
void test_large_str() {
|
||||
std::vector<signed char> data(257, 'a');
|
||||
data[254] = 'b';
|
||||
data[255] = 'b';
|
||||
data[256] = 'b';
|
||||
const signed char find[] = {'b', 'b', 'b'};
|
||||
do_search(Iter1(data.data()), Iter1(data.data() + data.size()),
|
||||
Iter2(find), Iter2(find + 3),
|
||||
Iter1(data.data() + 254));
|
||||
}
|
||||
|
||||
void test_custom_pred() {
|
||||
std::string long_string(1024, '0');
|
||||
auto searcher = std::experimental::make_boyer_moore_searcher(std::begin(long_string), std::end(long_string));
|
||||
const char str[] = "1234";
|
||||
auto ret = searcher(std::begin(str), std::end(str));
|
||||
assert(ret.first == std::end(str));
|
||||
assert(ret.second == std::end(str));
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
|
||||
test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
|
||||
test_large_str<random_access_iterator<const signed char*>, random_access_iterator<const signed char*>>();
|
||||
test_custom_pred();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// default searcher
|
||||
// template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -150,17 +150,11 @@
|
|||
# error "__cpp_lib_bind_front should not be defined before c++20"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_constexpr_functional
|
||||
|
@ -224,17 +218,11 @@
|
|||
# error "__cpp_lib_bind_front should have the value 201907L in c++20"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++20"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++20"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_constexpr_functional
|
||||
|
@ -322,17 +310,11 @@
|
|||
# error "__cpp_lib_bind_front should have the value 201907L in c++2b"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++2b"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2b"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++2b"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2b"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_constexpr_functional
|
||||
|
|
|
@ -1618,17 +1618,11 @@
|
|||
# error "__cpp_lib_bounded_array_traits should not be defined before c++20"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_byte
|
||||
|
@ -2579,17 +2573,11 @@
|
|||
# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++20"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++20"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_byte
|
||||
|
@ -3801,17 +3789,11 @@
|
|||
# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++2b"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++2b"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2b"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# ifndef __cpp_lib_boyer_moore_searcher
|
||||
# error "__cpp_lib_boyer_moore_searcher should be defined in c++2b"
|
||||
# endif
|
||||
# if __cpp_lib_boyer_moore_searcher != 201603L
|
||||
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2b"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_byte
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
@ -33,8 +32,9 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
@ -123,9 +123,19 @@ test2()
|
|||
do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
|
||||
}
|
||||
|
||||
void test_custom_pred() {
|
||||
std::string long_string(1024, '0');
|
||||
std::boyer_moore_searcher searcher(std::begin(long_string), std::end(long_string));
|
||||
const char str[] = "1234";
|
||||
auto ret = searcher(std::begin(str), std::end(str));
|
||||
assert(ret.first == std::end(str));
|
||||
assert(ret.second == std::end(str));
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
|
||||
test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
|
||||
test_custom_pred();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
@ -33,8 +32,8 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
@ -33,8 +32,8 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
@ -33,8 +32,8 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// XFAIL: stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// Test that <optional> provides all of the arithmetic, enum, and pointer
|
||||
// hash specializations.
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#include "poisoned_hash_helper.h"
|
||||
|
|
|
@ -176,7 +176,6 @@ feature_test_macros = [ add_version_header(x) for x in [
|
|||
"name": "__cpp_lib_boyer_moore_searcher",
|
||||
"values": { "c++17": 201603 },
|
||||
"headers": ["functional"],
|
||||
"unimplemented": True,
|
||||
}, {
|
||||
"name": "__cpp_lib_byte",
|
||||
"values": { "c++17": 201603 },
|
||||
|
|
Loading…
Reference in New Issue