ReactOS 0.4.16-dev-1059-gb1cf981
bsearch.cpp
Go to the documentation of this file.
1//
2// bsearch.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines bsearch(), which performs a binary search over an array.
7//
8#include <corecrt_internal.h>
9#include <search.h>
10
11#ifdef _M_CEE
12 #define __fileDECL __clrcall
13#else
14 #define __fileDECL __cdecl
15#endif
16
17/***
18*char *bsearch() - do a binary search on an array
19*
20*Purpose:
21* Does a binary search of a sorted array for a key.
22*
23*Entry:
24* const char *key - key to search for
25* const char *base - base of sorted array to search
26* unsigned int num - number of elements in array
27* unsigned int width - number of bytes per element
28* int (*compare)() - pointer to function that compares two array
29* elements, returning neg when #1 < #2, pos when #1 > #2, and
30* 0 when they are equal. Function is passed pointers to two
31* array elements.
32*
33*Exit:
34* if key is found:
35* returns pointer to occurrence of key in array
36* if key is not found:
37* returns nullptr
38*
39*Exceptions:
40* Input parameters are validated. Refer to the validation section of the function.
41*
42*******************************************************************************/
43
44#ifdef __USE_CONTEXT
45 #define __COMPARE(context, p1, p2) (*compare)(context, p1, p2)
46#else
47 #define __COMPARE(context, p1, p2) (*compare)(p1, p2)
48#endif
49
50#ifndef _M_CEE
51extern "C"
52#endif
53
55#ifdef __USE_CONTEXT
56void* __fileDECL bsearch_s(
57 void const* const key,
58 void const* const base,
59 size_t num,
60 size_t const width,
61 int (__fileDECL* const compare)(void*, void const*, void const*),
62 void* const context
63 )
64#else // __USE_CONTEXT
66 void const* const key,
67 void const* const base,
68 size_t num,
69 size_t const width,
70 int (__fileDECL* const compare)(void const*, void const*)
71 )
72#endif // __USE_CONTEXT
73{
74 _VALIDATE_RETURN(base != nullptr || num == 0, EINVAL, nullptr);
75 _VALIDATE_RETURN(width > 0, EINVAL, nullptr);
76 _VALIDATE_RETURN(compare != nullptr, EINVAL, nullptr);
77
78 char const* lo = reinterpret_cast<char const*>(base);
79 char const* hi = reinterpret_cast<char const*>(base) + (num - 1) * width;
80
81 // Reentrancy diligence: Save (and unset) global-state mode to the stack before making callout to 'compare'
82 __crt_state_management::scoped_global_state_reset saved_state;
83
84 // We allow a nullptr key here because it breaks some older code and because
85 // we do not dereference this ourselves so we can't be sure that it's a
86 // problem for the comparison function
87
88 while (lo <= hi)
89 {
90 size_t const half = num / 2;
91 if (half != 0)
92 {
93 char const* const mid = lo + (num & 1 ? half : (half - 1)) * width;
94
95 int const result = __COMPARE(context, key, mid);
96 if (result == 0)
97 {
98 return const_cast<void*>(static_cast<void const*>(mid));
99 }
100 else if (result < 0)
101 {
102 hi = mid - width;
103 num = num & 1 ? half : half - 1;
104 }
105 else
106 {
107 lo = mid + width;
108 num = half;
109 }
110 }
111 else if (num != 0)
112 {
113 return __COMPARE(context, key, lo)
114 ? nullptr
115 : const_cast<void*>(static_cast<void const*>(lo));
116 }
117 else
118 {
119 break;
120 }
121 }
122
123 return nullptr;
124}
125
126#undef __COMPARE
#define EINVAL
Definition: acclib.h:90
#define __fileDECL
Definition: bsearch.cpp:14
#define __COMPARE(context, p1, p2)
Definition: bsearch.cpp:47
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
return nullptr
Definition: expand.cpp:78
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
#define _CRT_SECURITYSAFECRITICAL_ATTRIBUTE
Definition: bug.cpp:8
Definition: http.c:7252
Definition: copy.c:22
#define bsearch
#define const
Definition: zconf.h:233