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

Emulating __uint128_t

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

Problem

I developed a lot of code locally with __uint128_t only to find out that it is not available on the target platform.

I am now trying to write my own struct that emulates the operators of __uint128_t I need: =, ~, ^, &, |, ^=, &=, |=

This is the code I have now, which will be compiled with a C++11 compiler:

struct board_t {
    uint64_t hi;
    uint64_t low;    

    board_t operator~() const {
        return {~hi, ~low};
    }

    board_t operator|(const board_t & rhs) const {
        return {hi | rhs.hi, low | rhs.low};
    }

    board_t& operator|=(const board_t & rhs) {
        hi |= rhs.hi;
        low |= rhs.low;

        return *this;
    }

    // Complete equivalent functions for &, ^, &= ^=
};


  • Will anything behave unexpectedly with this code?



  • Do I need to create a constructor? Is the usage of the {} struct initializer good form?



  • Do I need to override the assignment operator?



  • Are there other ways to improve this code, style, correctness and speed?

Solution

Will anything behave unexpectedly with this code?

For that to answer we would need the expectations. Most users will expect a number type to behave like the ints do.

What does that mean in your example?

  • your type should be usable in an if(number) (this also includes if(!number))



  • your type should be comparable with other int types, nobody wants to write number == board_t{0, 3} instead of number == 3 (this probably means you should write an implicit conversion from int to board_t



Surely there are other things you need to mimic from the ints.

Do I need to create a constructor? Is the usage of the {} struct initializer good form?

Given the fact that you should provide something like board_t(int) you will need to provide the other constructors as well.

Internal functions (that know about the internal format of board_t might use the "struct initialize" but in general I would avoid it as it introduces dependencies on the inner layout.

Do I need to override the assignment operator?

No, the default generated one will simply call the assignments on the members as well which is fine.

Are there other ways to improve this code, style, correctness and speed?

Yes:

  • why is the type called board_t?



  • if the user should be able to supply values you could generate an own literal for this purpose



  • define binary operators like operator+ outside the class to get "more symmetric" code (this makes both operands eligible for automatic conversions instead of only the right hand side)



  • the previous point may also be applied for unary operators that don't change the internal representation of the object (like operator~())



All in all your design should be:

If the platform supports uint128 the type should only be an alias of it and if it does not support this type, then your class should behave as much as uint128 as possible (so on platforms that support it your code should do the same for both "implementations").

Context

StackExchange Code Review Q#60778, answer score: 4

Revisions (0)

No revisions yet.