1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___ALGORITHM_FIND_H
11 #define _LIBCPP___ALGORITHM_FIND_H
12 
13 #include <__algorithm/unwrap_iter.h>
14 #include <__config>
15 #include <__functional/identity.h>
16 #include <__functional/invoke.h>
17 #include <__string/constexpr_c_functions.h>
18 #include <__type_traits/is_same.h>
19 
20 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
21 #  include <cwchar>
22 #endif
23 
24 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25 #  pragma GCC system_header
26 #endif
27 
28 _LIBCPP_BEGIN_NAMESPACE_STD
29 
30 template <class _Iter, class _Sent, class _Tp, class _Proj>
31 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
32 __find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
33   for (; __first != __last; ++__first)
34     if (std::__invoke(__proj, *__first) == __value)
35       break;
36   return __first;
37 }
38 
39 template <class _Tp,
40           class _Up,
41           class _Proj,
42           __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
43                             sizeof(_Tp) == 1,
44                         int> = 0>
45 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
46 __find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
47   if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
48     return __ret;
49   return __last;
50 }
51 
52 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
53 template <class _Tp,
54           class _Up,
55           class _Proj,
56           __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
57                             sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
58                         int> = 0>
59 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
60 __find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
61   if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
62     return __ret;
63   return __last;
64 }
65 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
66 
67 template <class _InputIterator, class _Tp>
68 _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
69 find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
70   __identity __proj;
71   return std::__rewrap_iter(
72       __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
73 }
74 
75 _LIBCPP_END_NAMESPACE_STD
76 
77 #endif // _LIBCPP___ALGORITHM_FIND_H
78