HiveBrain v1.2.0
Get Started
← Back to all entries
debugcppMinor

A template-fixed-size unsigned integer class

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
templatesizeunsignedfixedclassinteger

Problem

For some reason or another, I want to have available unsigned integers of sizes other than 1, 2, 4 and 8 (e.g. an unsigned integer with 3 bytes). For most platforms, compilers don't make those available; so - I rolled my own.

Other than asking for a general review, I will also pose a few specific questions / requests for guidance.

```
#ifndef UINT_H_
#define UINT_H_

#include
#include
#include
#include
#include // for memcpy and memset

namespace util {

/**
* A hopefully-fast integer-like class with arbitrary size
*
* @note Heavily dependent on compiler optimizations...
* @note For now, assumes little-endianness
* @note For now, limited to small sizes
*
*/
template
class uint_t final
{
static_assert(N ::fast;
using least_builtin_type = typename boost::int_t::least;

protected: // data members
value_type value; // Note it is _not_ necessarily aligned

public: // constructors
uint_t() noexcept = default;
uint_t(const uint_t& x) noexcept = default;
uint_t(uint_t&& x) noexcept = default;

protected: // building blocks for converting ctors, assignments and conversion operators

/ The next two methods are buggy, see @Deduplicator's answer /
template
uint_t& assign (I x) noexcept
{
if (sizeof(I)
I as_integer() const noexcept
{
I result;
if (sizeof(I)
uint_t& assign(I x) noexcept
{
auto x_bytes = (const byte* const) &x;

for (auto j = 0; j
I as_integer() const noexcept
{
I result;

if (sizeof(I) > N) { result = 0; }

auto result_bytes = (byte* const) &result;
for (auto j = 0; j (x); }
uint_t(signed char x) noexcept { assign(x); }
uint_t(unsigned char x) noexcept { assign(x); }
uint_t(short x) noexcept { assign(x); }
uint_t(unsigned short x) noexcept { assign(x); }
uint_t(int x) noexcept { assign(x); }
uint_t(unsigned x) noexcept { assig

Solution

There is only ever a reason to have a move-ctor / move-assignment if that is more efficient than copy-ctor / copy-assignment, or the only one of the two which is valid.

.assign is wrong.

You probably want to zero non-assigned bytes, and copy assigned bytes.

Currently, you zero and then overwrite some bytes and access out-of-bounds if the source is smaller than the destination.

You might want to write normal de- and en-coding code which has the same codepaths for little- as for big-endian.

// Example:
unsigned in;
unsigned char out[4];
for(int i = 0; i >= 8;
}

Code Snippets

// Example:
unsigned in;
unsigned char out[4];
for(int i = 0; i < 4; i++) {
    out[i] = in & 0xff;
    in >>= 8;
}

Context

StackExchange Code Review Q#151543, answer score: 2

Revisions (0)

No revisions yet.