2

I'm working on a structure that uses std::bitset and it looks like this:

Register.h

#pragma once

#include <bitset>
#include <vector> // used for typedefs of int types

namespace vpc { // virtual pc

    typedef std::int8_t  i8;
    typedef std::int16_t i16;
    typedef std::int32_t i32;
    typedef std::int64_t i64;

    const unsigned int BYTE  = 0x08;
    const unsigned int WORD  = 0x10;
    const unsigned int DWORD = 0x20;
    const unsigned int QWORD = 0x40;

    typedef std::bitset<BYTE>  Byte;
    typedef std::bitset<WORD>  Word;
    typedef std::bitset<DWORD> DWord;
    typedef std::bitset<QWORD> QWord;

    template<std::uint64_t N = BYTE>
    struct Register {
        Byte register_;

        Register() {
            static_assert(
                // assert 8 <= N <= 64
                ((N%8) == 0) && (N >=8) && (N <= 64) &&
                // and N != 24,40,48 and 56
                (N != 24) && (N != 40) && (N != 48) && (N != 56)
            ); 
        }
    }

    template<>
    struct Register<WORD> {
        Word register_;
        Register() = default;
     };

     template<>
     struct Register<DWORD> {
         DWord register_;
         Register() = default;
     }

     template<>
     struct Register<QWORD> {
         QWord register_;
         Register() = default;
     }

} // namespace vpc

Then I use this small program to write some values to the register class and to print them to the screen:

main.cpp

#include <iostream>
#include "Register.h"

int main() {
    using namespace vpc;

    Register r1;
    r1.register_ = 169;

    std::cout << "Stored Value\n";
std::cout << r1.register_ << "\n";
// 10101001 // printed value;

std::cout << "Bit Values\n";
for (i16 i = 0; i < 8; i++) {
    std::cout << r1.register_[i] << ' ';
}
std::cout << "\n\n";
// 1 0 0 1 0 1 0 1 // printed bit values

// using std::bitset.flip()
r1.register_.flip();
std::cout << "Flipped Bit Values\n";
for (i16 i = 0; i < 8; i++) {
    std::cout << r1.register_[i] << ' ';
}
std::cout << "\n\n";
// 0 1 1 0 1 0 1 0 // printed bit values    

    return EXIT_SUCCESS;
}

There is nothing wrong with the code above, however the flip is not exactly want I want. It is good to know that it is there and what it does but if we closely look at the output:

Output

Stored Value
10101001

Bit Values
1 0 0 1 0 1 0 1

Flipped Bit Values
0 1 1 0 1 0 1 0

The flip function is not want I want here. I'd like to reverse the stored bit order and save it back into itself or to create a copy of it. I'd like to be able to have a byte with bits: 0111 0011 that is stored and be able to generate either a copy or saved back to itself a byte with value 1100 1110 and not 1000 1100.

I don't see any functions that belong to std::bitset that does this, are there any other options from the std library? Or would I have to write my own? If so I'm not quite sure how to implement it with simplicity and efficiency in mind.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • 1
    What you're looking for is `rotation`. That is not supported by `std::bitset`. You have to write your own. It has been solved on SO before [Overload the shift operators of std::bitset](https://stackoverflow.com/questions/47452703/overload-the-shift-operators-of-stdbitset) – Croolman May 06 '19 at 04:41

1 Answers1

2

I don't know of a single algorithm that does this but you can use a combination of bitset::to_string and std::reverse to do this.

A minimal example.

#include "Register.h"
#include <algorithm>
#include <bitset>
#include <iostream>
#include <string>

int main() {
  vpc::Byte register_ = 169;
  std::cout << register_ << std::endl;

  auto str = register_.to_string();
  std::reverse(str.begin(), str.end());
  auto x = vpc::Byte(str);
  std::cout << x << std::endl;

  return 0;
}

See Demo Here.

Output:

10101001
10010101

This method can be used with any of the other bitset types you have defined.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • 1
    Wow so simple too; I knew you was able to convert a bitset to either an int or string and never thought about using string's reverse() function then storing that back into a bitset. – Francis Cugler May 06 '19 at 05:24
  • I made a stand alone function template that takes a Register does the bit manipulation and then stores it back into itself. I can do a similar function that will take the value but returns back a copy. This can be very useful as I'm planning on using these structs as the basis of registers in a virtual pc. – Francis Cugler May 06 '19 at 05:35