├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── ext
├── doctest.h
├── fmt
│ ├── fmtlib.cc
│ └── fmtlib.h
├── gsl
│ ├── gsl
│ ├── gsl_algorithm
│ ├── gsl_assert
│ ├── gsl_byte
│ ├── gsl_util
│ ├── multi_span
│ ├── span
│ └── string_span
└── json.hpp
├── src
├── file
│ ├── dbcfile.h
│ ├── dbcmetaparser.cpp
│ ├── dbcmetaparser.h
│ ├── dbcparser.cpp
│ ├── dbcparser.h
│ ├── dbcwriter.cpp
│ ├── dbcwriter.h
│ ├── jsonreader.cpp
│ ├── jsonreader.h
│ ├── jsonwriter.cpp
│ └── jsonwriter.h
├── main.cpp
├── models
│ ├── canbusdefmodel.cpp
│ ├── canbusdefmodel.h
│ ├── canbusmodel.cpp
│ ├── canbusmodel.h
│ ├── canframedefitem.cpp
│ ├── canframedefitem.h
│ ├── canframeitem.cpp
│ ├── canframeitem.h
│ ├── cansignaldefitem.cpp
│ ├── cansignaldefitem.h
│ ├── cansignalitem.cpp
│ ├── cansignalitem.h
│ ├── treeitem.cpp
│ ├── treeitem.h
│ ├── treeitemid.h
│ ├── treemodel.cpp
│ ├── treemodel.h
│ ├── valuedefitem.cpp
│ ├── valuedefitem.h
│ ├── valuedefmodel.cpp
│ └── valuedefmodel.h
├── network
│ ├── canudpreceiver.cpp
│ ├── canudpreceiver.h
│ ├── dummyreceiver.h
│ ├── udpasyncreceiver.cpp
│ ├── udpasyncreceiver.h
│ └── udpsocketguard.h
├── tincan
│ ├── canbus.cpp
│ ├── canbus.h
│ ├── canbusdef.h
│ ├── canframe.h
│ ├── canframedef.h
│ ├── canrawframe.h
│ ├── cansignal.h
│ ├── cansignaldef.h
│ ├── cantracer.cpp
│ ├── cantracer.h
│ ├── errors.h
│ ├── helper.h
│ ├── signalutil.cpp
│ ├── signalutil.h
│ ├── simulator.cpp
│ ├── simulator.h
│ ├── translate.cpp
│ └── translate.h
├── ui
│ ├── mainwindow.cpp
│ ├── mainwindow.h
│ ├── treeviewdialog.cpp
│ └── treeviewdialog.h
├── util.cpp
└── util.h
├── test
├── dbcparser_test.cpp
├── makefile
├── signalutil_test.cpp
└── test.dbc
├── tincan.png
├── tincan.pro
├── tincan_treeview.png
└── ui
├── mainwindow.ui
└── treeviewdialog.ui
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Default behavior
2 | * text eol=lf
3 |
4 | # Explicitly declare text files
5 | *.c text
6 | *.cc text
7 | *.cpp text
8 | *.h text
9 | *.hh text
10 | *.hpp text
11 | *.pro text
12 | *.qrc text
13 | *.conf text
14 | *.md text
15 |
16 | # Denote all files that are truly binary and should not be modified
17 | *.png binary
18 | *.jpg binary
19 | *.ico binary
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
34 | # Project files
35 | *.user
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Peter Ebermann
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tincan
2 |

