Convert space to tab indentation
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
308f63490c
commit
aa233bd5f9
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -14,269 +14,269 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Base64 encoding session
|
||||
///
|
||||
class base64_enc
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank encoding session
|
||||
///
|
||||
base64_enc() noexcept : num(0)
|
||||
{
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
}
|
||||
///
|
||||
/// Base64 encoding session
|
||||
///
|
||||
class base64_enc
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank encoding session
|
||||
///
|
||||
base64_enc() noexcept : num(0)
|
||||
{
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Encodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] data Data to encode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
/// \param[in ] is_last Is this the last block of data?
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true)
|
||||
{
|
||||
assert(data || !size);
|
||||
///
|
||||
/// Encodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] data Data to encode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
/// \param[in ] is_last Is this the last block of data?
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true)
|
||||
{
|
||||
assert(data || !size);
|
||||
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + enc_size(size));
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + enc_size(size));
|
||||
|
||||
// Convert data character by character.
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 3) {
|
||||
encode(out);
|
||||
num = 0;
|
||||
}
|
||||
// Convert data character by character.
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 3) {
|
||||
encode(out);
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (i >= size)
|
||||
break;
|
||||
if (i >= size)
|
||||
break;
|
||||
|
||||
buf[num++] = reinterpret_cast<const uint8_t*>(data)[i];
|
||||
}
|
||||
buf[num++] = reinterpret_cast<const uint8_t*>(data)[i];
|
||||
}
|
||||
|
||||
// If this is the last block, flush the buffer.
|
||||
if (is_last && num) {
|
||||
encode(out, num);
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
// If this is the last block, flush the buffer.
|
||||
if (is_last && num) {
|
||||
encode(out, num);
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Resets encoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
///
|
||||
/// Resets encoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Returns maximum encoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to encode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the encoded data of `size` length
|
||||
///
|
||||
size_t enc_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return ((num + size + 2)/3)*4;
|
||||
}
|
||||
///
|
||||
/// Returns maximum encoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to encode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the encoded data of `size` length
|
||||
///
|
||||
size_t enc_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return ((num + size + 2)/3)*4;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Encodes one complete internal buffer of data
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out)
|
||||
{
|
||||
out += base64_enc_lookup[ buf[0] >> 2 ];
|
||||
out += base64_enc_lookup[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
|
||||
out += base64_enc_lookup[((buf[1] << 2) | (buf[2] >> 6)) & 0x3f];
|
||||
out += base64_enc_lookup[ buf[2] & 0x3f];
|
||||
}
|
||||
protected:
|
||||
///
|
||||
/// Encodes one complete internal buffer of data
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out)
|
||||
{
|
||||
out += base64_enc_lookup[ buf[0] >> 2 ];
|
||||
out += base64_enc_lookup[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
|
||||
out += base64_enc_lookup[((buf[1] << 2) | (buf[2] >> 6)) & 0x3f];
|
||||
out += base64_enc_lookup[ buf[2] & 0x3f];
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Encodes partial internal buffer of data
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_ size_t size)
|
||||
{
|
||||
if (size > 0) {
|
||||
out += base64_enc_lookup[buf[0] >> 2];
|
||||
if (size > 1) {
|
||||
out += base64_enc_lookup[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
|
||||
if (size > 2) {
|
||||
out += base64_enc_lookup[((buf[1] << 2) | (buf[2] >> 6)) & 0x3f];
|
||||
out += base64_enc_lookup[buf[2] & 0x3f];
|
||||
} else {
|
||||
out += base64_enc_lookup[(buf[1] << 2) & 0x3f];
|
||||
out += '=';
|
||||
}
|
||||
} else {
|
||||
out += base64_enc_lookup[(buf[0] << 4) & 0x3f];
|
||||
out += '=';
|
||||
out += '=';
|
||||
}
|
||||
} else {
|
||||
out += '=';
|
||||
out += '=';
|
||||
out += '=';
|
||||
out += '=';
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Encodes partial internal buffer of data
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_ size_t size)
|
||||
{
|
||||
if (size > 0) {
|
||||
out += base64_enc_lookup[buf[0] >> 2];
|
||||
if (size > 1) {
|
||||
out += base64_enc_lookup[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
|
||||
if (size > 2) {
|
||||
out += base64_enc_lookup[((buf[1] << 2) | (buf[2] >> 6)) & 0x3f];
|
||||
out += base64_enc_lookup[buf[2] & 0x3f];
|
||||
} else {
|
||||
out += base64_enc_lookup[(buf[1] << 2) & 0x3f];
|
||||
out += '=';
|
||||
}
|
||||
} else {
|
||||
out += base64_enc_lookup[(buf[0] << 4) & 0x3f];
|
||||
out += '=';
|
||||
out += '=';
|
||||
}
|
||||
} else {
|
||||
out += '=';
|
||||
out += '=';
|
||||
out += '=';
|
||||
out += '=';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
uint8_t buf[3]; ///< Internal buffer
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
protected:
|
||||
uint8_t buf[3]; ///< Internal buffer
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
|
||||
|
||||
/// \cond internal
|
||||
static const char base64_enc_lookup[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
/// \endcond
|
||||
/// \cond internal
|
||||
static const char base64_enc_lookup[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
/// \endcond
|
||||
|
||||
|
||||
///
|
||||
/// Base64 decoding session
|
||||
///
|
||||
class base64_dec
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank decoding session
|
||||
///
|
||||
base64_dec() noexcept : num(0)
|
||||
{
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
buf[3] = 0;
|
||||
}
|
||||
///
|
||||
/// Base64 decoding session
|
||||
///
|
||||
class base64_dec
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank decoding session
|
||||
///
|
||||
base64_dec() noexcept : num(0)
|
||||
{
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
buf[3] = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Decodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] is_last Was this the last block of data?
|
||||
/// \param[in ] data Data to decode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Ty, class _Ax, class _Tchr>
|
||||
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
|
||||
{
|
||||
is_last = false;
|
||||
///
|
||||
/// Decodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] is_last Was this the last block of data?
|
||||
/// \param[in ] data Data to decode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Ty, class _Ax, class _Tchr>
|
||||
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
|
||||
{
|
||||
is_last = false;
|
||||
|
||||
// Trim data size to first terminator.
|
||||
for (size_t k = 0; k < size; k++)
|
||||
if (!data[k]) { size = k; break; }
|
||||
// Trim data size to first terminator.
|
||||
for (size_t k = 0; k < size; k++)
|
||||
if (!data[k]) { size = k; break; }
|
||||
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + dec_size(size));
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + dec_size(size));
|
||||
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 4) {
|
||||
// Buffer full; decode it.
|
||||
size_t nibbles = decode(out);
|
||||
num = 0;
|
||||
if (nibbles < 3) {
|
||||
is_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 4) {
|
||||
// Buffer full; decode it.
|
||||
size_t nibbles = decode(out);
|
||||
num = 0;
|
||||
if (nibbles < 3) {
|
||||
is_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= size)
|
||||
break;
|
||||
if (i >= size)
|
||||
break;
|
||||
|
||||
int x = data[i];
|
||||
if ((buf[num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
|
||||
num++;
|
||||
}
|
||||
}
|
||||
int x = data[i];
|
||||
if ((buf[num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Resets decoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
///
|
||||
/// Resets decoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Returns maximum decoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to decode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the decoded data of `size` length
|
||||
///
|
||||
size_t dec_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return ((num + size + 3)/4)*3;
|
||||
}
|
||||
///
|
||||
/// Returns maximum decoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to decode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the decoded data of `size` length
|
||||
///
|
||||
size_t dec_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return ((num + size + 3)/4)*3;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Decodes one complete internal buffer of data
|
||||
///
|
||||
template<class _Ty, class _Ax>
|
||||
size_t decode(_Inout_ std::vector<_Ty, _Ax> &out)
|
||||
{
|
||||
out.push_back((_Ty)(((buf[0] << 2) | (buf[1] >> 4)) & 0xff));
|
||||
if (buf[2] < 64) {
|
||||
out.push_back((_Ty)(((buf[1] << 4) | (buf[2] >> 2)) & 0xff));
|
||||
if (buf[3] < 64) {
|
||||
out.push_back((_Ty)(((buf[2] << 6) | buf[3]) & 0xff));
|
||||
return 3;
|
||||
} else
|
||||
return 2;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
protected:
|
||||
///
|
||||
/// Decodes one complete internal buffer of data
|
||||
///
|
||||
template<class _Ty, class _Ax>
|
||||
size_t decode(_Inout_ std::vector<_Ty, _Ax> &out)
|
||||
{
|
||||
out.push_back((_Ty)(((buf[0] << 2) | (buf[1] >> 4)) & 0xff));
|
||||
if (buf[2] < 64) {
|
||||
out.push_back((_Ty)(((buf[1] << 4) | (buf[2] >> 2)) & 0xff));
|
||||
if (buf[3] < 64) {
|
||||
out.push_back((_Ty)(((buf[2] << 6) | buf[3]) & 0xff));
|
||||
return 3;
|
||||
} else
|
||||
return 2;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
uint8_t buf[4]; ///< Internal buffer
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
protected:
|
||||
uint8_t buf[4]; ///< Internal buffer
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
|
||||
|
||||
/// \cond internal
|
||||
static const uint8_t base64_dec_lookup[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
/* 0 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 1 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 2 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
/* 3 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
|
||||
/* 4 */ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
/* 6 */ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
/* 7 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
|
||||
/* 8 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 9 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* A */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* B */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* C */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* D */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
/// \endcond
|
||||
/// \cond internal
|
||||
static const uint8_t base64_dec_lookup[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
/* 0 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 1 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 2 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
/* 3 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
|
||||
/* 4 */ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
/* 6 */ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
/* 7 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
|
||||
/* 8 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 9 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* A */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* B */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* C */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* D */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
/// \endcond
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -11,67 +11,67 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Standard C runtime library error
|
||||
///
|
||||
class errno_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ errno_t num, _In_ const std::string& msg) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Standard C runtime library error
|
||||
///
|
||||
class errno_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ errno_t num, _In_ const std::string& msg) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ errno_t num, _In_opt_z_ const char *msg = nullptr) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ errno_t num, _In_opt_z_ const char *msg = nullptr) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructs an exception using `GetLastError()`
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ const std::string& msg) :
|
||||
m_num(errno),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Constructs an exception using `GetLastError()`
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_ const std::string& msg) :
|
||||
m_num(errno),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructs an exception using `GetLastError()`
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_opt_z_ const char *msg = nullptr) :
|
||||
m_num(errno),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Constructs an exception using `GetLastError()`
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
errno_error(_In_opt_z_ const char *msg = nullptr) :
|
||||
m_num(errno),
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the error number
|
||||
///
|
||||
errno_t number() const
|
||||
{
|
||||
return m_num;
|
||||
}
|
||||
///
|
||||
/// Returns the error number
|
||||
///
|
||||
errno_t number() const
|
||||
{
|
||||
return m_num;
|
||||
}
|
||||
|
||||
protected:
|
||||
errno_t m_num; ///< Numeric error code
|
||||
};
|
||||
protected:
|
||||
errno_t m_num; ///< Numeric error code
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -10,19 +10,19 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// User cancelled exception
|
||||
///
|
||||
class user_cancelled : public std::exception
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
user_cancelled(_In_opt_z_ const char *msg = nullptr) : exception(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
///
|
||||
/// User cancelled exception
|
||||
///
|
||||
class user_cancelled : public std::exception
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
user_cancelled(_In_opt_z_ const char *msg = nullptr) : exception(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -14,149 +14,149 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Hexadecimal encoding session
|
||||
///
|
||||
class hex_enc
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank encoding session
|
||||
///
|
||||
hex_enc() noexcept
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Hexadecimal encoding session
|
||||
///
|
||||
class hex_enc
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank encoding session
|
||||
///
|
||||
hex_enc() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Encodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] data Data to encode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size)
|
||||
{
|
||||
assert(data || !size);
|
||||
///
|
||||
/// Encodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[out] out Output
|
||||
/// \param[in ] data Data to encode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size)
|
||||
{
|
||||
assert(data || !size);
|
||||
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + enc_size(size));
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + enc_size(size));
|
||||
|
||||
// Convert data character by character.
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
uint8_t
|
||||
x = reinterpret_cast<const uint8_t*>(data)[i],
|
||||
x_h = ((x & 0xf0) >> 4),
|
||||
x_l = ((x & 0x0f) );
|
||||
// Convert data character by character.
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
uint8_t
|
||||
x = reinterpret_cast<const uint8_t*>(data)[i],
|
||||
x_h = ((x & 0xf0) >> 4),
|
||||
x_l = ((x & 0x0f) );
|
||||
|
||||
out += x_h < 10 ? '0' + x_h : 'A' - 10 + x_h;
|
||||
out += x_l < 10 ? '0' + x_l : 'A' - 10 + x_l;
|
||||
}
|
||||
}
|
||||
out += x_h < 10 ? '0' + x_h : 'A' - 10 + x_h;
|
||||
out += x_l < 10 ? '0' + x_l : 'A' - 10 + x_l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Returns maximum encoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to encode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the encoded data of `size` length
|
||||
///
|
||||
size_t enc_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return size*2;
|
||||
}
|
||||
};
|
||||
///
|
||||
/// Returns maximum encoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to encode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the encoded data of `size` length
|
||||
///
|
||||
size_t enc_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return size*2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// Hexadecimal decoding session
|
||||
///
|
||||
class hex_dec
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank decoding session
|
||||
///
|
||||
hex_dec() noexcept :
|
||||
buf(0),
|
||||
num(0)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Hexadecimal decoding session
|
||||
///
|
||||
class hex_dec
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs blank decoding session
|
||||
///
|
||||
hex_dec() noexcept :
|
||||
buf(0),
|
||||
num(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Decodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[inout] out Output
|
||||
/// \param[out ] is_last Was this the last block of data? Actually, is this block of data complete?
|
||||
/// \param[in ] data Data to decode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Ty, class _Ax, class _Tchr>
|
||||
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
|
||||
{
|
||||
is_last = false;
|
||||
///
|
||||
/// Decodes one block of information, and _appends_ it to the output
|
||||
///
|
||||
/// \param[inout] out Output
|
||||
/// \param[out ] is_last Was this the last block of data? Actually, is this block of data complete?
|
||||
/// \param[in ] data Data to decode
|
||||
/// \param[in ] size Length of `data` in bytes
|
||||
///
|
||||
template<class _Ty, class _Ax, class _Tchr>
|
||||
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
|
||||
{
|
||||
is_last = false;
|
||||
|
||||
// Trim data size to first terminator.
|
||||
for (size_t k = 0; k < size; k++)
|
||||
if (!data[k]) { size = k; break; }
|
||||
// Trim data size to first terminator.
|
||||
for (size_t k = 0; k < size; k++)
|
||||
if (!data[k]) { size = k; break; }
|
||||
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + dec_size(size));
|
||||
// Preallocate output
|
||||
out.reserve(out.size() + dec_size(size));
|
||||
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 2) {
|
||||
// Buffer full.
|
||||
out.push_back(buf);
|
||||
num = 0;
|
||||
is_last = true;
|
||||
} else
|
||||
is_last = false;
|
||||
for (size_t i = 0;; i++) {
|
||||
if (num >= 2) {
|
||||
// Buffer full.
|
||||
out.push_back(buf);
|
||||
num = 0;
|
||||
is_last = true;
|
||||
} else
|
||||
is_last = false;
|
||||
|
||||
if (i >= size)
|
||||
break;
|
||||
if (i >= size)
|
||||
break;
|
||||
|
||||
int x = data[i];
|
||||
if ('0' <= x && x <= '9') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - '0');
|
||||
num++;
|
||||
} else if ('A' <= x && x <= 'F') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - ('A' - 10));
|
||||
num++;
|
||||
} else if ('a' <= x && x <= 'f') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - ('a' - 10));
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
int x = data[i];
|
||||
if ('0' <= x && x <= '9') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - '0');
|
||||
num++;
|
||||
} else if ('A' <= x && x <= 'F') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - ('A' - 10));
|
||||
num++;
|
||||
} else if ('a' <= x && x <= 'f') {
|
||||
buf = ((buf & 0xf) << 4) | (uint8_t)(x - ('a' - 10));
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Resets decoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
///
|
||||
/// Resets decoding session
|
||||
///
|
||||
void clear() noexcept
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Returns maximum decoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to decode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the decoded data of `size` length
|
||||
///
|
||||
size_t dec_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return (size + 1)/2;
|
||||
}
|
||||
///
|
||||
/// Returns maximum decoded size
|
||||
///
|
||||
/// \param[in] size Number of bytes to decode
|
||||
///
|
||||
/// \returns Maximum number of bytes for the decoded data of `size` length
|
||||
///
|
||||
size_t dec_size(_In_ size_t size) const noexcept
|
||||
{
|
||||
return (size + 1)/2;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
uint8_t buf; ///< Internal buffer
|
||||
size_t num; ///< Number of nibbles used in `buf`
|
||||
};
|
||||
protected:
|
||||
uint8_t buf; ///< Internal buffer
|
||||
size_t num; ///< Number of nibbles used in `buf`
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -12,237 +12,237 @@
|
||||
|
||||
|
||||
namespace stdex {
|
||||
namespace idrec {
|
||||
///
|
||||
/// Reads record ID
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[out] id Record ID
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when succeeded
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_ID>
|
||||
_Success_(return) bool read_id(_In_ std::istream& stream, _Out_ T_ID &id, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
if (end == (std::streamoff)-1 || stream.tellg() < end) {
|
||||
stream.read((char*)&id, sizeof(id));
|
||||
return stream.good();
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
namespace idrec {
|
||||
///
|
||||
/// Reads record ID
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[out] id Record ID
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when succeeded
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_ID>
|
||||
_Success_(return) bool read_id(_In_ std::istream& stream, _Out_ T_ID &id, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
if (end == (std::streamoff)-1 || stream.tellg() < end) {
|
||||
stream.read((char*)&id, sizeof(id));
|
||||
return stream.good();
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Skips current record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when successful
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_SIZE, unsigned int ALIGN>
|
||||
bool ignore(_In_ std::istream& stream)
|
||||
{
|
||||
// Read record size.
|
||||
T_SIZE size;
|
||||
stream.read((char*)&size, sizeof(size));
|
||||
if (!stream.good()) return false;
|
||||
///
|
||||
/// Skips current record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when successful
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_SIZE, unsigned int ALIGN>
|
||||
bool ignore(_In_ std::istream& stream)
|
||||
{
|
||||
// Read record size.
|
||||
T_SIZE size;
|
||||
stream.read((char*)&size, sizeof(size));
|
||||
if (!stream.good()) return false;
|
||||
|
||||
// Skip the record data.
|
||||
size += (T_SIZE)(ALIGN - size) % ALIGN;
|
||||
stream.ignore(size);
|
||||
if (!stream.good()) return false;
|
||||
// Skip the record data.
|
||||
size += (T_SIZE)(ALIGN - size) % ALIGN;
|
||||
stream.ignore(size);
|
||||
if (!stream.good()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Finds record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[in] id Record ID
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when found
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_ID, class T_SIZE, unsigned int ALIGN>
|
||||
bool find(_In_ std::istream& stream, _In_ T_ID id, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
T_ID _id;
|
||||
///
|
||||
/// Finds record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[in] id Record ID
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when found
|
||||
/// - \c false otherwise
|
||||
///
|
||||
template <class T_ID, class T_SIZE, unsigned int ALIGN>
|
||||
bool find(_In_ std::istream& stream, _In_ T_ID id, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
T_ID _id;
|
||||
|
||||
while (end == (std::streamoff)-1 || stream.tellg() < end) {
|
||||
stream.read((char*)&_id, sizeof(_id));
|
||||
if (!stream.good()) return false;
|
||||
while (end == (std::streamoff)-1 || stream.tellg() < end) {
|
||||
stream.read((char*)&_id, sizeof(_id));
|
||||
if (!stream.good()) return false;
|
||||
|
||||
if (_id == id) {
|
||||
// The record was found.
|
||||
return true;
|
||||
} else
|
||||
ignore<T_SIZE, ALIGN>(stream);
|
||||
}
|
||||
if (_id == id) {
|
||||
// The record was found.
|
||||
return true;
|
||||
} else
|
||||
ignore<T_SIZE, ALIGN>(stream);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Writes record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] id Record ID
|
||||
///
|
||||
/// \returns Position of the record header start in \p stream. Save for later \c close call.
|
||||
///
|
||||
template <class T_ID, class T_SIZE>
|
||||
std::streamoff open(_In_ std::ostream& stream, _In_ T_ID id)
|
||||
{
|
||||
std::streamoff start = stream.tellp();
|
||||
///
|
||||
/// Writes record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] id Record ID
|
||||
///
|
||||
/// \returns Position of the record header start in \p stream. Save for later \c close call.
|
||||
///
|
||||
template <class T_ID, class T_SIZE>
|
||||
std::streamoff open(_In_ std::ostream& stream, _In_ T_ID id)
|
||||
{
|
||||
std::streamoff start = stream.tellp();
|
||||
|
||||
// Write ID.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
stream.write((const char*)&id, sizeof(id));
|
||||
// Write ID.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
stream.write((const char*)&id, sizeof(id));
|
||||
|
||||
// Write 0 as a placeholder for data size.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
T_SIZE size = 0;
|
||||
stream.write((const char*)&size, sizeof(size));
|
||||
// Write 0 as a placeholder for data size.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
T_SIZE size = 0;
|
||||
stream.write((const char*)&size, sizeof(size));
|
||||
|
||||
return start;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Updates record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] start Start position of the record in \p stream
|
||||
///
|
||||
/// \returns Position of the record end in \p stream
|
||||
///
|
||||
template <class T_ID, class T_SIZE, unsigned int ALIGN>
|
||||
std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
|
||||
{
|
||||
std::streamoff end = stream.tellp();
|
||||
T_SIZE
|
||||
size = (T_SIZE)(end - start - sizeof(T_ID) - sizeof(T_SIZE)),
|
||||
remainder = (T_SIZE)(ALIGN - size) % ALIGN; // Number of bytes we need to add, to keep the data integral number of ALIGN blocks long
|
||||
///
|
||||
/// Updates record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] start Start position of the record in \p stream
|
||||
///
|
||||
/// \returns Position of the record end in \p stream
|
||||
///
|
||||
template <class T_ID, class T_SIZE, unsigned int ALIGN>
|
||||
std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
|
||||
{
|
||||
std::streamoff end = stream.tellp();
|
||||
T_SIZE
|
||||
size = (T_SIZE)(end - start - sizeof(T_ID) - sizeof(T_SIZE)),
|
||||
remainder = (T_SIZE)(ALIGN - size) % ALIGN; // Number of bytes we need to add, to keep the data integral number of ALIGN blocks long
|
||||
|
||||
if (remainder) {
|
||||
// Append padding.
|
||||
static const char padding[ALIGN] = {};
|
||||
stream.write(padding, remainder);
|
||||
end += remainder;
|
||||
}
|
||||
if (remainder) {
|
||||
// Append padding.
|
||||
static const char padding[ALIGN] = {};
|
||||
stream.write(padding, remainder);
|
||||
end += remainder;
|
||||
}
|
||||
|
||||
// Update the data size.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
stream.seekp(start + sizeof(T_ID));
|
||||
stream.write((const char*)&size, sizeof(size));
|
||||
stream.seekp(end);
|
||||
// Update the data size.
|
||||
if (stream.fail()) return (std::streamoff)-1;
|
||||
stream.seekp(start + sizeof(T_ID));
|
||||
stream.write((const char*)&size, sizeof(size));
|
||||
stream.seekp(end);
|
||||
|
||||
return end;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Helper class for read/write of records to/from memory
|
||||
///
|
||||
template <class T, class T_ID, const T_ID ID, class T_SIZE, unsigned int ALIGN>
|
||||
class record
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the class
|
||||
///
|
||||
/// \param[in] d Reference to record data
|
||||
///
|
||||
record(_In_ T &d) : data(d) {}
|
||||
///
|
||||
/// Helper class for read/write of records to/from memory
|
||||
///
|
||||
template <class T, class T_ID, const T_ID ID, class T_SIZE, unsigned int ALIGN>
|
||||
class record
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the class
|
||||
///
|
||||
/// \param[in] d Reference to record data
|
||||
///
|
||||
record(_In_ T &d) : data(d) {}
|
||||
|
||||
|
||||
///
|
||||
/// Constructs the class
|
||||
///
|
||||
/// \param[in] d Reference to record data
|
||||
///
|
||||
record(_In_ const T &d) : data((T&)d) {}
|
||||
///
|
||||
/// Constructs the class
|
||||
///
|
||||
/// \param[in] d Reference to record data
|
||||
///
|
||||
record(_In_ const T &d) : data((T&)d) {}
|
||||
|
||||
|
||||
///
|
||||
/// Returns record id
|
||||
///
|
||||
static const T_ID id()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
///
|
||||
/// Returns record id
|
||||
///
|
||||
static const T_ID id()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Assignment operator
|
||||
///
|
||||
/// \param[in] r Source record
|
||||
///
|
||||
/// \returns A const reference to this struct
|
||||
///
|
||||
const record<T, T_ID, ID, T_SIZE, ALIGN>& operator =(_In_ const record<T, T_ID, ID, T_SIZE, ALIGN> &r)
|
||||
{
|
||||
data = r.data;
|
||||
return *this;
|
||||
}
|
||||
///
|
||||
/// Assignment operator
|
||||
///
|
||||
/// \param[in] r Source record
|
||||
///
|
||||
/// \returns A const reference to this struct
|
||||
///
|
||||
const record<T, T_ID, ID, T_SIZE, ALIGN>& operator =(_In_ const record<T, T_ID, ID, T_SIZE, ALIGN> &r)
|
||||
{
|
||||
data = r.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Writes record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
///
|
||||
/// \returns Position of the record header start in \p stream. Save for later \c close call.
|
||||
///
|
||||
static std::streamoff open(_In_ std::ostream& stream)
|
||||
{
|
||||
return stdex::idrec::open<T_ID, T_SIZE>(stream, ID);
|
||||
}
|
||||
///
|
||||
/// Writes record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
///
|
||||
/// \returns Position of the record header start in \p stream. Save for later \c close call.
|
||||
///
|
||||
static std::streamoff open(_In_ std::ostream& stream)
|
||||
{
|
||||
return stdex::idrec::open<T_ID, T_SIZE>(stream, ID);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Updates record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] start Start position of the record in \p stream
|
||||
///
|
||||
/// \returns Position of the record end in \p stream
|
||||
///
|
||||
static std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
|
||||
{
|
||||
return stdex::idrec::close<T_ID, T_SIZE, ALIGN>(stream, start);
|
||||
}
|
||||
///
|
||||
/// Updates record header
|
||||
///
|
||||
/// \param[in] stream Output stream
|
||||
/// \param[in] start Start position of the record in \p stream
|
||||
///
|
||||
/// \returns Position of the record end in \p stream
|
||||
///
|
||||
static std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
|
||||
{
|
||||
return stdex::idrec::close<T_ID, T_SIZE, ALIGN>(stream, start);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Finds record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when found
|
||||
/// - \c false otherwise
|
||||
///
|
||||
static bool find(_In_ std::istream& stream, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
return stdex::idrec::find<T_ID, T_SIZE, ALIGN>(stream, ID, end);
|
||||
}
|
||||
///
|
||||
/// Finds record data
|
||||
///
|
||||
/// \param[in] stream Input stream
|
||||
/// \param[in] end Position limit. Default is -1 (no limit).
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when found
|
||||
/// - \c false otherwise
|
||||
///
|
||||
static bool find(_In_ std::istream& stream, _In_opt_ std::streamoff end = (std::streamoff)-1)
|
||||
{
|
||||
return stdex::idrec::find<T_ID, T_SIZE, ALIGN>(stream, ID, end);
|
||||
}
|
||||
|
||||
|
||||
T &data; ///< Record data reference
|
||||
};
|
||||
};
|
||||
T &data; ///< Record data reference
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -257,14 +257,14 @@ namespace stdex {
|
||||
template <class T, class T_ID, T_ID ID, class T_SIZE, unsigned int ALIGN>
|
||||
std::ostream& operator <<(_In_ std::ostream& stream, _In_ const stdex::idrec::record<T, T_ID, ID, T_SIZE, ALIGN> r)
|
||||
{
|
||||
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
|
||||
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
|
||||
|
||||
std::streamoff start = r.open(stream);
|
||||
if (stream.fail()) return stream;
|
||||
stream << r.data;
|
||||
r.close(stream, start);
|
||||
std::streamoff start = r.open(stream);
|
||||
if (stream.fail()) return stream;
|
||||
stream << r.data;
|
||||
r.close(stream, start);
|
||||
|
||||
return stream;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
@ -279,19 +279,19 @@ std::ostream& operator <<(_In_ std::ostream& stream, _In_ const stdex::idrec::re
|
||||
template <class T, class T_ID, T_ID ID, class T_SIZE, unsigned int ALIGN>
|
||||
std::istream& operator >>(_In_ std::istream& stream, _In_ stdex::idrec::record<T, T_ID, ID, T_SIZE, ALIGN> r)
|
||||
{
|
||||
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
|
||||
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
|
||||
|
||||
// Read data size.
|
||||
T_SIZE size;
|
||||
stream.read((char*)&size, sizeof(size));
|
||||
if (!stream.good()) return stream;
|
||||
// Read data size.
|
||||
T_SIZE size;
|
||||
stream.read((char*)&size, sizeof(size));
|
||||
if (!stream.good()) return stream;
|
||||
|
||||
// Read data.
|
||||
std::streamoff start = stream.tellg();
|
||||
stream >> r.data; // TODO: operator >> should not read past the record data! Make a size limited stream and read from it instead.
|
||||
// Read data.
|
||||
std::streamoff start = stream.tellg();
|
||||
stream >> r.data; // TODO: operator >> should not read past the record data! Make a size limited stream and read from it instead.
|
||||
|
||||
size += (T_SIZE)(ALIGN - size) % ALIGN;
|
||||
stream.seekg(start + size);
|
||||
size += (T_SIZE)(ALIGN - size) % ALIGN;
|
||||
stream.seekg(start + size);
|
||||
|
||||
return stream;
|
||||
return stream;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -9,54 +9,54 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Numerical interval
|
||||
///
|
||||
template <class T>
|
||||
struct interval
|
||||
{
|
||||
T start; ///< interval start
|
||||
T end; ///< interval end
|
||||
///
|
||||
/// Numerical interval
|
||||
///
|
||||
template <class T>
|
||||
struct interval
|
||||
{
|
||||
T start; ///< interval start
|
||||
T end; ///< interval end
|
||||
|
||||
///
|
||||
/// Constructs an invalid interval
|
||||
///
|
||||
inline interval() noexcept : start(1), end(0) {}
|
||||
///
|
||||
/// Constructs an invalid interval
|
||||
///
|
||||
inline interval() noexcept : start(1), end(0) {}
|
||||
|
||||
///
|
||||
/// Constructs a zero-size interval
|
||||
///
|
||||
/// \param[in] x Interval start and end value
|
||||
///
|
||||
inline interval(_In_ T x) noexcept : start(x), end(x) {}
|
||||
///
|
||||
/// Constructs a zero-size interval
|
||||
///
|
||||
/// \param[in] x Interval start and end value
|
||||
///
|
||||
inline interval(_In_ T x) noexcept : start(x), end(x) {}
|
||||
|
||||
///
|
||||
/// Constructs an interval
|
||||
///
|
||||
/// \param[in] _start Interval start value
|
||||
/// \param[in] _end Interval end value
|
||||
///
|
||||
inline interval(_In_ T _start, _In_ T _end) noexcept : start(_start), end(_end) {}
|
||||
///
|
||||
/// Constructs an interval
|
||||
///
|
||||
/// \param[in] _start Interval start value
|
||||
/// \param[in] _end Interval end value
|
||||
///
|
||||
inline interval(_In_ T _start, _In_ T _end) noexcept : start(_start), end(_end) {}
|
||||
|
||||
///
|
||||
/// Returns interval size
|
||||
///
|
||||
/// \returns Interval size or 0 if interval is invalid
|
||||
///
|
||||
inline T size() const { return start <= end ? end - start : 0; }
|
||||
///
|
||||
/// Returns interval size
|
||||
///
|
||||
/// \returns Interval size or 0 if interval is invalid
|
||||
///
|
||||
inline T size() const { return start <= end ? end - start : 0; }
|
||||
|
||||
///
|
||||
/// Is interval empty?
|
||||
///
|
||||
/// \returns true if interval is empty or false otherwise
|
||||
///
|
||||
inline bool empty() const { return start >= end; }
|
||||
///
|
||||
/// Is interval empty?
|
||||
///
|
||||
/// \returns true if interval is empty or false otherwise
|
||||
///
|
||||
inline bool empty() const { return start >= end; }
|
||||
|
||||
///
|
||||
/// Is interval valid?
|
||||
///
|
||||
/// \returns true if interval is valid or false otherwise
|
||||
///
|
||||
inline operator bool() const { return start <= end; }
|
||||
};
|
||||
///
|
||||
/// Is interval valid?
|
||||
///
|
||||
/// \returns true if interval is valid or false otherwise
|
||||
///
|
||||
inline operator bool() const { return start <= end; }
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -11,254 +11,254 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Progress indicator base class
|
||||
///
|
||||
template <class T>
|
||||
class progress
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Set progress indicator text
|
||||
///
|
||||
/// \param[in] msg Text to display
|
||||
///
|
||||
virtual void set_text(_In_z_ const char* msg)
|
||||
{
|
||||
msg;
|
||||
}
|
||||
///
|
||||
/// Progress indicator base class
|
||||
///
|
||||
template <class T>
|
||||
class progress
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Set progress indicator text
|
||||
///
|
||||
/// \param[in] msg Text to display
|
||||
///
|
||||
virtual void set_text(_In_z_ const char* msg)
|
||||
{
|
||||
msg;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set progress range extent
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
start; end;
|
||||
}
|
||||
///
|
||||
/// Set progress range extent
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
start; end;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
value;
|
||||
}
|
||||
///
|
||||
/// Set current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
value;
|
||||
}
|
||||
|
||||
///
|
||||
/// Show or hide progress
|
||||
///
|
||||
/// \param[in] show Shows or hides progress indicator
|
||||
///
|
||||
virtual void show(_In_ bool show = true)
|
||||
{
|
||||
show;
|
||||
}
|
||||
///
|
||||
/// Show or hide progress
|
||||
///
|
||||
/// \param[in] show Shows or hides progress indicator
|
||||
///
|
||||
virtual void show(_In_ bool show = true)
|
||||
{
|
||||
show;
|
||||
}
|
||||
|
||||
///
|
||||
/// Query whether user requested abort
|
||||
///
|
||||
virtual bool cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
///
|
||||
/// Query whether user requested abort
|
||||
///
|
||||
virtual bool cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// Lazy progress indicator base class
|
||||
///
|
||||
/// Use with expensive progress reporting to suppress progress indication for a period of time.
|
||||
///
|
||||
template <class T>
|
||||
class lazy_progress : public progress<T>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a lazy progress indicator
|
||||
///
|
||||
/// \param[in] timeout Timeout to wait before forwarding progress
|
||||
///
|
||||
lazy_progress(_In_ const std::chrono::nanoseconds& timeout = std::chrono::nanoseconds(500000)) :
|
||||
m_timeout(timeout),
|
||||
m_start(0),
|
||||
m_end(0),
|
||||
m_value(-1)
|
||||
{}
|
||||
///
|
||||
/// Lazy progress indicator base class
|
||||
///
|
||||
/// Use with expensive progress reporting to suppress progress indication for a period of time.
|
||||
///
|
||||
template <class T>
|
||||
class lazy_progress : public progress<T>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a lazy progress indicator
|
||||
///
|
||||
/// \param[in] timeout Timeout to wait before forwarding progress
|
||||
///
|
||||
lazy_progress(_In_ const std::chrono::nanoseconds& timeout = std::chrono::nanoseconds(500000)) :
|
||||
m_timeout(timeout),
|
||||
m_start(0),
|
||||
m_end(0),
|
||||
m_value(-1)
|
||||
{}
|
||||
|
||||
///
|
||||
/// Set progress range extent
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_start = start;
|
||||
m_end = end;
|
||||
}
|
||||
///
|
||||
/// Set progress range extent
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_start = start;
|
||||
m_end = end;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
if (value == m_start || value == m_end)
|
||||
m_last = std::chrono::high_resolution_clock::now();
|
||||
else if (value == m_value)
|
||||
return;
|
||||
else {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (now - m_last < m_timeout)
|
||||
return;
|
||||
m_last = now;
|
||||
}
|
||||
m_value = value;
|
||||
do_set();
|
||||
}
|
||||
///
|
||||
/// Set current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
if (value == m_start || value == m_end)
|
||||
m_last = std::chrono::high_resolution_clock::now();
|
||||
else if (value == m_value)
|
||||
return;
|
||||
else {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (now - m_last < m_timeout)
|
||||
return;
|
||||
m_last = now;
|
||||
}
|
||||
m_value = value;
|
||||
do_set();
|
||||
}
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Called when progress reporting is due. Should override this method to implement actual progress refresh.
|
||||
///
|
||||
virtual void do_set() {}
|
||||
protected:
|
||||
///
|
||||
/// Called when progress reporting is due. Should override this method to implement actual progress refresh.
|
||||
///
|
||||
virtual void do_set() {}
|
||||
|
||||
protected:
|
||||
std::chrono::nanoseconds m_timeout;
|
||||
std::chrono::steady_clock::time_point m_last;
|
||||
T m_start, m_end, m_value;
|
||||
};
|
||||
protected:
|
||||
std::chrono::nanoseconds m_timeout;
|
||||
std::chrono::steady_clock::time_point m_last;
|
||||
T m_start, m_end, m_value;
|
||||
};
|
||||
|
||||
///
|
||||
/// Global progress indicator base class
|
||||
///
|
||||
/// Use to report progress of a phase or section as a part of a whole progress.
|
||||
///
|
||||
template <class T>
|
||||
class global_progress : public progress<T>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a progress indicator
|
||||
///
|
||||
/// \param[in] host Host progress indicator
|
||||
///
|
||||
global_progress(_In_opt_ progress<T>* host = NULL) : m_host(host)
|
||||
{}
|
||||
///
|
||||
/// Global progress indicator base class
|
||||
///
|
||||
/// Use to report progress of a phase or section as a part of a whole progress.
|
||||
///
|
||||
template <class T>
|
||||
class global_progress : public progress<T>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a progress indicator
|
||||
///
|
||||
/// \param[in] host Host progress indicator
|
||||
///
|
||||
global_progress(_In_opt_ progress<T>* host = NULL) : m_host(host)
|
||||
{}
|
||||
|
||||
///
|
||||
/// Attach to a host progress indicator
|
||||
///
|
||||
/// \param[in] host Host progress indicator
|
||||
///
|
||||
inline void attach(_In_opt_ progress<T>* host)
|
||||
{
|
||||
m_host = host;
|
||||
}
|
||||
///
|
||||
/// Attach to a host progress indicator
|
||||
///
|
||||
/// \param[in] host Host progress indicator
|
||||
///
|
||||
inline void attach(_In_opt_ progress<T>* host)
|
||||
{
|
||||
m_host = host;
|
||||
}
|
||||
|
||||
///
|
||||
/// Detach host progress indicator
|
||||
///
|
||||
/// \returns Old host progress indicator
|
||||
///
|
||||
inline progress<T>* detach()
|
||||
{
|
||||
progress* k = m_host;
|
||||
m_host = NULL;
|
||||
return k;
|
||||
}
|
||||
///
|
||||
/// Detach host progress indicator
|
||||
///
|
||||
/// \returns Old host progress indicator
|
||||
///
|
||||
inline progress<T>* detach()
|
||||
{
|
||||
progress* k = m_host;
|
||||
m_host = NULL;
|
||||
return k;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set global extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
inline void set_global_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_glob.start = start;
|
||||
m_glob.end = end;
|
||||
if (m_host)
|
||||
m_host->set_range(m_glob.start, m_glob.end);
|
||||
}
|
||||
///
|
||||
/// Set global extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
inline void set_global_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_glob.start = start;
|
||||
m_glob.end = end;
|
||||
if (m_host)
|
||||
m_host->set_range(m_glob.start, m_glob.end);
|
||||
}
|
||||
|
||||
///
|
||||
/// Set section extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
inline void set_section_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_odsek.start = start;
|
||||
m_odsek.end = end;
|
||||
}
|
||||
///
|
||||
/// Set section extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
inline void set_section_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_odsek.start = start;
|
||||
m_odsek.end = end;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set progress indicator text
|
||||
///
|
||||
/// \param[in] msg Text to display
|
||||
///
|
||||
virtual void set_text(_In_ const char* msg)
|
||||
{
|
||||
if (m_host)
|
||||
m_host->set_text(msg);
|
||||
}
|
||||
///
|
||||
/// Set progress indicator text
|
||||
///
|
||||
/// \param[in] msg Text to display
|
||||
///
|
||||
virtual void set_text(_In_ const char* msg)
|
||||
{
|
||||
if (m_host)
|
||||
m_host->set_text(msg);
|
||||
}
|
||||
|
||||
///
|
||||
/// Set local extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_kaz.start = start;
|
||||
m_kaz.end = end;
|
||||
}
|
||||
///
|
||||
/// Set local extend of the progress indicator
|
||||
///
|
||||
/// \param[in] start Minimum value of the progress
|
||||
/// \param[in] end Maximum value of the progress
|
||||
///
|
||||
virtual void set_range(_In_ T start, _In_ T end)
|
||||
{
|
||||
m_kaz.start = start;
|
||||
m_kaz.end = end;
|
||||
}
|
||||
|
||||
///
|
||||
/// Set local current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
if (m_host) {
|
||||
T dolzina = m_kaz.size();
|
||||
if (dolzina != 0) {
|
||||
// TODO: Implement with muldiv.
|
||||
m_host->set(((value - m_kaz.start) * m_odsek.size() / dolzina) + m_odsek.start);
|
||||
}
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Set local current progress
|
||||
///
|
||||
/// \param[in] value Current value of the progress. Must be between start and end parameters provided in set_range() call.
|
||||
///
|
||||
virtual void set(_In_ T value)
|
||||
{
|
||||
if (m_host) {
|
||||
T dolzina = m_kaz.size();
|
||||
if (dolzina != 0) {
|
||||
// TODO: Implement with muldiv.
|
||||
m_host->set(((value - m_kaz.start) * m_odsek.size() / dolzina) + m_odsek.start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Show or hide progress
|
||||
///
|
||||
/// \param[in] show Shows or hides progress indicator
|
||||
///
|
||||
virtual void show(_In_ bool show = true)
|
||||
{
|
||||
if (m_host)
|
||||
m_host->show(show);
|
||||
}
|
||||
///
|
||||
/// Show or hide progress
|
||||
///
|
||||
/// \param[in] show Shows or hides progress indicator
|
||||
///
|
||||
virtual void show(_In_ bool show = true)
|
||||
{
|
||||
if (m_host)
|
||||
m_host->show(show);
|
||||
}
|
||||
|
||||
///
|
||||
/// Query whether user requested abort
|
||||
///
|
||||
virtual bool cancel()
|
||||
{
|
||||
return m_host && m_host->cancel();
|
||||
}
|
||||
///
|
||||
/// Query whether user requested abort
|
||||
///
|
||||
virtual bool cancel()
|
||||
{
|
||||
return m_host && m_host->cancel();
|
||||
}
|
||||
|
||||
protected:
|
||||
progress* m_host;
|
||||
interval<T> m_kaz, m_glob, m_odsek;
|
||||
};
|
||||
protected:
|
||||
progress* m_host;
|
||||
interval<T> m_kaz, m_glob, m_odsek;
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2022-2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2022-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -9,408 +9,408 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
///
|
||||
/// Helper class to allow limited size FIFO queues implemented as vector of elements
|
||||
///
|
||||
template <class T>
|
||||
class vector_queue
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Type to measure element count and indices in
|
||||
///
|
||||
typedef size_t size_type;
|
||||
///
|
||||
/// Helper class to allow limited size FIFO queues implemented as vector of elements
|
||||
///
|
||||
template <class T>
|
||||
class vector_queue
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Type to measure element count and indices in
|
||||
///
|
||||
typedef size_t size_type;
|
||||
|
||||
///
|
||||
/// Element type
|
||||
///
|
||||
typedef T value_type;
|
||||
///
|
||||
/// Element type
|
||||
///
|
||||
typedef T value_type;
|
||||
|
||||
///
|
||||
/// Reference to element type
|
||||
///
|
||||
typedef T& reference;
|
||||
///
|
||||
/// Reference to element type
|
||||
///
|
||||
typedef T& reference;
|
||||
|
||||
///
|
||||
/// Constant reference to element type
|
||||
///
|
||||
typedef const T& const_reference;
|
||||
///
|
||||
/// Constant reference to element type
|
||||
///
|
||||
typedef const T& const_reference;
|
||||
|
||||
///
|
||||
/// Pointer to element
|
||||
///
|
||||
typedef T* pointer;
|
||||
///
|
||||
/// Pointer to element
|
||||
///
|
||||
typedef T* pointer;
|
||||
|
||||
///
|
||||
/// Constant pointer to element
|
||||
///
|
||||
typedef const T* const_pointer;
|
||||
///
|
||||
/// Constant pointer to element
|
||||
///
|
||||
typedef const T* const_pointer;
|
||||
|
||||
public:
|
||||
///
|
||||
/// Construct queue of fixed size.
|
||||
///
|
||||
/// \param[in] size_max Maximum number of elements. Please note this cannot be changed later.
|
||||
///
|
||||
vector_queue(_In_ size_type size_max) :
|
||||
m_data(new value_type[size_max]),
|
||||
m_head(0),
|
||||
m_count(0),
|
||||
m_size_max(size_max)
|
||||
{
|
||||
}
|
||||
public:
|
||||
///
|
||||
/// Construct queue of fixed size.
|
||||
///
|
||||
/// \param[in] size_max Maximum number of elements. Please note this cannot be changed later.
|
||||
///
|
||||
vector_queue(_In_ size_type size_max) :
|
||||
m_data(new value_type[size_max]),
|
||||
m_head(0),
|
||||
m_count(0),
|
||||
m_size_max(size_max)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies existing queue.
|
||||
///
|
||||
/// \param[in] other Queue to copy from
|
||||
///
|
||||
vector_queue(_In_ const vector_queue<value_type> &other) :
|
||||
m_data(new value_type[other.m_size_max]),
|
||||
m_head(other.m_head),
|
||||
m_count(other.m_count),
|
||||
m_size_max(other.m_size_max)
|
||||
{
|
||||
// Copy elements.
|
||||
for (size_type i = 0; i < m_count; i++) {
|
||||
size_type i_l = abs(i);
|
||||
m_data[i_l] = other.m_data[i_l];
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Copies existing queue.
|
||||
///
|
||||
/// \param[in] other Queue to copy from
|
||||
///
|
||||
vector_queue(_In_ const vector_queue<value_type> &other) :
|
||||
m_data(new value_type[other.m_size_max]),
|
||||
m_head(other.m_head),
|
||||
m_count(other.m_count),
|
||||
m_size_max(other.m_size_max)
|
||||
{
|
||||
// Copy elements.
|
||||
for (size_type i = 0; i < m_count; i++) {
|
||||
size_type i_l = abs(i);
|
||||
m_data[i_l] = other.m_data[i_l];
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Destroys the queue
|
||||
///
|
||||
virtual ~vector_queue()
|
||||
{
|
||||
if (m_data) delete [] m_data;
|
||||
}
|
||||
///
|
||||
/// Destroys the queue
|
||||
///
|
||||
virtual ~vector_queue()
|
||||
{
|
||||
if (m_data) delete [] m_data;
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves existing queue.
|
||||
///
|
||||
/// \param[inout] other Queue to move
|
||||
///
|
||||
vector_queue(_Inout_ vector_queue<value_type> &&other) :
|
||||
m_data (std::move(other.m_data )),
|
||||
m_head (std::move(other.m_head )),
|
||||
m_count (std::move(other.m_count )),
|
||||
m_size_max(std::move(other.m_size_max))
|
||||
{
|
||||
// Reset other to consistent state.
|
||||
other.m_data = NULL;
|
||||
other.m_head = 0;
|
||||
other.m_count = 0;
|
||||
other.m_size_max = 0;
|
||||
}
|
||||
///
|
||||
/// Moves existing queue.
|
||||
///
|
||||
/// \param[inout] other Queue to move
|
||||
///
|
||||
vector_queue(_Inout_ vector_queue<value_type> &&other) :
|
||||
m_data (std::move(other.m_data )),
|
||||
m_head (std::move(other.m_head )),
|
||||
m_count (std::move(other.m_count )),
|
||||
m_size_max(std::move(other.m_size_max))
|
||||
{
|
||||
// Reset other to consistent state.
|
||||
other.m_data = NULL;
|
||||
other.m_head = 0;
|
||||
other.m_count = 0;
|
||||
other.m_size_max = 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies existing queue.
|
||||
///
|
||||
/// \param[in] other Queue to copy from
|
||||
///
|
||||
vector_queue<value_type>& operator=(_In_ const vector_queue<value_type> &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_head = other.m_head;
|
||||
m_count = other.m_count;
|
||||
m_size_max = other.m_size_max;
|
||||
///
|
||||
/// Copies existing queue.
|
||||
///
|
||||
/// \param[in] other Queue to copy from
|
||||
///
|
||||
vector_queue<value_type>& operator=(_In_ const vector_queue<value_type> &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_head = other.m_head;
|
||||
m_count = other.m_count;
|
||||
m_size_max = other.m_size_max;
|
||||
|
||||
// Copy elements.
|
||||
if (m_data) delete [] m_data;
|
||||
m_data = new value_type[other.m_size_max];
|
||||
for (size_type i = 0; i < m_count; i++) {
|
||||
size_type i_l = abs(i);
|
||||
m_data[i_l] = other.m_data[i_l];
|
||||
}
|
||||
}
|
||||
// Copy elements.
|
||||
if (m_data) delete [] m_data;
|
||||
m_data = new value_type[other.m_size_max];
|
||||
for (size_type i = 0; i < m_count; i++) {
|
||||
size_type i_l = abs(i);
|
||||
m_data[i_l] = other.m_data[i_l];
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves existing queue.
|
||||
///
|
||||
/// \param[inout] other Queue to move
|
||||
///
|
||||
vector_queue<value_type>& operator=(_Inout_ vector_queue<value_type> &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_data = std::move(other.m_data );
|
||||
m_head = std::move(other.m_head );
|
||||
m_count = std::move(other.m_count );
|
||||
m_size_max = std::move(other.m_size_max);
|
||||
///
|
||||
/// Moves existing queue.
|
||||
///
|
||||
/// \param[inout] other Queue to move
|
||||
///
|
||||
vector_queue<value_type>& operator=(_Inout_ vector_queue<value_type> &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_data = std::move(other.m_data );
|
||||
m_head = std::move(other.m_head );
|
||||
m_count = std::move(other.m_count );
|
||||
m_size_max = std::move(other.m_size_max);
|
||||
|
||||
// Reset other to consistent state.
|
||||
other.m_data = NULL;
|
||||
other.m_head = 0;
|
||||
other.m_count = 0;
|
||||
other.m_size_max = 0;
|
||||
}
|
||||
// Reset other to consistent state.
|
||||
other.m_data = NULL;
|
||||
other.m_head = 0;
|
||||
other.m_count = 0;
|
||||
other.m_size_max = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the number of elements in the vector.
|
||||
///
|
||||
size_type size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
///
|
||||
/// Returns the number of elements in the vector.
|
||||
///
|
||||
size_type size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the number of elements that the queue can contain before overwriting head ones.
|
||||
///
|
||||
size_type capacity() const
|
||||
{
|
||||
return m_size_max;
|
||||
}
|
||||
///
|
||||
/// Returns the number of elements that the queue can contain before overwriting head ones.
|
||||
///
|
||||
size_type capacity() const
|
||||
{
|
||||
return m_size_max;
|
||||
}
|
||||
|
||||
///
|
||||
/// Erases the elements of the queue.
|
||||
///
|
||||
void clear()
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
///
|
||||
/// Erases the elements of the queue.
|
||||
///
|
||||
void clear()
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Tests if the queue is empty.
|
||||
///
|
||||
bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
///
|
||||
/// Tests if the queue is empty.
|
||||
///
|
||||
bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference at(_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
///
|
||||
/// Returns a reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference at(_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference operator[](_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
///
|
||||
/// Returns a reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference operator[](_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a constant reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference at(_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
///
|
||||
/// Returns a constant reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference at(_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a constant reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference operator[](_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
///
|
||||
/// Returns a constant reference to the element at a specified location in the queue.
|
||||
///
|
||||
/// \param[in] pos The subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference operator[](_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_count) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[abs(pos)];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the element at the absolute location in the queue.
|
||||
///
|
||||
/// \note Absolute means "measured from the beginning of the storage".
|
||||
///
|
||||
/// \param[in] pos The absolute subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference at_abs(_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_size_max) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[pos];
|
||||
}
|
||||
///
|
||||
/// Returns a reference to the element at the absolute location in the queue.
|
||||
///
|
||||
/// \note Absolute means "measured from the beginning of the storage".
|
||||
///
|
||||
/// \param[in] pos The absolute subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
reference at_abs(_In_ size_type pos)
|
||||
{
|
||||
if (pos >= m_size_max) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[pos];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a constant reference to the element at the absolute location in the queue: measured from the beginning of the storage.
|
||||
///
|
||||
/// \note Absolute means "measured from the beginning of the storage".
|
||||
///
|
||||
/// \param[in] pos The absolute subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference at_abs(_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_size_max) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[pos];
|
||||
}
|
||||
///
|
||||
/// Returns a constant reference to the element at the absolute location in the queue: measured from the beginning of the storage.
|
||||
///
|
||||
/// \note Absolute means "measured from the beginning of the storage".
|
||||
///
|
||||
/// \param[in] pos The absolute subscript or position number of the element to reference in the queue.
|
||||
///
|
||||
const_reference at_abs(_In_ size_type pos) const
|
||||
{
|
||||
if (pos >= m_size_max) throw std::invalid_argument("Invalid subscript");
|
||||
return m_data[pos];
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies an existing element to the end of the queue, overriding the first one when queue is out of space.
|
||||
///
|
||||
/// \param[in] v Element to copy to the end of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was copied to.
|
||||
///
|
||||
size_type push_back(_In_ const value_type &v)
|
||||
{
|
||||
if (m_count < m_size_max) {
|
||||
size_type pos = abs(m_count);
|
||||
m_data[pos] = v;
|
||||
m_count++;
|
||||
return pos;
|
||||
} else {
|
||||
size_type pos = m_head;
|
||||
m_data[pos] = v;
|
||||
m_head = abs(1);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Copies an existing element to the end of the queue, overriding the first one when queue is out of space.
|
||||
///
|
||||
/// \param[in] v Element to copy to the end of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was copied to.
|
||||
///
|
||||
size_type push_back(_In_ const value_type &v)
|
||||
{
|
||||
if (m_count < m_size_max) {
|
||||
size_type pos = abs(m_count);
|
||||
m_data[pos] = v;
|
||||
m_count++;
|
||||
return pos;
|
||||
} else {
|
||||
size_type pos = m_head;
|
||||
m_data[pos] = v;
|
||||
m_head = abs(1);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves the element to the end of the queue, overriding the first one when queue is out of space.
|
||||
///
|
||||
/// \param[in] v Element to move to the end of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was moved to.
|
||||
///
|
||||
size_type push_back(_Inout_ value_type&&v)
|
||||
{
|
||||
if (m_count < m_size_max) {
|
||||
size_type pos = abs(m_count);
|
||||
m_data[pos] = std::move(v);
|
||||
m_count++;
|
||||
return pos;
|
||||
} else {
|
||||
size_type pos = m_head;
|
||||
m_data[pos] = std::move(v);
|
||||
m_head = abs(1);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Moves the element to the end of the queue, overriding the first one when queue is out of space.
|
||||
///
|
||||
/// \param[in] v Element to move to the end of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was moved to.
|
||||
///
|
||||
size_type push_back(_Inout_ value_type&&v)
|
||||
{
|
||||
if (m_count < m_size_max) {
|
||||
size_type pos = abs(m_count);
|
||||
m_data[pos] = std::move(v);
|
||||
m_count++;
|
||||
return pos;
|
||||
} else {
|
||||
size_type pos = m_head;
|
||||
m_data[pos] = std::move(v);
|
||||
m_head = abs(1);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Removes (dequeues) the last element of the queue.
|
||||
///
|
||||
void pop_back()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
m_count--;
|
||||
}
|
||||
///
|
||||
/// Removes (dequeues) the last element of the queue.
|
||||
///
|
||||
void pop_back()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
m_count--;
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies an existing element to the head of the queue, overriding the last one when queue is out of space and moving all others one place right.
|
||||
///
|
||||
/// \param[in] v Element to copy to the head of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was copied to.
|
||||
///
|
||||
size_type push_front(_In_ const value_type &v)
|
||||
{
|
||||
m_head = abs(-1);
|
||||
if (m_count < m_size_max)
|
||||
m_count++;
|
||||
m_data[m_head] = v;
|
||||
return m_head;
|
||||
}
|
||||
///
|
||||
/// Copies an existing element to the head of the queue, overriding the last one when queue is out of space and moving all others one place right.
|
||||
///
|
||||
/// \param[in] v Element to copy to the head of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was copied to.
|
||||
///
|
||||
size_type push_front(_In_ const value_type &v)
|
||||
{
|
||||
m_head = abs(-1);
|
||||
if (m_count < m_size_max)
|
||||
m_count++;
|
||||
m_data[m_head] = v;
|
||||
return m_head;
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves the element to the head of the queue, overriding the last one when queue is out of space and moving all others one place right.
|
||||
///
|
||||
/// \param[in] v Element to move to the head of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was moved to.
|
||||
///
|
||||
size_type push_front(_Inout_ value_type&&v)
|
||||
{
|
||||
m_head = abs(-1);
|
||||
if (m_count < m_size_max)
|
||||
m_count++;
|
||||
m_data[m_head] = std::move(v);
|
||||
return m_head;
|
||||
}
|
||||
///
|
||||
/// Moves the element to the head of the queue, overriding the last one when queue is out of space and moving all others one place right.
|
||||
///
|
||||
/// \param[in] v Element to move to the head of the queue.
|
||||
///
|
||||
/// \returns The absolute subscript or position number the element was moved to.
|
||||
///
|
||||
size_type push_front(_Inout_ value_type&&v)
|
||||
{
|
||||
m_head = abs(-1);
|
||||
if (m_count < m_size_max)
|
||||
m_count++;
|
||||
m_data[m_head] = std::move(v);
|
||||
return m_head;
|
||||
}
|
||||
|
||||
///
|
||||
/// Removes (dequeues) the head element of the queue.
|
||||
///
|
||||
void pop_front()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
m_head = abs(1);
|
||||
m_count--;
|
||||
}
|
||||
///
|
||||
/// Removes (dequeues) the head element of the queue.
|
||||
///
|
||||
void pop_front()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
m_head = abs(1);
|
||||
m_count--;
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the head element in the queue.
|
||||
///
|
||||
reference front()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return m_data[m_head];
|
||||
}
|
||||
///
|
||||
/// Returns a reference to the head element in the queue.
|
||||
///
|
||||
reference front()
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return m_data[m_head];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a constant reference to the head element in the queue.
|
||||
///
|
||||
const_reference front() const
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return m_data[m_head];
|
||||
}
|
||||
///
|
||||
/// Returns a constant reference to the head element in the queue.
|
||||
///
|
||||
const_reference front() const
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return m_data[m_head];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the last element in the queue.
|
||||
///
|
||||
reference back()
|
||||
{
|
||||
return m_data[tail()];
|
||||
}
|
||||
///
|
||||
/// Returns a reference to the last element in the queue.
|
||||
///
|
||||
reference back()
|
||||
{
|
||||
return m_data[tail()];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a constant reference to the last element in the queue.
|
||||
///
|
||||
const_reference back() const
|
||||
{
|
||||
return m_data[tail()];
|
||||
}
|
||||
///
|
||||
/// Returns a constant reference to the last element in the queue.
|
||||
///
|
||||
const_reference back() const
|
||||
{
|
||||
return m_data[tail()];
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns absolute subscript or position number of the head element in the queue. The element does not need to exist.
|
||||
///
|
||||
size_type head() const
|
||||
{
|
||||
return m_head;
|
||||
}
|
||||
///
|
||||
/// Returns absolute subscript or position number of the head element in the queue. The element does not need to exist.
|
||||
///
|
||||
size_type head() const
|
||||
{
|
||||
return m_head;
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns absolute subscript or position number of the last element in the queue. The element must exist.
|
||||
///
|
||||
size_type tail() const
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return abs(m_count - 1);
|
||||
}
|
||||
///
|
||||
/// Returns absolute subscript or position number of the last element in the queue. The element must exist.
|
||||
///
|
||||
size_type tail() const
|
||||
{
|
||||
if (!m_count) throw std::invalid_argument("Empty storage");
|
||||
return abs(m_count - 1);
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns absolute subscript or position number of the given element in the queue.
|
||||
///
|
||||
size_type abs(_In_ size_type pos) const
|
||||
{
|
||||
return (m_head + pos) % m_size_max;
|
||||
}
|
||||
///
|
||||
/// Returns absolute subscript or position number of the given element in the queue.
|
||||
///
|
||||
size_type abs(_In_ size_type pos) const
|
||||
{
|
||||
return (m_head + pos) % m_size_max;
|
||||
}
|
||||
|
||||
protected:
|
||||
value_type *m_data; ///< Underlying data container
|
||||
size_type m_head; ///< Index of the first element
|
||||
size_type m_count; ///< Number of elements
|
||||
size_type m_size_max; ///< Maximum size
|
||||
};
|
||||
protected:
|
||||
value_type *m_data; ///< Underlying data container
|
||||
size_type m_head; ///< Index of the first element
|
||||
size_type m_count; ///< Number of elements
|
||||
size_type m_size_max; ///< Maximum size
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user