LIEF: Library to Instrument Executable Formats
Version 1.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
lief-install
x86_64
static
include
frozen
algorithm.h
Go to the documentation of this file.
1
/*
2
* Frozen
3
* Copyright 2016 QuarksLab
4
*
5
* Licensed to the Apache Software Foundation (ASF) under one
6
* or more contributor license agreements. See the NOTICE file
7
* distributed with this work for additional information
8
* regarding copyright ownership. The ASF licenses this file
9
* to you under the Apache License, Version 2.0 (the
10
* "License"); you may not use this file except in compliance
11
* with the License. You may obtain a copy of the License at
12
*
13
* http://www.apache.org/licenses/LICENSE-2.0
14
*
15
* Unless required by applicable law or agreed to in writing,
16
* software distributed under the License is distributed on an
17
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18
* KIND, either express or implied. See the License for the
19
* specific language governing permissions and limitations
20
* under the License.
21
*/
22
23
#ifndef FROZEN_LETITGO_ALGORITHM_H
24
#define FROZEN_LETITGO_ALGORITHM_H
25
26
#include "
frozen/bits/basic_types.h
"
27
#include "
frozen/bits/version.h
"
28
#include "
frozen/string.h
"
29
30
namespace
frozen
{
31
32
// 'search' implementation if C++17 is not available
33
// https://en.cppreference.com/w/cpp/algorithm/search
34
template
<
class
ForwardIterator,
class
Searcher>
35
ForwardIterator
search
(ForwardIterator first, ForwardIterator last,
const
Searcher & searcher)
36
{
37
return
searcher(first, last).first;
38
}
39
40
// text book implementation from
41
// https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
42
43
template
<std::
size_t
size>
class
knuth_morris_pratt_searcher
{
44
bits::carray<std::ptrdiff_t, size>
step_;
45
bits::carray<char, size>
needle_;
46
47
static
constexpr
bits::carray<std::ptrdiff_t, size>
48
build_kmp_cache(
char
const
(&needle)[size + 1]) {
49
std::ptrdiff_t cnd = 0;
50
bits::carray<std::ptrdiff_t, size>
cache(-1);
51
for
(std::size_t pos = 1; pos < size; ++pos) {
52
if
(needle[pos] == needle[cnd]) {
53
cache[pos] = cache[cnd];
54
cnd += 1;
55
}
else
{
56
cache[pos] = cnd;
57
cnd = cache[cnd];
58
while
(cnd >= 0 && needle[pos] != needle[cnd])
59
cnd = cache[cnd];
60
cnd += 1;
61
}
62
}
63
return
cache;
64
}
65
66
public
:
67
constexpr
knuth_morris_pratt_searcher
(
char
const
(&needle)[size + 1])
68
: step_{build_kmp_cache(needle)}, needle_(needle) {}
69
70
template
<
class
ForwardIterator>
71
constexpr
std::pair<ForwardIterator, ForwardIterator>
operator()
(ForwardIterator first, ForwardIterator last)
const
{
72
std::size_t i = 0;
73
ForwardIterator iter = first;
74
while
(iter != last) {
75
if
(needle_[i] == *iter) {
76
if
(i == (size - 1))
77
return
{ iter - i, iter - i + size };
78
++i;
79
++iter;
80
}
else
{
81
if
(step_[i] > -1) {
82
i = step_[i];
83
}
else
{
84
++iter;
85
i = 0;
86
}
87
}
88
}
89
return
{ last, last };
90
}
91
};
92
93
template
<std::
size_t
N>
94
constexpr
knuth_morris_pratt_searcher
<N - 1>
make_knuth_morris_pratt_searcher
(
char
const
(&needle)[N]) {
95
return
{needle};
96
}
97
98
// text book implementation from
99
// https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
100
101
template
<std::
size_t
size>
class
boyer_moore_searcher
{
102
using
skip_table_type =
bits::carray
<std::ptrdiff_t,
sizeof
(char) << 8>;
103
using
suffix_table_type =
bits::carray<std::ptrdiff_t, size>
;
104
105
skip_table_type skip_table_;
106
suffix_table_type suffix_table_;
107
bits::carray<char, size>
needle_;
108
109
constexpr
auto
build_skip_table(
char
const
(&needle)[size + 1]) {
110
skip_table_type skip_table(size);
111
for
(std::size_t i = 0; i < size - 1; ++i)
112
skip_table[needle[i]] -= i + 1;
113
return
skip_table;
114
}
115
116
constexpr
bool
is_prefix(
char
const
(&needle)[size + 1], std::size_t pos) {
117
std::size_t suffixlen = size - pos;
118
119
for
(std::size_t i = 0; i < suffixlen; i++) {
120
if
(needle[i] != needle[pos + i])
121
return
false
;
122
}
123
return
true
;
124
}
125
126
constexpr
std::size_t suffix_length(
char
const
(&needle)[size + 1],
127
std::size_t pos) {
128
// increment suffix length slen to the first mismatch or beginning
129
// of the word
130
for
(std::size_t slen = 0; slen < pos ; slen++)
131
if
(needle[pos - slen] != needle[size - 1 - slen])
132
return
slen;
133
134
return
pos;
135
}
136
137
constexpr
auto
build_suffix_table(
char
const
(&needle)[size + 1]) {
138
suffix_table_type suffix;
139
std::ptrdiff_t last_prefix_index = size - 1;
140
141
// first loop
142
for
(std::ptrdiff_t p = size - 1; p >= 0; p--) {
143
if
(is_prefix(needle, p + 1))
144
last_prefix_index = p + 1;
145
146
suffix[p] = last_prefix_index + (size - 1 - p);
147
}
148
149
// second loop
150
for
(std::size_t p = 0; p < size - 1; p++) {
151
auto
slen = suffix_length(needle, p);
152
if
(needle[p - slen] != needle[size - 1 - slen])
153
suffix[size - 1 - slen] = size - 1 - p + slen;
154
155
}
156
return
suffix;
157
}
158
159
public
:
160
constexpr
boyer_moore_searcher
(
char
const
(&needle)[size + 1])
161
: skip_table_{build_skip_table(needle)},
162
suffix_table_{build_suffix_table(needle)},
163
needle_(needle) {}
164
165
template
<
class
RandomAccessIterator>
166
constexpr
std::pair<RandomAccessIterator, RandomAccessIterator>
operator()
(RandomAccessIterator first, RandomAccessIterator last)
const
{
167
if
(size == 0)
168
return
{ first, first };
169
170
if
(size >
size_t
(last - first))
171
return
{ last, last };
172
173
RandomAccessIterator iter = first + size - 1;
174
while
(
true
) {
175
std::ptrdiff_t j = size - 1;
176
while
(j > 0 && (*iter == needle_[j])) {
177
--iter;
178
--j;
179
}
180
if
(j == 0 && *iter == needle_[0])
181
return
{ iter, iter + size};
182
183
std::ptrdiff_t jump = std::max(skip_table_[*iter], suffix_table_[j]);
184
if
(jump >= last - iter)
185
return
{ last, last };
186
iter += jump;
187
}
188
}
189
};
190
191
template
<std::
size_t
N>
192
constexpr
boyer_moore_searcher
<N - 1>
make_boyer_moore_searcher
(
char
const
(&needle)[N]) {
193
return
{needle};
194
}
195
196
}
// namespace frozen
197
198
#endif
basic_types.h
frozen::bits::carray
Definition
basic_types.h:90
frozen::boyer_moore_searcher
Definition
algorithm.h:101
frozen::boyer_moore_searcher::boyer_moore_searcher
constexpr boyer_moore_searcher(char const (&needle)[size+1])
Definition
algorithm.h:160
frozen::boyer_moore_searcher::operator()
constexpr std::pair< RandomAccessIterator, RandomAccessIterator > operator()(RandomAccessIterator first, RandomAccessIterator last) const
Definition
algorithm.h:166
frozen::knuth_morris_pratt_searcher
Definition
algorithm.h:43
frozen::knuth_morris_pratt_searcher::operator()
constexpr std::pair< ForwardIterator, ForwardIterator > operator()(ForwardIterator first, ForwardIterator last) const
Definition
algorithm.h:71
frozen::knuth_morris_pratt_searcher::knuth_morris_pratt_searcher
constexpr knuth_morris_pratt_searcher(char const (&needle)[size+1])
Definition
algorithm.h:67
version.h
frozen
Definition
algorithm.h:30
frozen::make_boyer_moore_searcher
constexpr boyer_moore_searcher< N - 1 > make_boyer_moore_searcher(char const (&needle)[N])
Definition
algorithm.h:192
frozen::make_knuth_morris_pratt_searcher
constexpr knuth_morris_pratt_searcher< N - 1 > make_knuth_morris_pratt_searcher(char const (&needle)[N])
Definition
algorithm.h:94
frozen::search
ForwardIterator search(ForwardIterator first, ForwardIterator last, const Searcher &searcher)
Definition
algorithm.h:35
string.h
Generated by
1.17.0