3 | Visualization of CAN bus traffic via UDP interface
4 |
5 | Description
6 | ---
7 | Tincan decodes and displays CAN frames. The default interface is via UDP socket and requires a gateway device, e.g. a Raspberry Pi 3 with a PiCAN2 HAT running [cangw](https://github.com/mwkpe/cantools), or any CAN to UDP gateway that sends raw frames. Adding other interfaces can be done by adapting the [dummy receiver](src/network/dummyreceiver.h).
8 |
9 | Features
10 | ---
11 | * Import of frame, signal and value definitions from DBC files
12 | * Live view of received frames and signals in a [tree view](tincan_treeview.png).
13 | * Simple trace view of frame and signal data
14 |
15 | Status
16 | ---
17 | WIP
18 |
19 | Build
20 | ---
21 | Building requires the Qt framework (Qt 5.12+ MinGW 7.3). The project file must be modified where absolute paths to boost and Asio were used. The other libs are part of the repo.
22 |
23 | Acknowledgements
24 | ---
25 | Tincan is using [Qt](http://https://www.qt.io), [boost](http://www.boost.org/), [Spirit X3](http://boost-spirit.com), [Asio](https://think-async.com/), [GSL](https://github.com/Microsoft/GSL), [fmt](https://github.com/fmtlib/fmt), [JSON](https://github.com/nlohmann/json) and [doctest](https://github.com/onqtam/doctest).
26 |
--------------------------------------------------------------------------------
/ext/fmt/fmtlib.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Formatting library for C++
3 |
4 | Copyright (c) 2012 - 2016, Victor Zverovich
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #include "fmtlib.h"
29 |
30 | #include
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include // for std::ptrdiff_t
38 |
39 | #if defined(_WIN32) && defined(__MINGW32__)
40 | # include
41 | #endif
42 |
43 | #if FMT_USE_WINDOWS_H
44 | # if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
45 | # define WIN32_LEAN_AND_MEAN
46 | # endif
47 | # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
48 | # include
49 | # else
50 | # define NOMINMAX
51 | # include
52 | # undef NOMINMAX
53 | # endif
54 | #endif
55 |
56 | #if FMT_EXCEPTIONS
57 | # define FMT_TRY try
58 | # define FMT_CATCH(x) catch (x)
59 | #else
60 | # define FMT_TRY if (true)
61 | # define FMT_CATCH(x) if (false)
62 | #endif
63 |
64 | #ifdef _MSC_VER
65 | # pragma warning(push)
66 | # pragma warning(disable: 4127) // conditional expression is constant
67 | # pragma warning(disable: 4702) // unreachable code
68 | // Disable deprecation warning for strerror. The latter is not called but
69 | // MSVC fails to detect it.
70 | # pragma warning(disable: 4996)
71 | #endif
72 |
73 | // Dummy implementations of strerror_r and strerror_s called if corresponding
74 | // system functions are not available.
75 | static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
76 | return fmt::internal::Null<>();
77 | }
78 | static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
79 | return fmt::internal::Null<>();
80 | }
81 |
82 | namespace fmt {
83 |
84 | FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {}
85 | FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {}
86 | FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {}
87 |
88 | namespace {
89 |
90 | #ifndef _MSC_VER
91 | # define FMT_SNPRINTF snprintf
92 | #else // _MSC_VER
93 | inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
94 | va_list args;
95 | va_start(args, format);
96 | int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
97 | va_end(args);
98 | return result;
99 | }
100 | # define FMT_SNPRINTF fmt_snprintf
101 | #endif // _MSC_VER
102 |
103 | #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
104 | # define FMT_SWPRINTF snwprintf
105 | #else
106 | # define FMT_SWPRINTF swprintf
107 | #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
108 |
109 | const char RESET_COLOR[] = "\x1b[0m";
110 |
111 | typedef void (*FormatFunc)(Writer &, int, StringRef);
112 |
113 | // Portable thread-safe version of strerror.
114 | // Sets buffer to point to a string describing the error code.
115 | // This can be either a pointer to a string stored in buffer,
116 | // or a pointer to some static immutable string.
117 | // Returns one of the following values:
118 | // 0 - success
119 | // ERANGE - buffer is not large enough to store the error message
120 | // other - failure
121 | // Buffer should be at least of size 1.
122 | int safe_strerror(
123 | int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
124 | FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
125 |
126 | class StrError {
127 | private:
128 | int error_code_;
129 | char *&buffer_;
130 | std::size_t buffer_size_;
131 |
132 | // A noop assignment operator to avoid bogus warnings.
133 | void operator=(const StrError &) {}
134 |
135 | // Handle the result of XSI-compliant version of strerror_r.
136 | int handle(int result) {
137 | // glibc versions before 2.13 return result in errno.
138 | return result == -1 ? errno : result;
139 | }
140 |
141 | // Handle the result of GNU-specific version of strerror_r.
142 | int handle(char *message) {
143 | // If the buffer is full then the message is probably truncated.
144 | if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
145 | return ERANGE;
146 | buffer_ = message;
147 | return 0;
148 | }
149 |
150 | // Handle the case when strerror_r is not available.
151 | int handle(internal::Null<>) {
152 | return fallback(strerror_s(buffer_, buffer_size_, error_code_));
153 | }
154 |
155 | // Fallback to strerror_s when strerror_r is not available.
156 | int fallback(int result) {
157 | // If the buffer is full then the message is probably truncated.
158 | return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
159 | ERANGE : result;
160 | }
161 |
162 | // Fallback to strerror if strerror_r and strerror_s are not available.
163 | int fallback(internal::Null<>) {
164 | errno = 0;
165 | buffer_ = strerror(error_code_);
166 | return errno;
167 | }
168 |
169 | public:
170 | StrError(int err_code, char *&buf, std::size_t buf_size)
171 | : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
172 |
173 | int run() {
174 | // Suppress a warning about unused strerror_r.
175 | strerror_r(0, FMT_NULL, "");
176 | return handle(strerror_r(error_code_, buffer_, buffer_size_));
177 | }
178 | };
179 | return StrError(error_code, buffer, buffer_size).run();
180 | }
181 |
182 | void format_error_code(Writer &out, int error_code,
183 | StringRef message) FMT_NOEXCEPT {
184 | // Report error code making sure that the output fits into
185 | // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
186 | // bad_alloc.
187 | out.clear();
188 | static const char SEP[] = ": ";
189 | static const char ERROR_STR[] = "error ";
190 | // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
191 | std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
192 | typedef internal::IntTraits::MainType MainType;
193 | MainType abs_value = static_cast(error_code);
194 | if (internal::is_negative(error_code)) {
195 | abs_value = 0 - abs_value;
196 | ++error_code_size;
197 | }
198 | error_code_size += internal::count_digits(abs_value);
199 | if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
200 | out << message << SEP;
201 | out << ERROR_STR << error_code;
202 | assert(out.size() <= internal::INLINE_BUFFER_SIZE);
203 | }
204 |
205 | void report_error(FormatFunc func, int error_code,
206 | StringRef message) FMT_NOEXCEPT {
207 | MemoryWriter full_message;
208 | func(full_message, error_code, message);
209 | // Use Writer::data instead of Writer::c_str to avoid potential memory
210 | // allocation.
211 | std::fwrite(full_message.data(), full_message.size(), 1, stderr);
212 | std::fputc('\n', stderr);
213 | }
214 | } // namespace
215 |
216 | FMT_FUNC void SystemError::init(
217 | int err_code, CStringRef format_str, ArgList args) {
218 | error_code_ = err_code;
219 | MemoryWriter w;
220 | format_system_error(w, err_code, format(format_str, args));
221 | std::runtime_error &base = *this;
222 | base = std::runtime_error(w.str());
223 | }
224 |
225 | template
226 | int internal::CharTraits::format_float(
227 | char *buffer, std::size_t size, const char *format,
228 | unsigned width, int precision, T value) {
229 | if (width == 0) {
230 | return precision < 0 ?
231 | FMT_SNPRINTF(buffer, size, format, value) :
232 | FMT_SNPRINTF(buffer, size, format, precision, value);
233 | }
234 | return precision < 0 ?
235 | FMT_SNPRINTF(buffer, size, format, width, value) :
236 | FMT_SNPRINTF(buffer, size, format, width, precision, value);
237 | }
238 |
239 | template
240 | int internal::CharTraits::format_float(
241 | wchar_t *buffer, std::size_t size, const wchar_t *format,
242 | unsigned width, int precision, T value) {
243 | if (width == 0) {
244 | return precision < 0 ?
245 | FMT_SWPRINTF(buffer, size, format, value) :
246 | FMT_SWPRINTF(buffer, size, format, precision, value);
247 | }
248 | return precision < 0 ?
249 | FMT_SWPRINTF(buffer, size, format, width, value) :
250 | FMT_SWPRINTF(buffer, size, format, width, precision, value);
251 | }
252 |
253 | template
254 | const char internal::BasicData::DIGITS[] =
255 | "0001020304050607080910111213141516171819"
256 | "2021222324252627282930313233343536373839"
257 | "4041424344454647484950515253545556575859"
258 | "6061626364656667686970717273747576777879"
259 | "8081828384858687888990919293949596979899";
260 |
261 | #define FMT_POWERS_OF_10(factor) \
262 | factor * 10, \
263 | factor * 100, \
264 | factor * 1000, \
265 | factor * 10000, \
266 | factor * 100000, \
267 | factor * 1000000, \
268 | factor * 10000000, \
269 | factor * 100000000, \
270 | factor * 1000000000
271 |
272 | template
273 | const uint32_t internal::BasicData::POWERS_OF_10_32[] = {
274 | 0, FMT_POWERS_OF_10(1)
275 | };
276 |
277 | template
278 | const uint64_t internal::BasicData::POWERS_OF_10_64[] = {
279 | 0,
280 | FMT_POWERS_OF_10(1),
281 | FMT_POWERS_OF_10(ULongLong(1000000000)),
282 | // Multiply several constants instead of using a single long long constant
283 | // to avoid warnings about C++98 not supporting long long.
284 | ULongLong(1000000000) * ULongLong(1000000000) * 10
285 | };
286 |
287 | FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
288 | (void)type;
289 | if (std::isprint(static_cast(code))) {
290 | FMT_THROW(FormatError(
291 | format("unknown format code '{}' for {}", code, type)));
292 | }
293 | FMT_THROW(FormatError(
294 | format("unknown format code '\\x{:02x}' for {}",
295 | static_cast(code), type)));
296 | }
297 |
298 | #if FMT_USE_WINDOWS_H
299 |
300 | FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
301 | static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
302 | if (s.size() > INT_MAX)
303 | FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
304 | int s_size = static_cast(s.size());
305 | int length = MultiByteToWideChar(
306 | CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
307 | if (length == 0)
308 | FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
309 | buffer_.resize(length + 1);
310 | length = MultiByteToWideChar(
311 | CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
312 | if (length == 0)
313 | FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
314 | buffer_[length] = 0;
315 | }
316 |
317 | FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
318 | if (int error_code = convert(s)) {
319 | FMT_THROW(WindowsError(error_code,
320 | "cannot convert string from UTF-16 to UTF-8"));
321 | }
322 | }
323 |
324 | FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) {
325 | if (s.size() > INT_MAX)
326 | return ERROR_INVALID_PARAMETER;
327 | int s_size = static_cast(s.size());
328 | int length = WideCharToMultiByte(
329 | CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
330 | if (length == 0)
331 | return GetLastError();
332 | buffer_.resize(length + 1);
333 | length = WideCharToMultiByte(
334 | CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
335 | if (length == 0)
336 | return GetLastError();
337 | buffer_[length] = 0;
338 | return 0;
339 | }
340 |
341 | FMT_FUNC void WindowsError::init(
342 | int err_code, CStringRef format_str, ArgList args) {
343 | error_code_ = err_code;
344 | MemoryWriter w;
345 | internal::format_windows_error(w, err_code, format(format_str, args));
346 | std::runtime_error &base = *this;
347 | base = std::runtime_error(w.str());
348 | }
349 |
350 | FMT_FUNC void internal::format_windows_error(
351 | Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
352 | FMT_TRY {
353 | MemoryBuffer buffer;
354 | buffer.resize(INLINE_BUFFER_SIZE);
355 | for (;;) {
356 | wchar_t *system_message = &buffer[0];
357 | int result = FormatMessageW(
358 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
359 | FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
360 | system_message, static_cast(buffer.size()), FMT_NULL);
361 | if (result != 0) {
362 | UTF16ToUTF8 utf8_message;
363 | if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
364 | out << message << ": " << utf8_message;
365 | return;
366 | }
367 | break;
368 | }
369 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
370 | break; // Can't get error message, report error code instead.
371 | buffer.resize(buffer.size() * 2);
372 | }
373 | } FMT_CATCH(...) {}
374 | fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
375 | }
376 |
377 | #endif // FMT_USE_WINDOWS_H
378 |
379 | FMT_FUNC void format_system_error(
380 | Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
381 | FMT_TRY {
382 | internal::MemoryBuffer buffer;
383 | buffer.resize(internal::INLINE_BUFFER_SIZE);
384 | for (;;) {
385 | char *system_message = &buffer[0];
386 | int result = safe_strerror(error_code, system_message, buffer.size());
387 | if (result == 0) {
388 | out << message << ": " << system_message;
389 | return;
390 | }
391 | if (result != ERANGE)
392 | break; // Can't get error message, report error code instead.
393 | buffer.resize(buffer.size() * 2);
394 | }
395 | } FMT_CATCH(...) {}
396 | fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
397 | }
398 |
399 | template
400 | void internal::ArgMap::init(const ArgList &args) {
401 | if (!map_.empty())
402 | return;
403 | typedef internal::NamedArg NamedArg;
404 | const NamedArg *named_arg = FMT_NULL;
405 | bool use_values =
406 | args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
407 | if (use_values) {
408 | for (unsigned i = 0;/*nothing*/; ++i) {
409 | internal::Arg::Type arg_type = args.type(i);
410 | switch (arg_type) {
411 | case internal::Arg::NONE:
412 | return;
413 | case internal::Arg::NAMED_ARG:
414 | named_arg = static_cast(args.values_[i].pointer);
415 | map_.push_back(Pair(named_arg->name, *named_arg));
416 | break;
417 | default:
418 | /*nothing*/;
419 | }
420 | }
421 | return;
422 | }
423 | for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
424 | internal::Arg::Type arg_type = args.type(i);
425 | if (arg_type == internal::Arg::NAMED_ARG) {
426 | named_arg = static_cast(args.args_[i].pointer);
427 | map_.push_back(Pair(named_arg->name, *named_arg));
428 | }
429 | }
430 | for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
431 | switch (args.args_[i].type) {
432 | case internal::Arg::NONE:
433 | return;
434 | case internal::Arg::NAMED_ARG:
435 | named_arg = static_cast(args.args_[i].pointer);
436 | map_.push_back(Pair(named_arg->name, *named_arg));
437 | break;
438 | default:
439 | /*nothing*/;
440 | }
441 | }
442 | }
443 |
444 | template
445 | void internal::FixedBuffer::grow(std::size_t) {
446 | FMT_THROW(std::runtime_error("buffer overflow"));
447 | }
448 |
449 | FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg(
450 | unsigned arg_index, const char *&error) {
451 | internal::Arg arg = args_[arg_index];
452 | switch (arg.type) {
453 | case internal::Arg::NONE:
454 | error = "argument index out of range";
455 | break;
456 | case internal::Arg::NAMED_ARG:
457 | arg = *static_cast(arg.pointer);
458 | break;
459 | default:
460 | /*nothing*/;
461 | }
462 | return arg;
463 | }
464 |
465 | FMT_FUNC void report_system_error(
466 | int error_code, fmt::StringRef message) FMT_NOEXCEPT {
467 | // 'fmt::' is for bcc32.
468 | report_error(format_system_error, error_code, message);
469 | }
470 |
471 | #if FMT_USE_WINDOWS_H
472 | FMT_FUNC void report_windows_error(
473 | int error_code, fmt::StringRef message) FMT_NOEXCEPT {
474 | // 'fmt::' is for bcc32.
475 | report_error(internal::format_windows_error, error_code, message);
476 | }
477 | #endif
478 |
479 | FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
480 | MemoryWriter w;
481 | w.write(format_str, args);
482 | std::fwrite(w.data(), 1, w.size(), f);
483 | }
484 |
485 | FMT_FUNC void print(CStringRef format_str, ArgList args) {
486 | print(stdout, format_str, args);
487 | }
488 |
489 | FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) {
490 | char escape[] = "\x1b[30m";
491 | escape[3] = static_cast('0' + c);
492 | std::fputs(escape, stdout);
493 | print(format, args);
494 | std::fputs(RESET_COLOR, stdout);
495 | }
496 |
497 | #ifndef FMT_HEADER_ONLY
498 |
499 | template struct internal::BasicData;
500 |
501 | // Explicit instantiations for char.
502 |
503 | template void internal::FixedBuffer::grow(std::size_t);
504 |
505 | template void internal::ArgMap::init(const ArgList &args);
506 |
507 | template FMT_API int internal::CharTraits::format_float(
508 | char *buffer, std::size_t size, const char *format,
509 | unsigned width, int precision, double value);
510 |
511 | template FMT_API int internal::CharTraits::format_float(
512 | char *buffer, std::size_t size, const char *format,
513 | unsigned width, int precision, long double value);
514 |
515 | // Explicit instantiations for wchar_t.
516 |
517 | template void internal::FixedBuffer::grow(std::size_t);
518 |
519 | template void internal::ArgMap::init(const ArgList &args);
520 |
521 | template FMT_API int internal::CharTraits::format_float(
522 | wchar_t *buffer, std::size_t size, const wchar_t *format,
523 | unsigned width, int precision, double value);
524 |
525 | template FMT_API int internal::CharTraits::format_float(
526 | wchar_t *buffer, std::size_t size, const wchar_t *format,
527 | unsigned width, int precision, long double value);
528 |
529 | #endif // FMT_HEADER_ONLY
530 |
531 | } // namespace fmt
532 |
533 | #ifdef _MSC_VER
534 | # pragma warning(pop)
535 | #endif
536 |
--------------------------------------------------------------------------------
/ext/gsl/gsl:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_GSL_H
20 | #define GSL_GSL_H
21 |
22 | #include // Ensures/Expects
23 | #include // finally()/narrow()/narrow_cast()...
24 | #include // multi_span, strided_span...
25 | #include // span
26 | #include // zstring, string_span, zstring_builder...
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | #if defined(_MSC_VER) && _MSC_VER < 1910
33 | #pragma push_macro("constexpr")
34 | #define constexpr /*constexpr*/
35 |
36 | #endif // defined(_MSC_VER) && _MSC_VER < 1910
37 |
38 | namespace gsl
39 | {
40 |
41 | //
42 | // GSL.owner: ownership pointers
43 | //
44 | using std::unique_ptr;
45 | using std::shared_ptr;
46 |
47 | //
48 | // owner
49 | //
50 | // owner is designed as a bridge for code that must deal directly with owning pointers for some reason
51 | //
52 | // T must be a pointer type
53 | // - disallow construction from any type other than pointer type
54 | //
55 | template ::value>>
56 | using owner = T;
57 |
58 | //
59 | // not_null
60 | //
61 | // Restricts a pointer or smart pointer to only hold non-null values.
62 | //
63 | // Has zero size overhead over T.
64 | //
65 | // If T is a pointer (i.e. T == U*) then
66 | // - allow construction from U*
67 | // - disallow construction from nullptr_t
68 | // - disallow default construction
69 | // - ensure construction from null U* fails
70 | // - allow implicit conversion to U*
71 | //
72 | template
73 | class not_null
74 | {
75 | public:
76 | static_assert(std::is_assignable::value, "T cannot be assigned nullptr.");
77 |
78 | template ::value>>
79 | constexpr not_null(U&& u) : ptr_(std::forward(u))
80 | {
81 | Expects(ptr_ != nullptr);
82 | }
83 |
84 | template ::value>>
85 | constexpr not_null(const not_null& other) : not_null(other.get())
86 | {
87 | }
88 |
89 | not_null(const not_null& other) = default;
90 | not_null& operator=(const not_null& other) = default;
91 |
92 | constexpr T get() const
93 | {
94 | Ensures(ptr_ != nullptr);
95 | return ptr_;
96 | }
97 |
98 | constexpr operator T() const { return get(); }
99 | constexpr T operator->() const { return get(); }
100 | constexpr decltype(auto) operator*() const { return *get(); }
101 |
102 | // prevents compilation when someone attempts to assign a null pointer constant
103 | not_null(std::nullptr_t) = delete;
104 | not_null& operator=(std::nullptr_t) = delete;
105 |
106 | // unwanted operators...pointers only point to single objects!
107 | not_null& operator++() = delete;
108 | not_null& operator--() = delete;
109 | not_null operator++(int) = delete;
110 | not_null operator--(int) = delete;
111 | not_null& operator+=(std::ptrdiff_t) = delete;
112 | not_null& operator-=(std::ptrdiff_t) = delete;
113 | void operator[](std::ptrdiff_t) const = delete;
114 |
115 | private:
116 | T ptr_;
117 | };
118 |
119 | template
120 | std::ostream& operator<<(std::ostream& os, const not_null& val)
121 | {
122 | os << val.get();
123 | return os;
124 | }
125 |
126 | template
127 | auto operator==(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() == rhs.get())
128 | {
129 | return lhs.get() == rhs.get();
130 | }
131 |
132 | template
133 | auto operator!=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() != rhs.get())
134 | {
135 | return lhs.get() != rhs.get();
136 | }
137 |
138 | template
139 | auto operator<(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() < rhs.get())
140 | {
141 | return lhs.get() < rhs.get();
142 | }
143 |
144 | template
145 | auto operator<=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() <= rhs.get())
146 | {
147 | return lhs.get() <= rhs.get();
148 | }
149 |
150 | template
151 | auto operator>(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() > rhs.get())
152 | {
153 | return lhs.get() > rhs.get();
154 | }
155 |
156 | template
157 | auto operator>=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() >= rhs.get())
158 | {
159 | return lhs.get() >= rhs.get();
160 | }
161 |
162 | // more unwanted operators
163 | template
164 | std::ptrdiff_t operator-(const not_null&, const not_null&) = delete;
165 | template
166 | not_null operator-(const not_null&, std::ptrdiff_t) = delete;
167 | template
168 | not_null operator+(const not_null&, std::ptrdiff_t) = delete;
169 | template
170 | not_null operator+(std::ptrdiff_t, const not_null&) = delete;
171 |
172 | } // namespace gsl
173 |
174 | namespace std
175 | {
176 | template
177 | struct hash>
178 | {
179 | std::size_t operator()(const gsl::not_null& value) const { return hash{}(value); }
180 | };
181 |
182 | } // namespace std
183 |
184 | #if defined(_MSC_VER) && _MSC_VER < 1910
185 | #undef constexpr
186 | #pragma pop_macro("constexpr")
187 |
188 | #endif // defined(_MSC_VER) && _MSC_VER < 1910
189 |
190 | #endif // GSL_GSL_H
191 |
--------------------------------------------------------------------------------
/ext/gsl/gsl_algorithm:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_ALGORITHM_H
20 | #define GSL_ALGORITHM_H
21 |
22 | #include
23 |
24 | #include
25 |
26 | #ifdef _MSC_VER
27 | #pragma warning(push)
28 |
29 | // turn off some warnings that are noisy about our Expects statements
30 | #pragma warning(disable : 4127) // conditional expression is constant
31 | #pragma warning(disable : 4996) // unsafe use of std::copy_n
32 |
33 | // blanket turn off warnings from CppCoreCheck for now
34 | // so people aren't annoyed by them when running the tool.
35 | // more targeted suppressions will be added in a future update to the GSL
36 | #pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
37 | #endif // _MSC_VER
38 |
39 | namespace gsl
40 | {
41 |
42 | template
44 | void copy(span src, span dest)
45 | {
46 | static_assert(std::is_assignable::value,
47 | "Elements of source span can not be assigned to elements of destination span");
48 | static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent ||
49 | (SrcExtent <= DestExtent),
50 | "Source range is longer than target range");
51 |
52 | Expects(dest.size() >= src.size());
53 | std::copy_n(src.data(), src.size(), dest.data());
54 | }
55 |
56 | } // namespace gsl
57 |
58 | #ifdef _MSC_VER
59 | #pragma warning(pop)
60 | #endif // _MSC_VER
61 |
62 | #endif // GSL_ALGORITHM_H
63 |
--------------------------------------------------------------------------------
/ext/gsl/gsl_assert:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_CONTRACTS_H
20 | #define GSL_CONTRACTS_H
21 |
22 | #include
23 | #include
24 |
25 | //
26 | // There are three configuration options for this GSL implementation's behavior
27 | // when pre/post conditions on the GSL types are violated:
28 | //
29 | // 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
30 | // 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
31 | // 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
32 | //
33 | #if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
34 | defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
35 | #define GSL_TERMINATE_ON_CONTRACT_VIOLATION
36 | #endif
37 |
38 | #define GSL_STRINGIFY_DETAIL(x) #x
39 | #define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
40 |
41 | #if defined(__clang__) || defined(__GNUC__)
42 | #define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
43 | #define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
44 | #else
45 | #define GSL_LIKELY(x) (!!(x))
46 | #define GSL_UNLIKELY(x) (!!(x))
47 | #endif
48 |
49 | //
50 | // GSL_ASSUME(cond)
51 | //
52 | // Tell the optimizer that the predicate cond must hold. It is unspecified
53 | // whether or not cond is actually evaluated.
54 | //
55 | #ifdef _MSC_VER
56 | #define GSL_ASSUME(cond) __assume(cond)
57 | #elif defined(__clang__)
58 | #define GSL_ASSUME(cond) __builtin_assume(cond)
59 | #elif defined(__GNUC__)
60 | #define GSL_ASSUME(cond) ((cond) ? static_cast(0) : __builtin_unreachable())
61 | #else
62 | #define GSL_ASSUME(cond) static_cast(!!(cond))
63 | #endif
64 |
65 | //
66 | // GSL.assert: assertions
67 | //
68 |
69 | namespace gsl
70 | {
71 | struct fail_fast : public std::logic_error
72 | {
73 | explicit fail_fast(char const* const message) : std::logic_error(message) {}
74 | };
75 | }
76 |
77 | #if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
78 |
79 | #define GSL_CONTRACT_CHECK(type, cond) \
80 | (GSL_LIKELY(cond) ? static_cast(0) \
81 | : throw gsl::fail_fast("GSL: " type " failure at " __FILE__ \
82 | ": " GSL_STRINGIFY(__LINE__)))
83 |
84 | #elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
85 |
86 | #define GSL_CONTRACT_CHECK(type, cond) (GSL_LIKELY(cond) ? static_cast(0) : std::terminate())
87 |
88 | #elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
89 |
90 | #define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
91 |
92 | #endif
93 |
94 | #define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
95 | #define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
96 |
97 | #endif // GSL_CONTRACTS_H
98 |
--------------------------------------------------------------------------------
/ext/gsl/gsl_byte:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_BYTE_H
20 | #define GSL_BYTE_H
21 |
22 | #include
23 |
24 | #ifdef _MSC_VER
25 |
26 | #pragma warning(push)
27 |
28 | // don't warn about function style casts in byte related operators
29 | #pragma warning(disable : 26493)
30 |
31 | #ifndef GSL_USE_STD_BYTE
32 | // this tests if we are under MSVC and the standard lib has std::byte and it is enabled
33 | #if _MSC_VER >= 1911 && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE)
34 |
35 | #define GSL_USE_STD_BYTE 1
36 |
37 | #else // _MSC_VER >= 1911 && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE)
38 |
39 | #define GSL_USE_STD_BYTE 0
40 |
41 | #endif // _MSC_VER >= 1911 && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE)
42 | #endif // GSL_USE_STD_BYTE
43 |
44 | #else // _MSC_VER
45 |
46 | #ifndef GSL_USE_STD_BYTE
47 | // this tests if we are under GCC or Clang with enough -std:c++1z power to get us std::byte
48 | #if defined(__cplusplus) && (__cplusplus >= 201703L)
49 |
50 | #define GSL_USE_STD_BYTE 1
51 | #include
52 |
53 | #else // defined(__cplusplus) && (__cplusplus >= 201703L)
54 |
55 | #define GSL_USE_STD_BYTE 0
56 |
57 | #endif //defined(__cplusplus) && (__cplusplus >= 201703L)
58 | #endif // GSL_USE_STD_BYTE
59 |
60 | #endif // _MSC_VER
61 |
62 | namespace gsl
63 | {
64 | #if GSL_USE_STD_BYTE
65 |
66 |
67 | using std::byte;
68 | using std::to_integer;
69 |
70 | #else // GSL_USE_STD_BYTE
71 |
72 | // This is a simple definition for now that allows
73 | // use of byte within span<> to be standards-compliant
74 | enum class byte : unsigned char
75 | {
76 | };
77 |
78 | template ::value>>
79 | inline constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
80 | {
81 | return b = byte(static_cast(b) << shift);
82 | }
83 |
84 | template ::value>>
85 | inline constexpr byte operator<<(byte b, IntegerType shift) noexcept
86 | {
87 | return byte(static_cast(b) << shift);
88 | }
89 |
90 | template ::value>>
91 | inline constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
92 | {
93 | return b = byte(static_cast(b) >> shift);
94 | }
95 |
96 | template ::value>>
97 | inline constexpr byte operator>>(byte b, IntegerType shift) noexcept
98 | {
99 | return byte(static_cast(b) >> shift);
100 | }
101 |
102 | inline constexpr byte& operator|=(byte& l, byte r) noexcept
103 | {
104 | return l = byte(static_cast(l) | static_cast(r));
105 | }
106 |
107 | inline constexpr byte operator|(byte l, byte r) noexcept
108 | {
109 | return byte(static_cast(l) | static_cast(r));
110 | }
111 |
112 | inline constexpr byte& operator&=(byte& l, byte r) noexcept
113 | {
114 | return l = byte(static_cast(l) & static_cast(r));
115 | }
116 |
117 | inline constexpr byte operator&(byte l, byte r) noexcept
118 | {
119 | return byte(static_cast(l) & static_cast(r));
120 | }
121 |
122 | inline constexpr byte& operator^=(byte& l, byte r) noexcept
123 | {
124 | return l = byte(static_cast(l) ^ static_cast(r));
125 | }
126 |
127 | inline constexpr byte operator^(byte l, byte r) noexcept
128 | {
129 | return byte(static_cast(l) ^ static_cast(r));
130 | }
131 |
132 | inline constexpr byte operator~(byte b) noexcept { return byte(~static_cast(b)); }
133 |
134 | template ::value>>
135 | inline constexpr IntegerType to_integer(byte b) noexcept
136 | {
137 | return static_cast(b);
138 | }
139 |
140 | #endif // GSL_USE_STD_BYTE
141 |
142 | template
143 | inline constexpr byte to_byte_impl(T t) noexcept
144 | {
145 | static_assert(
146 | E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
147 | "If you are calling to_byte with an integer contant use: gsl::to_byte() version.");
148 | return static_cast(t);
149 | }
150 | template <>
151 | inline constexpr byte to_byte_impl(unsigned char t) noexcept
152 | {
153 | return byte(t);
154 | }
155 |
156 | template
157 | inline constexpr byte to_byte(T t) noexcept
158 | {
159 | return to_byte_impl::value, T>(t);
160 | }
161 |
162 | template
163 | inline constexpr byte to_byte() noexcept
164 | {
165 | static_assert(I >= 0 && I <= 255,
166 | "gsl::byte only has 8 bits of storage, values must be in range 0-255");
167 | return static_cast(I);
168 | }
169 |
170 | } // namespace gsl
171 |
172 | #ifdef _MSC_VER
173 | #pragma warning(pop)
174 | #endif // _MSC_VER
175 |
176 | #endif // GSL_BYTE_H
177 |
--------------------------------------------------------------------------------
/ext/gsl/gsl_util:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_UTIL_H
20 | #define GSL_UTIL_H
21 |
22 | #include // Ensures/Expects
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #if defined(_MSC_VER)
30 |
31 | #pragma warning(push)
32 | #pragma warning(disable : 4127) // conditional expression is constant
33 |
34 | #if _MSC_VER < 1910
35 | #pragma push_macro("constexpr")
36 | #define constexpr /*constexpr*/
37 | #endif // _MSC_VER < 1910
38 | #endif // _MSC_VER
39 |
40 | namespace gsl
41 | {
42 | //
43 | // GSL.util: utilities
44 | //
45 |
46 | // final_act allows you to ensure something gets run at the end of a scope
47 | template
48 | class final_act
49 | {
50 | public:
51 | explicit final_act(F f) noexcept : f_(std::move(f)), invoke_(true) {}
52 |
53 | final_act(final_act&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
54 | {
55 | other.invoke_ = false;
56 | }
57 |
58 | final_act(const final_act&) = delete;
59 | final_act& operator=(const final_act&) = delete;
60 |
61 | ~final_act() noexcept
62 | {
63 | if (invoke_) f_();
64 | }
65 |
66 | private:
67 | F f_;
68 | bool invoke_;
69 | };
70 |
71 | // finally() - convenience function to generate a final_act
72 | template
73 | inline final_act finally(const F& f) noexcept
74 | {
75 | return final_act(f);
76 | }
77 |
78 | template
79 | inline final_act finally(F&& f) noexcept
80 | {
81 | return final_act(std::forward(f));
82 | }
83 |
84 | // narrow_cast(): a searchable way to do narrowing casts of values
85 | template
86 | inline constexpr T narrow_cast(U&& u) noexcept
87 | {
88 | return static_cast(std::forward(u));
89 | }
90 |
91 | struct narrowing_error : public std::exception
92 | {
93 | };
94 |
95 | namespace details
96 | {
97 | template
98 | struct is_same_signedness
99 | : public std::integral_constant::value == std::is_signed::value>
100 | {
101 | };
102 | }
103 |
104 | // narrow() : a checked version of narrow_cast() that throws if the cast changed the value
105 | template
106 | inline T narrow(U u)
107 | {
108 | T t = narrow_cast(u);
109 | if (static_cast(t) != u) throw narrowing_error();
110 | if (!details::is_same_signedness::value && ((t < T{}) != (u < U{})))
111 | throw narrowing_error();
112 | return t;
113 | }
114 |
115 | //
116 | // at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
117 | //
118 | template
119 | inline constexpr T& at(T (&arr)[N], const std::ptrdiff_t index)
120 | {
121 | Expects(index >= 0 && index < narrow_cast(N));
122 | return arr[static_cast(index)];
123 | }
124 |
125 | template
126 | inline constexpr auto at(Cont& cont, const std::ptrdiff_t index) -> decltype(cont[cont.size()])
127 | {
128 | Expects(index >= 0 && index < narrow_cast(cont.size()));
129 | using size_type = decltype(cont.size());
130 | return cont[static_cast(index)];
131 | }
132 |
133 | template
134 | inline constexpr T at(const std::initializer_list cont, const std::ptrdiff_t index)
135 | {
136 | Expects(index >= 0 && index < narrow_cast(cont.size()));
137 | return *(cont.begin() + index);
138 | }
139 |
140 | } // namespace gsl
141 |
142 | #if defined(_MSC_VER)
143 | #if _MSC_VER < 1910
144 | #undef constexpr
145 | #pragma pop_macro("constexpr")
146 |
147 | #endif // _MSC_VER < 1910
148 |
149 | #pragma warning(pop)
150 |
151 | #endif // _MSC_VER
152 |
153 | #endif // GSL_UTIL_H
154 |
--------------------------------------------------------------------------------
/ext/gsl/span:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 | //
5 | // This code is licensed under the MIT License (MIT).
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 | // THE SOFTWARE.
14 | //
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | #pragma once
18 |
19 | #ifndef GSL_SPAN_H
20 | #define GSL_SPAN_H
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #ifdef _MSC_VER
35 | #pragma warning(push)
36 |
37 | // turn off some warnings that are noisy about our Expects statements
38 | #pragma warning(disable : 4127) // conditional expression is constant
39 | #pragma warning(disable : 4702) // unreachable code
40 |
41 | // blanket turn off warnings from CppCoreCheck for now
42 | // so people aren't annoyed by them when running the tool.
43 | // more targeted suppressions will be added in a future update to the GSL
44 | #pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
45 |
46 | #if _MSC_VER < 1910
47 | #pragma push_macro("constexpr")
48 | #define constexpr /*constexpr*/
49 |
50 | #endif // _MSC_VER < 1910
51 | #endif // _MSC_VER
52 |
53 | #ifdef GSL_THROW_ON_CONTRACT_VIOLATION
54 | #define GSL_NOEXCEPT /*noexcept*/
55 | #else
56 | #define GSL_NOEXCEPT noexcept
57 | #endif // GSL_THROW_ON_CONTRACT_VIOLATION
58 |
59 | namespace gsl
60 | {
61 |
62 | // [views.constants], constants
63 | constexpr const std::ptrdiff_t dynamic_extent = -1;
64 |
65 | template
66 | class span;
67 |
68 | // implementation details
69 | namespace details
70 | {
71 | template
72 | struct is_span_oracle : std::false_type
73 | {
74 | };
75 |
76 | template
77 | struct is_span_oracle> : std::true_type
78 | {
79 | };
80 |
81 | template
82 | struct is_span : public is_span_oracle>
83 | {
84 | };
85 |
86 | template
87 | struct is_std_array_oracle : std::false_type
88 | {
89 | };
90 |
91 | template
92 | struct is_std_array_oracle> : std::true_type
93 | {
94 | };
95 |
96 | template
97 | struct is_std_array : public is_std_array_oracle>
98 | {
99 | };
100 |
101 | template
102 | struct is_allowed_extent_conversion
103 | : public std::integral_constant
105 | {
106 | };
107 |
108 | template
109 | struct is_allowed_element_type_conversion
110 | : public std::integral_constant::value>
111 | {
112 | };
113 |
114 | template
115 | class span_iterator
116 | {
117 | using element_type_ = typename Span::element_type;
118 |
119 | public:
120 | using iterator_category = std::random_access_iterator_tag;
121 | using value_type = std::remove_cv_t;
122 | using difference_type = typename Span::index_type;
123 |
124 | using reference = std::conditional_t&;
125 | using pointer = std::add_pointer_t;
126 |
127 | span_iterator() = default;
128 |
129 | constexpr span_iterator(const Span* span, typename Span::index_type index) GSL_NOEXCEPT
130 | : span_(span), index_(index)
131 | {
132 | Expects(span == nullptr || (0 <= index_ && index <= span_->length()));
133 | }
134 |
135 | friend span_iterator;
136 | template* = nullptr>
137 | constexpr span_iterator(const span_iterator& other) GSL_NOEXCEPT
138 | : span_iterator(other.span_, other.index_)
139 | {
140 | }
141 |
142 | constexpr reference operator*() const GSL_NOEXCEPT
143 | {
144 | Expects(index_ != span_->length());
145 | return *(span_->data() + index_);
146 | }
147 |
148 | constexpr pointer operator->() const GSL_NOEXCEPT
149 | {
150 | Expects(index_ != span_->length());
151 | return span_->data() + index_;
152 | }
153 |
154 | constexpr span_iterator& operator++() GSL_NOEXCEPT
155 | {
156 | Expects(0 <= index_ && index_ != span_->length());
157 | ++index_;
158 | return *this;
159 | }
160 |
161 | constexpr span_iterator operator++(int) GSL_NOEXCEPT
162 | {
163 | auto ret = *this;
164 | ++(*this);
165 | return ret;
166 | }
167 |
168 | constexpr span_iterator& operator--() GSL_NOEXCEPT
169 | {
170 | Expects(index_ != 0 && index_ <= span_->length());
171 | --index_;
172 | return *this;
173 | }
174 |
175 | constexpr span_iterator operator--(int) GSL_NOEXCEPT
176 | {
177 | auto ret = *this;
178 | --(*this);
179 | return ret;
180 | }
181 |
182 | constexpr span_iterator operator+(difference_type n) const GSL_NOEXCEPT
183 | {
184 | auto ret = *this;
185 | return ret += n;
186 | }
187 |
188 | constexpr span_iterator& operator+=(difference_type n) GSL_NOEXCEPT
189 | {
190 | Expects((index_ + n) >= 0 && (index_ + n) <= span_->length());
191 | index_ += n;
192 | return *this;
193 | }
194 |
195 | constexpr span_iterator operator-(difference_type n) const GSL_NOEXCEPT
196 | {
197 | auto ret = *this;
198 | return ret -= n;
199 | }
200 |
201 | constexpr span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
202 |
203 | constexpr difference_type operator-(const span_iterator& rhs) const GSL_NOEXCEPT
204 | {
205 | Expects(span_ == rhs.span_);
206 | return index_ - rhs.index_;
207 | }
208 |
209 | constexpr reference operator[](difference_type n) const GSL_NOEXCEPT
210 | {
211 | return *(*this + n);
212 | }
213 |
214 | constexpr friend bool operator==(const span_iterator& lhs,
215 | const span_iterator& rhs) GSL_NOEXCEPT
216 | {
217 | return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
218 | }
219 |
220 | constexpr friend bool operator!=(const span_iterator& lhs,
221 | const span_iterator& rhs) GSL_NOEXCEPT
222 | {
223 | return !(lhs == rhs);
224 | }
225 |
226 | constexpr friend bool operator<(const span_iterator& lhs,
227 | const span_iterator& rhs) GSL_NOEXCEPT
228 | {
229 | Expects(lhs.span_ == rhs.span_);
230 | return lhs.index_ < rhs.index_;
231 | }
232 |
233 | constexpr friend bool operator<=(const span_iterator& lhs,
234 | const span_iterator& rhs) GSL_NOEXCEPT
235 | {
236 | return !(rhs < lhs);
237 | }
238 |
239 | constexpr friend bool operator>(const span_iterator& lhs,
240 | const span_iterator& rhs) GSL_NOEXCEPT
241 | {
242 | return rhs < lhs;
243 | }
244 |
245 | constexpr friend bool operator>=(const span_iterator& lhs,
246 | const span_iterator& rhs) GSL_NOEXCEPT
247 | {
248 | return !(rhs > lhs);
249 | }
250 |
251 | protected:
252 | const Span* span_ = nullptr;
253 | std::ptrdiff_t index_ = 0;
254 | };
255 |
256 | template
257 | inline constexpr span_iterator
258 | operator+(typename span_iterator::difference_type n,
259 | const span_iterator& rhs) GSL_NOEXCEPT
260 | {
261 | return rhs + n;
262 | }
263 |
264 | template
265 | inline constexpr span_iterator
266 | operator-(typename span_iterator::difference_type n,
267 | const span_iterator& rhs) GSL_NOEXCEPT
268 | {
269 | return rhs - n;
270 | }
271 |
272 | template
273 | class extent_type
274 | {
275 | public:
276 | using index_type = std::ptrdiff_t;
277 |
278 | static_assert(Ext >= 0, "A fixed-size span must be >= 0 in size.");
279 |
280 | constexpr extent_type() GSL_NOEXCEPT {}
281 |
282 | template
283 | constexpr extent_type(extent_type ext)
284 | {
285 | static_assert(Other == Ext || Other == dynamic_extent,
286 | "Mismatch between fixed-size extent and size of initializing data.");
287 | Expects(ext.size() == Ext);
288 | }
289 |
290 | constexpr extent_type(index_type size) { Expects(size == Ext); }
291 |
292 | constexpr index_type size() const GSL_NOEXCEPT { return Ext; }
293 | };
294 |
295 | template <>
296 | class extent_type
297 | {
298 | public:
299 | using index_type = std::ptrdiff_t;
300 |
301 | template
302 | explicit constexpr extent_type(extent_type ext) : size_(ext.size())
303 | {
304 | }
305 |
306 | explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); }
307 |
308 | constexpr index_type size() const GSL_NOEXCEPT { return size_; }
309 |
310 | private:
311 | index_type size_;
312 | };
313 | } // namespace details
314 |
315 | // [span], class template span
316 | template
317 | class span
318 | {
319 | public:
320 | // constants and types
321 | using element_type = ElementType;
322 | using value_type = std::remove_cv_t;
323 | using index_type = std::ptrdiff_t;
324 | using pointer = element_type*;
325 | using reference = element_type&;
326 |
327 | using iterator = details::span_iterator, false>;
328 | using const_iterator = details::span_iterator, true>;
329 | using reverse_iterator = std::reverse_iterator;
330 | using const_reverse_iterator = std::reverse_iterator;
331 |
332 | using size_type = index_type;
333 |
334 | constexpr static const index_type extent = Extent;
335 |
336 | // [span.cons], span constructors, copy, assignment, and destructor
337 | template " SFINAE,
339 | // since "std::enable_if_t" is ill-formed when Extent is greater than 0.
340 | class = std::enable_if_t<(Dependent || Extent <= 0)>>
341 | constexpr span() GSL_NOEXCEPT : storage_(nullptr, details::extent_type<0>())
342 | {
343 | }
344 |
345 | constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
346 |
347 | constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
348 |
349 | constexpr span(pointer firstElem, pointer lastElem)
350 | : storage_(firstElem, std::distance(firstElem, lastElem))
351 | {
352 | }
353 |
354 | template
355 | constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT
356 | : storage_(&arr[0], details::extent_type())
357 | {
358 | }
359 |
360 | template >
361 | constexpr span(std::array& arr) GSL_NOEXCEPT
362 | : storage_(&arr[0], details::extent_type())
363 | {
364 | }
365 |
366 | template
367 | constexpr span(const std::array, N>& arr) GSL_NOEXCEPT
368 | : storage_(&arr[0], details::extent_type())
369 | {
370 | }
371 |
372 | template >
373 | constexpr span(const std::unique_ptr& ptr, index_type count)
374 | : storage_(ptr.get(), count)
375 | {
376 | }
377 |
378 | constexpr span(const std::unique_ptr& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0)
379 | {
380 | }
381 | constexpr span(const std::shared_ptr& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0)
382 | {
383 | }
384 |
385 | // NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
386 | // on Container to be a contiguous sequence container.
387 | template ::value && !details::is_std_array::value &&
390 | std::is_convertible::value &&
391 | std::is_convertible().data())>::value>>
393 | constexpr span(Container& cont) : span(cont.data(), narrow(cont.size()))
394 | {
395 | }
396 |
397 | template ::value && !details::is_span::value &&
400 | std::is_convertible::value &&
401 | std::is_convertible().data())>::value>>
403 | constexpr span(const Container& cont) : span(cont.data(), narrow(cont.size()))
404 | {
405 | }
406 |
407 | constexpr span(const span& other) GSL_NOEXCEPT = default;
408 | constexpr span(span&& other) GSL_NOEXCEPT = default;
409 |
410 | template <
411 | class OtherElementType, std::ptrdiff_t OtherExtent,
412 | class = std::enable_if_t<
413 | details::is_allowed_extent_conversion