1 #ifndef libjmmcg_core_memops_hpp
2 #define libjmmcg_core_memops_hpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "blatant_old_msvc_compiler_hacks.hpp"
25 #include "max_min.hpp"
26
27 #include <boost/mpl/assert.hpp>
28
29 #include <algorithm>
30 #include <cassert>
31 #include <cstdint>
32 #include <cstring>
33 #include <iostream>
34 #include <memory>
35
36 #include <immintrin.h>
37
38 #ifndef __SSE__
39 # error "At a miniumum SSE is required for the code to compile, please enable it with -march=native or -msse, or other suitable options and run the resultant binary on a suitable architecture."
40 #endif
41
42
43
44
45
46 namespace jmmcg {
47
48
49
50
51
52
53
54
55
56 template<class Iter1, class Iter2> inline void FORCE_INLINE
57 memcpy(Iter1 dest, Iter2 src, std::size_t n) noexcept(true);
58 template<> inline void FORCE_INLINE
59 memcpy<char *, char const *>(char *dest, char const *src, std::size_t n) noexcept(true);
60 template<> inline void FORCE_INLINE
61 memcpy<wchar_t *, wchar_t const *>(wchar_t *dest, wchar_t const *src, std::size_t n) noexcept(true);
62
63
64
65
66
67
68
69
70
71 template<class Iter1, class Iter2> inline void FORCE_INLINE
72 memmove(Iter1 dest, Iter2 src, std::size_t n) noexcept(true);
73 template<> inline void FORCE_INLINE
74 memmove<char *, char const *>(char *dest, char const *src, std::size_t n) noexcept(true);
75 template<> inline void FORCE_INLINE
76 memmove<wchar_t *, wchar_t const *>(wchar_t *dest, wchar_t const *src, std::size_t n) noexcept(true);
77
78
79
80
81
82
83
84
85
86 template<class Iter, class V> inline void FORCE_INLINE
87 memset(Iter dest, V i, std::size_t n) noexcept(true);
88 template<> inline void FORCE_INLINE
89 memset<char *, char>(char *dest, char i, std::size_t n) noexcept(true);
90 template<> inline void FORCE_INLINE
91 memset<wchar_t *, wchar_t>(wchar_t *dest, wchar_t i, std::size_t n) noexcept(true);
92
93
94
95
96
97
98
99
100
101
102 template<class Iter> inline bool FORCE_INLINE
103 memcmp(Iter src1, Iter src2, std::size_t n) noexcept(true);
104 template<> inline bool FORCE_INLINE
105 memcmp<char const *>(char const *src1, char const *src2, std::size_t n) noexcept(true);
106 template<> inline bool FORCE_INLINE
107 memcmp<wchar_t const *>(wchar_t const *src1, wchar_t const *src2, std::size_t n) noexcept(true);
108
109 template<class Val, std::size_t SrcSz, std::size_t DestSz> void FORCE_INLINE
110 memcpy(Val const (& src)[SrcSz], Val (& dest)[DestSz]) noexcept(false);
111
112
113
114
115
116
117
118
119
120
121
122
123 template<
124 std::size_t SrcSz,
125 std::size_t DestSz
126 >
127 inline constexpr void FORCE_INLINE
128 memcpy_opt(char const (&src)[SrcSz], char (&dest)[DestSz]) noexcept(true);
129
130
131
132
133
134
135
136
137
138
139
140
141
142 template<
143 std::size_t FirstSz,
144 std::size_t SecondSz
145 >
146 inline constexpr bool FORCE_INLINE
147 memcmp_opt(char const (&first)[FirstSz], char const (&second)[SecondSz]) noexcept(true);
148
149
150
151
152
153
154
155
156
157
158
159
160
161 template<
162 char const needle,
163 std::size_t FirstSz
164 >
165 inline constexpr char const * FORCE_INLINE
166 strchr_opt(char const (&haystack)[FirstSz]) noexcept(true) __attribute__((pure));
167
168
169
170
171
172
173
174
175
176
177
178
179
180 template<
181 std::size_t FirstSz,
182 std::size_t SecondSz,
183 class LessThan32BytesLong=typename std::enable_if<SecondSz<=32>::type
184 >
185 inline constexpr char const * FORCE_INLINE
186 strstr_opt(char const (&haystack)[FirstSz], char const (&needle)[SecondSz]) noexcept(true) __attribute__((pure));
187
188 template<
189 std::size_t SrcSz,
190 std::size_t DestSz
191 >
192 inline constexpr void FORCE_INLINE
193 memcpy_opt(std::array<char, SrcSz> const &src, std::array<char, DestSz> &dest) noexcept(true);
194 template<
195 std::size_t SrcSz,
196 std::size_t DestSz
197 >
198 inline constexpr void FORCE_INLINE
199 memcpy_opt(std::array<uint8_t, SrcSz> const &src, std::array<uint8_t, DestSz> &dest) noexcept(true);
200
201 template<
202 std::size_t Sz
203 >
204 inline bool FORCE_INLINE
205 memcmp(std::array<char, Sz> const &src1, std::array<char, Sz> const &src2) noexcept(true);
206 template<
207 std::size_t Sz
208 >
209 inline bool FORCE_INLINE
210 memcmp(std::array<uint8_t, Sz> const &src1, std::array<uint8_t, Sz> const &src2) noexcept(true);
211
212 template<
213 std::size_t Sz
214 >
215 inline bool FORCE_INLINE
216 operator==(std::array<char, Sz> const &src1, std::array<char, Sz> const &src2) noexcept(true);
217 template<
218 std::size_t Sz
219 >
220 inline bool FORCE_INLINE
221 operator==(std::array<uint8_t, Sz> const &src1, std::array<uint8_t, Sz> const &src2) noexcept(true);
222
223
224
225
226
227
228
229
230
231
232 template<
233 std::size_t SrcSz,
234 std::size_t DestSz
235 >
236 inline constexpr void FORCE_INLINE
237 memcpy_slow(char const (& src)[SrcSz], char (& dest)[DestSz]) noexcept(true);
238
239 template<class T, class V=std::pair<typename T::value_type const *, typename T::value_type const *>> inline T FORCE_INLINE
240 copy(V const &src) noexcept(true);
241
242 template<
243 std::size_t SrcSz,
244 std::size_t DestSz
245 > inline constexpr std::array<char, DestSz> FORCE_INLINE
246 copy(std::array<char, SrcSz> const &src) noexcept(true);
247
248 template<
249 std::size_t SrcSz,
250 std::size_t DestSz
251 > inline constexpr std::array<uint8_t, DestSz> FORCE_INLINE
252 copy(std::array<uint8_t, SrcSz> const &src) noexcept(true);
253
254 }
255
256 namespace std {
257
258 template<
259 std::size_t Sz
260 >
261 inline std::ostream &
262 operator<<(std::ostream &os, std::array<char, Sz> const &src);
263
264 }
265
266 #include "memops_impl.hpp"
267
268 #endif