jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
basic_types.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020-2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef JAU_BASIC_TYPES_HPP_
26#define JAU_BASIC_TYPES_HPP_
27
28#include <cstring>
29#include <ios>
30#include <stdexcept>
31#include <string>
32#include <cstdint>
33#include <iostream>
34#include <system_error>
35#include <thread>
36#include <condition_variable>
37
38#include <jau/cpp_lang_util.hpp>
41
42#include <jau/int_types.hpp>
43#include <jau/int_math.hpp>
44
45#include <jau/byte_util.hpp>
46#include <jau/string_util.hpp>
47
49#include <jau/fraction_type.hpp>
50
51namespace jau {
52
53 /**
54 * \ingroup Fractions
55 *
56 * Returns current monotonic time since Unix Epoch `00:00:00 UTC on 1970-01-01`.
57 *
58 * Returned fraction_timespec is passing machine precision and range of the underlying API.
59 *
60 * See fraction_timespec::to_fraction_i64() of how to measure duration in high range and precision:
61 * <pre>
62 * fraction_timespec t0 = getMonotonicTime();
63 * // do something
64 *
65 * // Exact duration
66 * fraction_timespec td_1 = getMonotonicTime() - t0;
67 *
68 * // or for durations <= 292 years
69 * fraction_i64 td_2 = (getMonotonicTime() - t0).to_fraction_i64();
70 * </pre>
71 *
72 * This is in stark contract to counting nanoseconds in int64_t which only lasts until `2262-04-12`,
73 * since INT64_MAX is 9'223'372'036'854'775'807 for 9'223'372'036 seconds or 292 years.
74 *
75 * Monotonic time shall be used for high-performance measurements of durations,
76 * since the underlying OS shall support fast calls.
77 *
78 * @see fraction_timespec
79 * @see fraction_timespec::to_fraction_i64()
80 * @see getWallClockTime()
81 */
83
84 /**
85 * \ingroup Fractions
86 *
87 * Returns current wall-clock real-time since Unix Epoch `00:00:00 UTC on 1970-01-01`.
88 *
89 * Returned fraction_timespec is passing machine precision and range of the underlying API.
90 *
91 * Wall-Clock time shall be used for accurate measurements of the actual time only,
92 * since the underlying OS unlikely supports fast calls.
93 *
94 * @see fraction_timespec
95 * @see fraction_timespec::to_fraction_i64()
96 * @see getMonotonicTime()
97 */
99
100 /**
101 * Returns current monotonic time in milliseconds.
102 */
103 uint64_t getCurrentMilliseconds() noexcept;
104
105 /**
106 * Returns current wall-clock system `time of day` in seconds since Unix Epoch
107 * `00:00:00 UTC on 1 January 1970`.
108 */
109 uint64_t getWallClockSeconds() noexcept;
110
111 /**
112 * millisecond sleep using high precision monotonic timer,
113 * useful for one-shot delays (only).
114 *
115 * Consider using jau::sleep_until or jau::sleep_for
116 * utilizing absolute target time sleep when waiting
117 * for an event, overcoming clock re-adjustments.
118 *
119 * @param td_ms duration to sleep in milliseconds
120 * @param ignore_irq continue sleep when interrupted by a signal if true, defaults to true
121 * @return true if completed waiting, otherwise false for interruption or error
122 */
123 bool milli_sleep(uint64_t td_ms, const bool ignore_irq=true) noexcept;
124
125 /**
126 * sleep using high precision monotonic timer,
127 * useful for one-shot delays (only).
128 *
129 * Consider using jau::sleep_until or jau::sleep_for
130 * utilizing absolute target time sleep when waiting
131 * for an event, overcoming clock re-adjustments.
132 *
133 * @param relative_time an object of type fraction_timespec representing the time to sleep
134 * @param ignore_irq continue sleep when interrupted by a signal if true, defaults to true
135 * @return true if completed waiting, otherwise false for interruption or error
136 */
137 bool sleep(const fraction_timespec& relative_time, const bool ignore_irq=true) noexcept;
138
139 /**
140 * sleep_until causes the current thread to block until the specific time is reached.
141 *
142 * Method works similar to std::this_thread::sleep_until(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
143 * for maintaining high-precision and infinite range.
144 *
145 * Implementation also uses ::clock_nanosleep(), with absolute time and either
146 * monotonic- or wall-clok time depending on given monotonic flag.
147 * This instead of ::nanosleep() with undefined clock-type and interruptions.
148 *
149 * @param absolute_time an object of type fraction_timespec representing the time when to stop waiting
150 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
151 * @param ignore_irq continue sleep when interrupted by a signal if true, defaults to true
152 * @return true if completed waiting, otherwise false for interruption or error
153 * @see sleep_until()
154 * @see sleep_for()
155 * @see wait_until()
156 * @see wait_for()
157 */
158 bool sleep_until(const fraction_timespec& absolute_time, const bool monotonic=true, const bool ignore_irq=true) noexcept;
159
160 /**
161 * sleep_for causes the current thread to block until a specific amount of time has passed.
162 *
163 * Implementation calls sleep_until() passing absolute time derived via getMonotonicTime() or getWallClockTime(), see:
164 * <pre>
165 * fraction_timespec absolute_time = ( monotonic ? getMonotonicTime() : getWallClockTime() ) + relative_time;
166 * </pre>
167 *
168 * Method works similar to std::this_thread::sleep_until(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
169 * for maintaining high-precision and infinite range.
170 *
171 * @param relative_time an object of type fraction_timespec representing the the maximum time to spend waiting
172 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
173 * @param ignore_irq continue sleep when interrupted by a signal if true, defaults to true
174 * @return true if completed waiting, otherwise false for interruption or error
175 * @see sleep_until()
176 * @see sleep_for()
177 * @see wait_until()
178 * @see wait_for()
179 */
180 bool sleep_for(const fraction_timespec& relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept;
181
182 /**
183 * sleep_for causes the current thread to block until a specific amount of time has passed.
184 *
185 * Implementation calls sleep_until() passing absolute time derived via getMonotonicTime() or getWallClockTime(), see:
186 * <pre>
187 * fraction_timespec absolute_time = ( monotonic ? getMonotonicTime() : getWallClockTime() ) + relative_time;
188 * </pre>
189 *
190 * Method works similar to std::this_thread::sleep_until(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
191 * for maintaining high-precision and infinite range.
192 *
193 * @param relative_time an object of type fraction_i64 representing the the maximum time to spend waiting, which is limited to 292 years if using nanoseconds fractions.
194 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
195 * @param ignore_irq continue sleep when interrupted by a signal if true, defaults to true
196 * @return true if completed waiting, otherwise false for interruption or error
197 * @see sleep_until()
198 * @see sleep_for()
199 * @see wait_until()
200 * @see wait_for()
201 */
202 bool sleep_for(const fraction_i64& relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept;
203
204 /**
205 * wait_until causes the current thread to block until the condition variable is notified, a specific time is reached, or a spurious wakeup occurs.
206 *
207 * Method works similar to std::condition_variable::wait_until(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
208 * for maintaining high-precision and infinite range.
209 *
210 * @param cv std::condition_variable instance
211 * @param lock an object of type std::unique_lock<std::mutex>, which must be locked by the current thread
212 * @param absolute_time an object of type fraction_timespec representing the time when to stop waiting
213 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
214 * @return std::cv_status::timeout if the relative timeout specified by rel_time expired, std::cv_status::no_timeout otherwise.
215 * @see sleep_until()
216 * @see sleep_for()
217 * @see wait_until()
218 * @see wait_for()
219 */
220 std::cv_status wait_until(std::condition_variable& cv, std::unique_lock<std::mutex>& lock, const fraction_timespec& absolute_time,
221 const bool monotonic=true) noexcept;
222
223 /**
224 * wait_for causes the current thread to block until the condition variable is notified, a specific amount of time has passed, or a spurious wakeup occurs.
225 *
226 * Implementation calls wait_until() passing absolute time derived via getMonotonicTime() or getWallClockTime(), see:
227 * <pre>
228 * fraction_timespec absolute_time = ( monotonic ? getMonotonicTime() : getWallClockTime() ) + relative_time;
229 * </pre>
230 *
231 * Method works similar to std::condition_variable::wait_for(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
232 * for maintaining high-precision and infinite range.
233 *
234 * When using a condition predicate loop to ensure no spurious wake-up preemptively ends waiting for the condition variable event or timeout,
235 * it is always recommended to use wait_until() using the absolute timeout time computed once before said loop. Example from latch::wait_for():
236 * <pre>
237 std::unique_lock<std::mutex> lock(mtx_cd);
238 const fraction_timespec timeout_time = getMonotonicTime() + timeout_duration;
239 while( 0 < count ) {
240 std::cv_status s = wait_until(cv, lock, timeout_time);
241 if( 0 == count ) {
242 return true;
243 }
244 if( std::cv_status::timeout == s ) {
245 return false;
246 }
247 }
248 * </pre>
249 * @param cv std::condition_variable instance
250 * @param lock an object of type std::unique_lock<std::mutex>, which must be locked by the current thread
251 * @param relative_time an object of type fraction_timespec representing the the maximum time to spend waiting
252 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
253 * @return std::cv_status::timeout if the relative timeout specified by rel_time expired, std::cv_status::no_timeout otherwise.
254 * @see sleep_until()
255 * @see sleep_for()
256 * @see wait_until()
257 * @see wait_for()
258 */
259 std::cv_status wait_for(std::condition_variable& cv, std::unique_lock<std::mutex>& lock, const fraction_timespec& relative_time,
260 const bool monotonic=true) noexcept;
261
262 /**
263 * wait_for causes the current thread to block until the condition variable is notified, a specific amount of time has passed, or a spurious wakeup occurs.
264 *
265 * Implementation calls wait_until() passing absolute time derived via getMonotonicTime() or getWallClockTime(), see:
266 * <pre>
267 * fraction_timespec absolute_time = ( monotonic ? getMonotonicTime() : getWallClockTime() ) + relative_time;
268 * </pre>
269 *
270 * Method works similar to std::condition_variable::wait_for(), but utilizes fraction_timespec instead of `int64_t nanoseconds counter`
271 * for maintaining high-precision and infinite range.
272 *
273 * When using a condition predicate loop to ensure no spurious wake-up preemptively ends waiting for the condition variable event or timeout,
274 * it is always recommended to use wait_until() using the absolute timeout time computed once before said loop. Example from latch::wait_for():
275 * <pre>
276 std::unique_lock<std::mutex> lock(mtx_cd);
277 const fraction_timespec timeout_time = getMonotonicTime() + timeout_duration;
278 while( 0 < count ) {
279 std::cv_status s = wait_until(cv, lock, timeout_time);
280 if( 0 == count ) {
281 return true;
282 }
283 if( std::cv_status::timeout == s ) {
284 return false;
285 }
286 }
287 * </pre>
288 * @param cv std::condition_variable instance
289 * @param lock an object of type std::unique_lock<std::mutex>, which must be locked by the current thread
290 * @param relative_time an object of type fraction_i64 representing the the maximum time to spend waiting, which is limited to 292 years if using nanoseconds fractions.
291 * @param monotonic if true, implementation uses the fast and steady monotonic clock (default), otherwise the wall-clock
292 * @return std::cv_status::timeout if the relative timeout specified by rel_time expired, std::cv_status::no_timeout otherwise.
293 * @see sleep_until()
294 * @see sleep_for()
295 * @see wait_until()
296 * @see wait_for()
297 */
298 std::cv_status wait_for(std::condition_variable& cv, std::unique_lock<std::mutex>& lock, const fraction_i64& relative_time,
299 const bool monotonic=true) noexcept;
300
301 std::string threadName(const std::thread::id id) noexcept;
302
303 /**
304 // *************************************************
305 // *************************************************
306 // *************************************************
307 */
308
309 #define E_FILE_LINE __FILE__,__LINE__
310
312 private:
313 // brief message
314 std::string msg_;
315 // optional whole backtrace
316 std::string backtrace_;
317 // brief message + optional whole backtrace
318 std::string what_;
319
320 protected:
321 ExceptionBase(std::string &&type, std::string const& m, const char* file, int line) noexcept;
322
323 public:
324 virtual ~ExceptionBase() noexcept = default;
325 ExceptionBase(const ExceptionBase &o) noexcept = default;
326 ExceptionBase(ExceptionBase &&o) noexcept = default;
327 ExceptionBase& operator=(const ExceptionBase &o) noexcept = default;
328 ExceptionBase& operator=(ExceptionBase &&o) noexcept = default;
329
330 /** Returns brief message. */
331 const std::string& brief_message() const noexcept { return msg_; }
332 /** Returns optional whole backtrace. */
333 const std::string& backtrace() const noexcept { return backtrace_; }
334 /** Returns brief message and optional whole backtrace, i.e. std::exception::what() string. */
335 const std::string& whole_message() const noexcept { return what_; }
336
337 /** Allow conversion to `const std::string&` using brief_message(), as required by Catch2's `REQUIRE_THROWS_MATCHES` */
338 operator const std::string& () const noexcept { return brief_message(); };
339
340 std::ostream& operator<<(std::ostream& out) noexcept {
341 return out << what_;
342 }
343
344 virtual const char* what() const noexcept {
345 return whole_message().c_str();
346 }
347 };
349 protected:
350 RuntimeExceptionBase(std::string &&type, std::string const& m, const char* file, int line) noexcept
351 : ExceptionBase(std::move(type), m, file, line) {}
352
353 public:
354 ~RuntimeExceptionBase() noexcept override = default;
355
356 RuntimeExceptionBase(const RuntimeExceptionBase& o) noexcept = default;
358 RuntimeExceptionBase& operator=(const RuntimeExceptionBase& o) noexcept = default;
359 RuntimeExceptionBase& operator=(RuntimeExceptionBase&& o) noexcept = default;
360 };
362 protected:
363 LogicErrorBase(std::string &&type, std::string const& m, const char* file, int line) noexcept
364 : ExceptionBase(std::move(type), m, file, line) {}
365
366 public:
367 ~LogicErrorBase() noexcept override = default;
368
369 LogicErrorBase(const LogicErrorBase& o) noexcept = default;
370 LogicErrorBase(LogicErrorBase&& o) noexcept = default;
371 LogicErrorBase& operator=(const LogicErrorBase& o) noexcept = default;
372 LogicErrorBase& operator=(LogicErrorBase&& o) noexcept = default;
373 };
375 protected:
376 std::error_code m_ec;
377 RuntimeSystemExceptionBase(std::string &&type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
378 : RuntimeExceptionBase(std::move(type), m, file, line), m_ec(ec) {}
379
380 public:
381 ~RuntimeSystemExceptionBase() noexcept override = default;
382
385 RuntimeSystemExceptionBase& operator=(const RuntimeSystemExceptionBase& o) noexcept = default;
386 RuntimeSystemExceptionBase& operator=(RuntimeSystemExceptionBase&& o) noexcept = default;
387
388 const std::error_code& code() const noexcept { return m_ec; }
389 };
390
391 class OutOfMemoryError : public ExceptionBase, public std::bad_alloc {
392 public:
393 OutOfMemoryError(std::string const& m, const char* file, int line)
394 : ExceptionBase("OutOfMemoryError", m, file, line), bad_alloc() {}
395
396 const char* what() const noexcept override {
397 return whole_message().c_str();
398 }
399 };
400
401 class RuntimeException : public RuntimeExceptionBase, public std::runtime_error {
402 protected:
403 RuntimeException(std::string &&type, std::string const& m, const char* file, int line) noexcept
404 : RuntimeExceptionBase(std::move(type), m, file, line), runtime_error(whole_message()) {}
405
406 public:
407 RuntimeException(std::string const& m, const char* file, int line) noexcept
408 : RuntimeException("RuntimeException", m, file, line) {}
409
410 ~RuntimeException() noexcept override = default;
411
412 RuntimeException(const RuntimeException& o) noexcept = default;
413 RuntimeException(RuntimeException&& o) noexcept = default;
414 RuntimeException& operator=(const RuntimeException& o) noexcept = default;
415 RuntimeException& operator=(RuntimeException&& o) noexcept = default;
416
417 // base class std::exception:
418 const char* what() const noexcept override {
419 return whole_message().c_str();
420 }
421 };
422 class LogicError : public LogicErrorBase, public std::logic_error {
423 protected:
424 LogicError(std::string &&type, std::string const& m, const char* file, int line) noexcept
425 : LogicErrorBase(std::move(type), m, file, line), logic_error(whole_message()) {}
426
427 public:
428 LogicError(std::string const& m, const char* file, int line) noexcept
429 : LogicError("LogicErrorStd", m, file, line) {}
430
431 ~LogicError() noexcept override = default;
432
433 LogicError(const LogicError& o) noexcept = default;
434 LogicError(LogicError&& o) noexcept = default;
435 LogicError& operator=(const LogicError& o) noexcept = default;
436 LogicError& operator=(LogicError&& o) noexcept = default;
437
438 const char* what() const noexcept override {
439 return whole_message().c_str();
440 }
441 };
442 class RuntimeSystemException : public RuntimeSystemExceptionBase, public std::system_error {
443 protected:
444 RuntimeSystemException(std::string &&type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
445 : RuntimeSystemExceptionBase(std::move(type), ec, m, file, line), system_error(ec, whole_message()) {}
446
447 public:
448 RuntimeSystemException(const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
449 : RuntimeSystemException("RuntimeSystemExceptionStd", ec, m, file, line) {}
450
451 ~RuntimeSystemException() noexcept override = default;
452
453 RuntimeSystemException(const RuntimeSystemException& o) noexcept = default;
455 RuntimeSystemException& operator=(const RuntimeSystemException& o) noexcept = default;
456 RuntimeSystemException& operator=(RuntimeSystemException&& o) noexcept = default;
457
458 const char* what() const noexcept override {
459 return whole_message().c_str();
460 }
461 };
462
463 class IndexOutOfBoundsError : public LogicErrorBase, public std::out_of_range {
464 protected:
465 IndexOutOfBoundsError(const char* file, int line, std::string &&type, std::string const& m) noexcept
466 : LogicErrorBase(std::move(type), m, file, line), out_of_range(whole_message()) {}
467
468 public:
469 IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char* file, int line) noexcept
470 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+std::to_string(index)+", data length "+std::to_string(length)) {}
471
472 IndexOutOfBoundsError(const std::string& msg, const std::size_t index, const std::size_t length, const char* file, int line) noexcept
473 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", msg+": index "+std::to_string(index)+", data length "+std::to_string(length)) {}
474
475 IndexOutOfBoundsError(const std::string& index_s, const std::string& length_s, const char* file, int line) noexcept
476 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+index_s+", data length "+length_s) {}
477
478 IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char* file, int line) noexcept
479 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+std::to_string(index)+", count "+std::to_string(count)+", data length "+std::to_string(length)) {}
480
481 const char* what() const noexcept override {
482 return whole_message().c_str();
483 }
484 };
485
486 class IllegalArgumentError : public LogicErrorBase, public std::invalid_argument {
487 protected:
488 IllegalArgumentError(std::string &&type, std::string const& m, const char* file, int line) noexcept
489 : LogicErrorBase(std::move(type), m, file, line), invalid_argument(whole_message()) {}
490
491 public:
492 IllegalArgumentError(std::string const& m, const char* file, int line) noexcept
493 : IllegalArgumentError("IllegalArgumentError", m, file, line) {}
494
495 const char* what() const noexcept override {
496 return whole_message().c_str();
497 }
498 };
499
500 class IllegalStateError : public LogicErrorBase, public std::domain_error {
501 protected:
502 IllegalStateError(std::string &&type, std::string const& m, const char* file, int line) noexcept
503 : LogicErrorBase(std::move(type), m, file, line), domain_error(whole_message()) {}
504
505 public:
506 IllegalStateError(std::string const& m, const char* file, int line) noexcept
507 : IllegalStateError("IllegalStateError", m, file, line) {}
508
509 const char* what() const noexcept override {
510 return whole_message().c_str();
511 }
512 };
513
514 class IOError : public RuntimeSystemExceptionBase, public std::ios_base::failure {
515 public:
516 IOError(std::string const& m, const char* file, int line, const std::error_code& ec = std::io_errc::stream) noexcept
517 : RuntimeSystemExceptionBase("IOError", ec, m, file, line), failure(whole_message(), ec) {}
518
519 const char* what() const noexcept override {
520 return whole_message().c_str();
521 }
522 };
523
525 public:
526 InternalError(std::string const& m, const char* file, int line) noexcept
527 : RuntimeException("InternalError", m, file, line) {}
528 };
529
531 public:
532 NotImplementedException(std::string const& m, const char* file, int line) noexcept
533 : RuntimeException("NotImplementedException", m, file, line) {}
534 };
535
537 public:
538 NullPointerException(std::string const& m, const char* file, int line) noexcept
539 : RuntimeException("NullPointerException", m, file, line) {}
540 };
541
543 public:
544 UnsupportedOperationException(std::string const& m, const char* file, int line) noexcept
545 : RuntimeException("UnsupportedOperationException", m, file, line) {}
546 };
547
548 /**
549 // *************************************************
550 // *************************************************
551 // *************************************************
552 */
553
554 /** \addtogroup Integer
555 *
556 * @{
557 */
558
559 inline void set_bit_uint32(const uint8_t nr, uint32_t &mask)
560 {
561 using namespace jau::int_literals;
562 if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); }
563 mask |= 1_u32 << (nr & 31);
564 }
565
566 inline void clear_bit_uint32(const uint8_t nr, uint32_t &mask)
567 {
568 using namespace jau::int_literals;
569 if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); }
570 mask |= ~(1_u32 << (nr & 31));
571 }
572
573 inline uint32_t test_bit_uint32(const uint8_t nr, const uint32_t mask)
574 {
575 using namespace jau::int_literals;
576 if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); }
577 return mask & (1_u32 << (nr & 31));
578 }
579
580 inline void set_bit_uint64(const uint8_t nr, uint64_t &mask)
581 {
582 using namespace jau::int_literals;
583 if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); }
584 mask |= 1_u64 << (nr & 63);
585 }
586
587 inline void clear_bit_uint64(const uint8_t nr, uint64_t &mask)
588 {
589 using namespace jau::int_literals;
590 if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); }
591 mask |= ~(1_u64 << (nr & 63));
592 }
593
594 inline uint64_t test_bit_uint64(const uint8_t nr, const uint64_t mask)
595 {
596 using namespace jau::int_literals;
597 if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); }
598 return mask & (1_u64 << (nr & 63));
599 }
600
601 /**
602 // *************************************************
603 // *************************************************
604 // *************************************************
605 */
606
607 /**
608 * Merge the given 'uuid16' into a 'base_uuid' copy at the given little endian 'uuid16_le_octet_index' position.
609 * <p>
610 * The given 'uuid16' value will be added with the 'base_uuid' copy at the given position.
611 * </p>
612 * <pre>
613 * base_uuid: 00000000-0000-1000-8000-00805F9B34FB
614 * uuid16: DCBA
615 * uuid16_le_octet_index: 12
616 * result: 0000DCBA-0000-1000-8000-00805F9B34FB
617 *
618 * LE: low-mem - FB349B5F8000-0080-0010-0000-ABCD0000 - high-mem
619 * ^ index 12
620 * LE: uuid16 -> value.data[12+13]
621 *
622 * BE: low-mem - 0000DCBA-0000-1000-8000-00805F9B34FB - high-mem
623 * ^ index 2
624 * BE: uuid16 -> value.data[2+3]
625 * </pre>
626 */
627 uint128dp_t merge_uint128(uint16_t const uuid16, uint128dp_t const & base_uuid, nsize_t const uuid16_le_octet_index);
628
629 /**
630 * Merge the given 'uuid32' into a 'base_uuid' copy at the given little endian 'uuid32_le_octet_index' position.
631 * <p>
632 * The given 'uuid32' value will be added with the 'base_uuid' copy at the given position.
633 * </p>
634 * <pre>
635 * base_uuid: 00000000-0000-1000-8000-00805F9B34FB
636 * uuid32: 87654321
637 * uuid32_le_octet_index: 12
638 * result: 87654321-0000-1000-8000-00805F9B34FB
639 *
640 * LE: low-mem - FB349B5F8000-0080-0010-0000-12345678 - high-mem
641 * ^ index 12
642 * LE: uuid32 -> value.data[12..15]
643 *
644 * BE: low-mem - 87654321-0000-1000-8000-00805F9B34FB - high-mem
645 * ^ index 0
646 * BE: uuid32 -> value.data[0..3]
647 * </pre>
648 */
649 uint128dp_t merge_uint128(uint32_t const uuid32, uint128dp_t const & base_uuid, nsize_t const uuid32_le_octet_index);
650
651 /**@}*/
652
653} // namespace jau
654
655/** \example test_intdecstring01.cpp
656 * This C++ unit test validates the jau::to_decstring implementation
657 */
658
659#endif /* JAU_BASIC_TYPES_HPP_ */
#define E_FILE_LINE
const std::string & backtrace() const noexcept
Returns optional whole backtrace.
const std::string & whole_message() const noexcept
Returns brief message and optional whole backtrace, i.e.
ExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
std::ostream & operator<<(std::ostream &out) noexcept
virtual ~ExceptionBase() noexcept=default
const std::string & brief_message() const noexcept
Returns brief message.
virtual const char * what() const noexcept
IOError(std::string const &m, const char *file, int line, const std::error_code &ec=std::io_errc::stream) noexcept
const char * what() const noexcept override
IllegalArgumentError(std::string &&type, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
IllegalArgumentError(std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
IllegalStateError(std::string &&type, std::string const &m, const char *file, int line) noexcept
IllegalStateError(std::string const &m, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::string &msg, const std::size_t index, const std::size_t length, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char *file, int line) noexcept
const char * what() const noexcept override
IndexOutOfBoundsError(const std::string &index_s, const std::string &length_s, const char *file, int line) noexcept
IndexOutOfBoundsError(const char *file, int line, std::string &&type, std::string const &m) noexcept
InternalError(std::string const &m, const char *file, int line) noexcept
LogicErrorBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
~LogicErrorBase() noexcept override=default
LogicError(std::string &&type, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
LogicError(std::string const &m, const char *file, int line) noexcept
~LogicError() noexcept override=default
NotImplementedException(std::string const &m, const char *file, int line) noexcept
NullPointerException(std::string const &m, const char *file, int line) noexcept
OutOfMemoryError(std::string const &m, const char *file, int line)
const char * what() const noexcept override
~RuntimeExceptionBase() noexcept override=default
RuntimeExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
RuntimeException(std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
~RuntimeException() noexcept override=default
RuntimeException(std::string &&type, std::string const &m, const char *file, int line) noexcept
RuntimeSystemExceptionBase(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
~RuntimeSystemExceptionBase() noexcept override=default
const std::error_code & code() const noexcept
RuntimeSystemException(const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
~RuntimeSystemException() noexcept override=default
RuntimeSystemException(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
UnsupportedOperationException(std::string const &m, const char *file, int line) noexcept
fraction_timespec getWallClockTime() noexcept
Returns current wall-clock real-time since Unix Epoch 00:00:00 UTC on 1970-01-01.
fraction_timespec getMonotonicTime() noexcept
Returns current monotonic time since Unix Epoch 00:00:00 UTC on 1970-01-01.
fraction< int64_t > fraction_i64
fraction using int64_t as integral type
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition int_types.hpp:55
void set_bit_uint32(const uint8_t nr, uint32_t &mask)
uint128dp_t merge_uint128(uint16_t const uuid16, uint128dp_t const &base_uuid, nsize_t const uuid16_le_octet_index)
Merge the given 'uuid16' into a 'base_uuid' copy at the given little endian 'uuid16_le_octet_index' p...
void set_bit_uint64(const uint8_t nr, uint64_t &mask)
void clear_bit_uint32(const uint8_t nr, uint32_t &mask)
uint64_t test_bit_uint64(const uint8_t nr, const uint64_t mask)
uint32_t test_bit_uint32(const uint8_t nr, const uint32_t mask)
void clear_bit_uint64(const uint8_t nr, uint64_t &mask)
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
std::cv_status wait_for(std::condition_variable &cv, std::unique_lock< std::mutex > &lock, const fraction_timespec &relative_time, const bool monotonic=true) noexcept
wait_for causes the current thread to block until the condition variable is notified,...
uint64_t getWallClockSeconds() noexcept
Returns current wall-clock system time of day in seconds since Unix Epoch 00:00:00 UTC on 1 January 1...
std::string threadName(const std::thread::id id) noexcept
std::cv_status wait_until(std::condition_variable &cv, std::unique_lock< std::mutex > &lock, const fraction_timespec &absolute_time, const bool monotonic=true) noexcept
wait_until causes the current thread to block until the condition variable is notified,...
bool sleep_until(const fraction_timespec &absolute_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_until causes the current thread to block until the specific time is reached.
bool sleep(const fraction_timespec &relative_time, const bool ignore_irq=true) noexcept
sleep using high precision monotonic timer, useful for one-shot delays (only).
bool milli_sleep(uint64_t td_ms, const bool ignore_irq=true) noexcept
millisecond sleep using high precision monotonic timer, useful for one-shot delays (only).
uint64_t getCurrentMilliseconds() noexcept
Returns current monotonic time in milliseconds.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
STL namespace.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
A 128-bit packed uint8_t data array.