Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/wlib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
project(wlib)

file (GLOB header_files
"Wlib.h"
"strings/*.h"
"stl/*.h"
"memory/*.h")
"Wlib.h"
"strings/*.h"
"stl/*.h"
"memory/*.h")

file (GLOB source_files
"memory/*.cpp")
"memory/*.cpp")

set(HEADER_FILES ${header_files} )
set(SOURCE_FILES ${source_files})
Expand Down
9 changes: 4 additions & 5 deletions lib/wlib/Wlib.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#ifndef EMBEDDEDTESTS_WLIB_H
#define EMBEDDEDTESTS_WLIB_H

#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })

#define max(x, y) (((x) > (y)) ? (x) : (y))
#define min(x, y) (((x) < (y)) ? (x) : (y))

#define BYTE_SIZE 8
#define INT_SIZE (BYTE_SIZE * sizeof(uint32_t))

#endif //EMBEDDEDTESTS_WLIB_H
190 changes: 128 additions & 62 deletions lib/wlib/stl/Bitset.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,149 +17,215 @@
#include <stdint.h>
#include <math.h>

#include "Wlib.h"

namespace wlp {
#define NO_OF_BITS (8 * sizeof(unsigned int))

template<uint8_t bits>
/**
* Computes the mask corresponding to the number of bits
* or the exponent in the from 2^n - 1.
* @tparam exp the number of bits, 32 or less
*/
template<uint8_t exp>
struct pow_mask {
static const uint32_t value = (uint32_t) ((1 << exp) - 1);
};

/**
* Template specialization for 32 bits to
* prevent overflow.
*/
template<> struct pow_mask<32> {
static const uint32_t value = 0xffffffff;
};

/**
* Compute the minimum number of integers
* needed to store a certain number of bits.
* @tparam nBits the bits to store
*/
template<uint8_t nBits>
struct ceil_bits {
static const uint32_t value = (nBits + INT_SIZE - 1) / INT_SIZE;
};

template<uint8_t nBits>
class Bitset {
public:
/**
* Default Constructor creates an empty bitset
* Default Constructor creates an empty bitset.
*/
Bitset() {
memset(m_array, 0, sizeof(m_array));
}

/**
* Constructor creates a bitset from a number that can be of max
* 64 bit in size
* Constructor creates a bitset from a number that
* can be of max 64 bit in size.
*
* @param number the number to create bitset from
* @param n the number to create bitset from
*/
explicit Bitset(uint64_t number){
memset(m_array, 0, sizeof(m_array));

uint16_t size = sizeof(number) * 8;
explicit Bitset(uint64_t n) {
setFromNumber(n);
}

if (size > bits) size = bits;
/**
* Copy constructor.
* @param b Bitset to copy
*/
Bitset(Bitset<nBits>& b) {
uint32_t end = ceil_bits<nBits>::value;
for (uint16_t i = 0; i < end; i++) {
m_array[i] = (m_array[i] & 0) | b.m_array[i];
}
}

for (uint16_t index = 0; index < size; ++index) {
uint8_t remainder = (uint8_t) (number % 2);
number /= 2;
/**
* Copy constructor for const.
* @param b Bitset to copy
*/
Bitset(const Bitset<nBits>& b) {
uint32_t end = ceil_bits<nBits>::value;
for (uint16_t i = 0; i < end; i++) {
m_array[i] = (m_array[i] & 0) | b.m_array[i];
}
}

if (remainder) set(index);
else reset(index);
/**
* Set the value of the Bitset from a number
* of maximum 64 bit size.
* @param n the number to set from
*/
void setFromNumber(uint64_t n) {
memset(m_array, 0, sizeof(m_array));
constexpr uint32_t end = nBits / INT_SIZE;
constexpr uint32_t extra = nBits - end * INT_SIZE;
for (uint16_t i = 0; i < end; ++i) {
m_array[i] = (uint32_t) n;
n >>= INT_SIZE;
}
if (extra) {
m_array[end] = ((uint32_t) n) & pow_mask<extra>::value;
}
}


/**
* Sets the bit at @code index to be true
* Sets the bit at @code index to be true.
*
* @param index the index of the bit
*/
void set(uint16_t index) {
m_array[index / NO_OF_BITS] |= (1U << (index % NO_OF_BITS));
m_array[index / INT_SIZE] |= (1U << (index % INT_SIZE));
}

/**
* Sets the bit at @code index to be false
* Sets the bit at @code index to be false.
*
* @param index the index of the bit
*/
void reset(uint16_t index) {
m_array[index / NO_OF_BITS] &= ~(1U << (index % NO_OF_BITS));
m_array[index / INT_SIZE] &= ~(1U << (index % INT_SIZE));
}

/**
* Toggles the but at @code index
* Toggles the but at @code index.
*
* @param index the index of the bit
*/
void flip(uint16_t index) {
m_array[index / NO_OF_BITS] ^= (1U << (index % NO_OF_BITS));
m_array[index / INT_SIZE] ^= (1U << (index % INT_SIZE));
}

/**
* Returns the value of bit at @code index
* Returns the value of bit at @code index.
*
* @param index the index of the bit
* @return the bit value
*/
bool test(uint16_t index) {
return (m_array[index / NO_OF_BITS] & (1U << (index % NO_OF_BITS))) != 0;
bool test(uint16_t index) const {
return (m_array[index / INT_SIZE] & (1U << (index % INT_SIZE))) != 0;
}

/**
* Converts the bits into 64 bit unsigned integer
*
* @return unsigned 64 bit integer
*/
uint64_t to_uint64_t() {
uint64_t number = 0;

for (uint8_t i = 0; i < 64; ++i) {
uint64_t powerVal = (uint64_t) ceil(pow(2, i));
uint8_t bitVal = (uint8_t) test(i);
number += bitVal * powerVal;
uint64_t to_uint64_t() const {
if (nBits <= 32) {
return to_uint32_t();
}

return number;
return (((uint64_t) m_array[1]) << INT_SIZE) | ((uint32_t) m_array[0]);
}

/**
* Converts the bits into 32 bit unsigned integer
*
* @return unsigned 32 bit integer
*/
uint32_t to_uint32_t() {
uint32_t number = 0;

for (uint8_t i = 0; i < 32; ++i) {
uint32_t powerVal = (uint32_t) ceil(pow(2, i));
uint8_t bitVal = (uint8_t) test(i);
number += bitVal * powerVal;
}

return number;
uint32_t to_uint32_t() const {
return (uint32_t) m_array[0];
}

/**
* Converts the bits into 16 bit unsigned integer
*
* @return unsigned 16 bit integer
*/
uint16_t to_uint16_t() {
uint16_t number = 0;

for (uint8_t i = 0; i < 16; ++i) {
uint16_t powerVal = (uint16_t) ceil(pow(2, i));
uint8_t bitVal = (uint8_t) test(i);
number += bitVal * powerVal;
}

return number;
uint16_t to_uint16_t() const {
return (uint16_t) (m_array[0] & pow_mask<16>::value);
}

/**
* Converts the bits into 8 bit unsigned integer
*
* @return unsigned 8 bit integer
*/
uint8_t to_uint8_t() {
uint8_t number = 0;
uint8_t to_uint8_t() const {
return (uint8_t) (m_array[0] & pow_mask<8>::value);
}

for (uint8_t i = 0; i < 8; ++i) {
uint8_t powerVal = (uint8_t) ceil(pow(2, i));
uint8_t bitVal = (uint8_t) test(i);
number += bitVal * powerVal;
/**
* Access operator returns the bit at the given position.
* @param i the position of the bit to test
* @return the value of the bit
*/
bool operator[](const uint16_t i) const {
return test(i);
}

/**
* Assignment operator copies the contents of the bitset.
* @param b Bitset to assign
*/
Bitset<nBits>& operator=(Bitset<nBits>& b) {
uint32_t end = ceil_bits<nBits>::value;
for (uint16_t i = 0; i < end; i++) {
m_array[i] = (m_array[i] & 0) | b.m_array[i];
}
return *this;
}

return number;
/**
* Assignment operator copies the contents of the bitset.
* @param b Bitset to assign
*/
Bitset<nBits>& operator=(const Bitset<nBits>& b) {
uint32_t end = ceil_bits<nBits>::value;
for (uint16_t i = 0; i < end; i++) {
m_array[i] = (m_array[i] & 0) | b.m_array[i];
}
return *this;
}

private:
int m_array[bits/ NO_OF_BITS];
/**
* Backing array of integers that contain the bites.
* Integer type arrays generally have the fastest access
* times in C++.
*/
uint32_t m_array[ceil_bits<nBits>::value];
};
}

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include_directories(${WLIB_INCLUDE_DIR})

file(GLOB files
"test.cpp"
"stl/*.cpp"
"strings/*.cpp")

add_executable(tests ${files})
Expand Down
Loading