1 //
2 // Copyright (C) 2024 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #ifndef BERBERIS_ANDROID_API_LIBVULKAN_SEARCH_H_
18 #define BERBERIS_ANDROID_API_LIBVULKAN_SEARCH_H_
19
20 #include <string.h>
21
22 #include <algorithm>
23 #include <type_traits>
24
25 namespace berberis {
26
27 // This is essentially std::sorted as in C++20.
28 template <class ForwardIterator, class Compare>
IsSorted(ForwardIterator first,ForwardIterator last,Compare comp)29 inline constexpr bool IsSorted(ForwardIterator first, ForwardIterator last, Compare comp) {
30 // Advancing past last may be undefined behavior. Handle that separately here.
31 if (first == last) {
32 return true;
33 }
34 for (auto tmp = first; ++tmp != last; first = tmp) {
35 if (comp(*tmp, *first)) {
36 return false;
37 }
38 }
39 return true;
40 }
41
StrCmpLess(const char * lhs,const char * rhs)42 inline constexpr bool StrCmpLess(const char* lhs, const char* rhs) {
43 if (__builtin_is_constant_evaluated()) {
44 for (;;) {
45 unsigned char lc = *lhs++;
46 unsigned char rc = *rhs++;
47 if (lc < rc) {
48 return true;
49 }
50 if (lc > rc) {
51 return false;
52 }
53 if (lc == '\0') {
54 return false;
55 }
56 }
57 } else {
58 return strcmp(lhs, rhs) < 0;
59 }
60 }
61
62 inline constexpr class StrCmpLessName {
63 public:
64 using is_transparent = void;
65
66 template <typename Type1, typename Type2>
operator()67 constexpr bool operator()(const Type1& lhs, const Type2& rhs) {
68 return StrCmpLess(lhs.name, rhs.name);
69 }
70 template <typename Type1>
operator()71 constexpr bool operator()(const Type1& lhs, const char* rhs) {
72 return StrCmpLess(lhs.name, rhs);
73 }
74 template <typename Type1>
operator()75 constexpr bool operator()(const char* lhs, const Type1& rhs) {
76 return StrCmpLess(lhs, rhs.name);
77 }
78 } StrCmpLessName;
79
80 template <typename Array>
FindElementByName(const Array & array,const char * name)81 auto FindElementByName(const Array& array, const char* name) {
82 auto element = std::lower_bound(std::begin(array), std::end(array), name, StrCmpLessName);
83 if (element != std::end(array) and strcmp(element->name, name) == 0) {
84 return element;
85 }
86 return decltype(element){};
87 }
88
89 } // namespace berberis
90
91 #endif // BERBERIS_ANDROID_API_LIBVULKAN_SEARCH_H_
92