From 3ee5abf74b00be7206fa581bb4ce4f1222486d42 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 12 Aug 2022 13:39:24 +0100 Subject: [PATCH] Work in progress --- include/etl/bitset.h | 1454 +--------------- include/etl/private/bitset_legacy.h | 1494 ++++++++++++++++ include/etl/private/bitset_new.h | 1540 +++++++++++++++++ test/CMakeLists.txt | 3 +- test/UnitTest++/CheckMacros.h | 58 +- test/UnitTest++/Checks.h | 24 + test/sanity-check/bitset_legacy.h.t.cpp | 29 + .../{bitset.h.t.cpp => bitset_new.h.t.cpp} | 4 +- test/sanity-check/c++03/CMakeLists.txt | 3 +- test/sanity-check/c++11/CMakeLists.txt | 3 +- test/sanity-check/c++14/CMakeLists.txt | 3 +- test/sanity-check/c++17/CMakeLists.txt | 3 +- ...test_bitset.cpp => test_bitset_legacy.cpp} | 4 +- test/test_bitset_new.cpp | 1390 +++++++++++++++ test/vs2019/etl.vcxproj | 36 +- test/vs2019/etl.vcxproj.filters | 19 +- 16 files changed, 4597 insertions(+), 1470 deletions(-) create mode 100644 include/etl/private/bitset_legacy.h create mode 100644 include/etl/private/bitset_new.h create mode 100644 test/sanity-check/bitset_legacy.h.t.cpp rename test/sanity-check/{bitset.h.t.cpp => bitset_new.h.t.cpp} (94%) rename test/{test_bitset.cpp => test_bitset_legacy.cpp} (99%) create mode 100644 test/test_bitset_new.cpp diff --git a/include/etl/bitset.h b/include/etl/bitset.h index 65990fde..d827c762 100644 --- a/include/etl/bitset.h +++ b/include/etl/bitset.h @@ -31,1460 +31,12 @@ SOFTWARE. #ifndef ETL_BITSET_INCLUDED #define ETL_BITSET_INCLUDED -#include -#include -#include - #include "platform.h" -#include "algorithm.h" -#include "iterator.h" - -#include "integral_limits.h" -#include "algorithm.h" -#include "nullptr.h" -#include "log.h" -#include "exception.h" -#include "integral_limits.h" -#include "binary.h" -#include "char_traits.h" -#include "static_assert.h" -#include "error_handler.h" -#include "span.h" -#include "string.h" - -#include "private/minmax_push.h" - -#if defined(ETL_COMPILER_KEIL) -#pragma diag_suppress 1300 -#endif - -#if ETL_USING_CPP11 - #define ETL_STR(x) x - #define ETL_STRL(x) L##x - #define ETL_STRu(x) u##x - #define ETL_STRU(x) U##x +#if defined(ETL_USE_LEGACY_BITSET) + #include "private/bitset_legacy.h" #else - #define ETL_STR(x) x - #define ETL_STRL(x) x - #define ETL_STRu(x) x - #define ETL_STRU(x) x + #include "private/bitset_new.h" #endif -//***************************************************************************** -///\defgroup bitset bitset -/// Similar to std::bitset but without requiring std::string. -///\ingroup containers -//***************************************************************************** - -namespace etl -{ - //*************************************************************************** - /// Exception base for bitset - ///\ingroup bitset - //*************************************************************************** - class bitset_exception : public etl::exception - { - public: - - bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset null pointer exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_nullptr : public bitset_exception - { - public: - - bitset_nullptr(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset type_too_small exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_type_too_small : public bitset_exception - { - public: - - bitset_type_too_small(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset overflow exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_overflow : public bitset_exception - { - public: - - bitset_overflow(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_) - { - } - }; - - //************************************************************************* - /// The base class for etl::bitset - ///\ingroup bitset - //************************************************************************* - class ibitset - { - protected: - - // The type used for each element in the array. -#if !defined(ETL_BITSET_ELEMENT_TYPE) - typedef uint_least8_t element_t; -#else - typedef ETL_BITSET_ELEMENT_TYPE element_t; -#endif - - public: - - static ETL_CONSTANT element_t ALL_SET = etl::integral_limits::max; - static ETL_CONSTANT element_t ALL_CLEAR = 0; - - static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; - -#if ETL_USING_CPP11 - typedef etl::span span_type; - typedef etl::span const_span_type; -#endif - - enum - { - npos = etl::integral_limits::max - }; - - //************************************************************************* - /// The reference type returned. - //************************************************************************* - class bit_reference - { - public: - - friend class ibitset; - - //******************************* - /// Conversion operator. - //******************************* - operator bool() const - { - return p_bitset->test(position); - } - - //******************************* - /// Assignment operator. - //******************************* - bit_reference& operator = (bool b) - { - p_bitset->set(position, b); - return *this; - } - - //******************************* - /// Assignment operator. - //******************************* - bit_reference& operator = (const bit_reference& r) - { - p_bitset->set(position, bool(r)); - return *this; - } - - //******************************* - /// Flip the bit. - //******************************* - bit_reference& flip() - { - p_bitset->flip(position); - return *this; - } - - //******************************* - /// Return the logical inverse of the bit. - //******************************* - bool operator~() const - { - return !p_bitset->test(position); - } - - private: - - //******************************* - /// Default constructor. - //******************************* - bit_reference() - : p_bitset(ETL_NULLPTR) - , position(0) - { - } - - //******************************* - /// Constructor. - //******************************* - bit_reference(ibitset& r_bitset, size_t position_) - : p_bitset(&r_bitset) - , position(position_) - { - } - - ibitset* p_bitset; ///< The bitset. - size_t position; ///< The position in the bitset. - }; - - //************************************************************************* - /// The number of bits in the bitset. - //************************************************************************* - size_t size() const - { - return Total_Bits; - } - - //************************************************************************* - /// Count the number of bits set. - //************************************************************************* - size_t count() const - { - size_t n = 0UL; - - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - n += etl::count_bits(pdata[i]); - } - - return n; - } - - //************************************************************************* - /// Tests a bit at a position. - /// Positions greater than the number of configured bits will return false. - //************************************************************************* - bool test(size_t position) const - { - size_t index; - element_t mask; - - if (Number_Of_Elements == 0) - { - return false; - } - else if (Number_Of_Elements == 1) - { - index = 0; - mask = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - mask = element_t(1) << (position & (Bits_Per_Element - 1)); - } - - return (pdata[index] & mask) != 0; - } - - //************************************************************************* - /// Set all bits. - //************************************************************************* - ibitset& set() - { - ::memset(pdata, 0xFF, Number_Of_Elements); - pdata[Number_Of_Elements - 1U] = Top_Mask; - - return *this; - } - - //************************************************************************* - /// Set the bit at the position. - //************************************************************************* - ibitset& set(size_t position, bool value = true) - { - size_t index; - element_t bit; - - if (Number_Of_Elements == 0) - { - return *this; - } - else if (Number_Of_Elements == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - bit = element_t(1) << (position & (Bits_Per_Element - 1)); - } - - if (value) - { - pdata[index] |= bit; - } - else - { - pdata[index] &= ~bit; - } - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - ibitset& from_string(const char* text) - { - reset(); - - size_t i = etl::min(Total_Bits, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRL('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a wide string. - //************************************************************************* - ibitset& from_string(const wchar_t* text) - { - reset(); - - size_t i = etl::min(Total_Bits, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRL('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a u16 string. - //************************************************************************* - ibitset& from_string(const char16_t* text) - { - reset(); - - size_t i = etl::min(Total_Bits, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRu('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a u32 string. - //************************************************************************* - ibitset& from_string(const char32_t* text) - { - reset(); - - size_t i = etl::min(Total_Bits, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRU('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - ibitset& set(const char* text) - { - from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a wstring. - //************************************************************************* - ibitset& set(const wchar_t* text) - { - from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u16string. - //************************************************************************* - ibitset& set(const char16_t* text) - { - from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u32string. - //************************************************************************* - ibitset& set(const char32_t* text) - { - from_string(text); - - return *this; - } - - //************************************************************************* - /// Put to a value. - //************************************************************************* - template - typename etl::enable_if::value, T>::type - value() const - { - for (size_t i = sizeof(long long) / sizeof(element_t); i < Number_Of_Elements; ++i) - { - ETL_ASSERT_AND_RETURN_VALUE(!(pdata[i]), ETL_ERROR(etl::bitset_overflow), T(0)); - } - - T v = T(0); - - const bool OK = (sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element); - - ETL_ASSERT_AND_RETURN_VALUE(OK, ETL_ERROR(etl::bitset_type_too_small), T(0)); - - if (OK) - { - uint_least8_t shift = 0U; - - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - v |= T(typename etl::make_unsigned::type(pdata[i]) << shift); - shift += uint_least8_t(Bits_Per_Element); - } - } - - return v; - } - - //************************************************************************* - /// Put to a unsigned long. - //************************************************************************* - unsigned long to_ulong() const - { - return value(); - } - - //************************************************************************* - /// Put to a unsigned long long. - //************************************************************************* - unsigned long long to_ullong() const - { - return value(); - } - - //************************************************************************* - /// Resets the bitset. - //************************************************************************* - ibitset& reset() - { - ::memset(pdata, 0x00, Number_Of_Elements); - - return *this; - } - - //************************************************************************* - /// Reset the bit at the position. - //************************************************************************* - ibitset& reset(size_t position) - { - size_t index; - element_t bit; - - if (Number_Of_Elements == 0) - { - return *this; - } - else if (Number_Of_Elements == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - bit = element_t(1) << (position & (Bits_Per_Element - 1)); - } - - pdata[index] &= ~bit; - - return *this; - } - - //************************************************************************* - /// Flip all of the bits. - //************************************************************************* - ibitset& flip() - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - pdata[i] = ~pdata[i]; - } - - adjust_top_bits(); - - return *this; - } - - //************************************************************************* - /// Flip the bit at the position. - //************************************************************************* - ibitset& flip(size_t position) - { - if (position < Total_Bits) - { - size_t index; - element_t bit; - - if (Number_Of_Elements == 0) - { - return *this; - } - else if (Number_Of_Elements == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> log2::value; - bit = element_t(1) << (position & (Bits_Per_Element - 1)); - } - - pdata[index] ^= bit; - } - - return *this; - } - - //************************************************************************* - // Are all the bits sets? - //************************************************************************* - bool all() const - { - if (Number_Of_Elements == 0UL) - { - return true; - } - - // All but the last. - for (size_t i = 0UL; i < (Number_Of_Elements - 1U); ++i) - { - if (pdata[i] != ALL_SET) - { - return false; - } - } - - // The last. - if (pdata[Number_Of_Elements - 1U] != (ALL_SET & Top_Mask)) - { - return false; - } - - return true; - } - - //************************************************************************* - /// Are any of the bits set? - //************************************************************************* - bool any() const - { - return !none(); - } - - //************************************************************************* - /// Are none of the bits set? - //************************************************************************* - bool none() const - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - if (pdata[i] != 0) - { - return false; - } - } - - return true; - } - - //************************************************************************* - /// Finds the first bit in the specified state. - ///\param state The state to search for. - ///\returns The position of the bit or Number_Of_Elements if none were found. - //************************************************************************* - size_t find_first(bool state) const - { - return find_next(state, 0); - } - - //************************************************************************* - /// Finds the next bit in the specified state. - ///\param state The state to search for. - ///\param position The position to start from. - ///\returns The position of the bit or ibitset::npos if none were found. - //************************************************************************* - size_t find_next(bool state, size_t position) const - { - // Where to start. - size_t index; - size_t bit; - - if (Number_Of_Elements == 0) - { - return ibitset::npos; - } - else if (Number_Of_Elements == 1) - { - index = 0; - bit = position; - } - else - { - index = position >> log2::value; - bit = position & (Bits_Per_Element - 1); - } - - element_t mask = 1 << bit; - - // For each element in the bitset... - while (index < Number_Of_Elements) - { - element_t value = pdata[index]; - - // Needs checking? - if ((state && (value != ALL_CLEAR)) || - (!state && (value != ALL_SET))) - { - // For each bit in the element... - while ((bit < Bits_Per_Element) && (position < Total_Bits)) - { - // Equal to the required state? - if (((value & mask) != 0) == state) - { - return position; - } - - // Move on to the next bit. - mask <<= 1; - ++position; - ++bit; - } - } - else - { - position += (Bits_Per_Element - bit); - } - - // Start at the beginning for all other elements. - bit = 0; - mask = 1; - - ++index; - } - - return ibitset::npos; - } - - //************************************************************************* - /// Read [] operator. - //************************************************************************* - bool operator[] (size_t position) const - { - return test(position); - } - - //************************************************************************* - /// Write [] operator. - //************************************************************************* - bit_reference operator [] (size_t position) - { - return bit_reference(*this, position); - } - - //************************************************************************* - /// operator &= - //************************************************************************* - ibitset& operator &=(const ibitset& other) - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - pdata[i] &= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator |= - //************************************************************************* - ibitset& operator |=(const ibitset& other) - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - pdata[i] |= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator ^= - //************************************************************************* - ibitset& operator ^=(const ibitset& other) - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - pdata[i] ^= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator <<= - //************************************************************************* - ibitset& operator<<=(size_t shift) - { - if (shift >= Total_Bits) - { - reset(); - } - else if (Number_Of_Elements != 0UL) - { - // Just one element? - if (Number_Of_Elements == 1UL) - { - pdata[0] <<= shift; - } - else if (shift == Bits_Per_Element) - { - etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements); - pdata[0] = 0; - } - else - { - // Where we are shifting from. - int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U); - const size_t src_position = Bits_Per_Element - (shift % Bits_Per_Element); - - // Where we are shifting to. - int dst_index = int(Number_Of_Elements - 1U); - - // Shift control constants. - const size_t lsb_shift = Bits_Per_Element - src_position; - const size_t msb_shift = src_position; - - const element_t lsb_mask = element_t(etl::integral_limits::max >> (Bits_Per_Element - src_position)); - const element_t msb_mask = etl::integral_limits::max - lsb_mask; - const element_t lsb_shifted_mask = element_t(lsb_mask << lsb_shift); - - // First lsb. - element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); - pdata[dst_index] = lsb; - --src_index; - - // Now do the shifting. - while (src_index >= 0) - { - // Shift msb. - element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); - pdata[dst_index] = pdata[dst_index] | msb; - --dst_index; - - // Shift lsb. - element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); - pdata[dst_index] = lsb; - --src_index; - } - - // Clear the remaining bits. - // First lsb. - pdata[dst_index] &= lsb_shifted_mask; - --dst_index; - - // The other remaining bytes on the right. - while (dst_index >= 0) - { - pdata[dst_index] = 0; - --dst_index; - } - } - - // Truncate any bits shifted to the left. - adjust_top_bits(); - } - - return *this; - } - - //************************************************************************* - /// operator >>= - //************************************************************************* - ibitset& operator>>=(size_t shift) - { - if (shift >= Total_Bits) - { - reset(); - } - else if (Number_Of_Elements != 0UL) - { - // Just one element? - if (Number_Of_Elements == 1UL) - { - pdata[0] >>= shift; - } - // Shift is the size of an element? - else if (shift == Bits_Per_Element) - { - etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata); - pdata[Number_Of_Elements - 1U] = 0; - } - else - { - // Where we are shifting from. - int src_index = int(shift / Bits_Per_Element); - const size_t src_position = shift % Bits_Per_Element; - - // Where we are shifting to. - int dst_index = 0; - - // Shift control constants. - const size_t lsb_shift = Bits_Per_Element - src_position; - const size_t msb_shift = src_position; - - const element_t lsb_mask = element_t(etl::integral_limits::max >> (Bits_Per_Element - src_position)); - const element_t msb_mask = etl::integral_limits::max - lsb_mask; - const element_t msb_shifted_mask = element_t(msb_mask >> msb_shift); - - // Now do the shifting. - while (src_index < int(Number_Of_Elements - 1)) - { - // Shift msb. - element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); - ++src_index; - - // Shift lsb. - element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); - - // Combine them. - pdata[dst_index] = lsb | msb; - ++dst_index; - } - - // Final msb. - element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); - pdata[dst_index] = msb; - - // Clear the remaining bits. - // First msb. - pdata[dst_index] &= msb_shifted_mask; - ++dst_index; - - // The other remaining bytes. - while (dst_index < int(Number_Of_Elements)) - { - pdata[dst_index] = 0; - ++dst_index; - } - } - } - - return *this; - } - - //************************************************************************* - /// operator = - //************************************************************************* - ibitset& operator =(const ibitset& other) - { - if (this != &other) - { - etl::copy_n(other.pdata, Number_Of_Elements, pdata); - } - - return *this; - } - - //************************************************************************* - /// swap - //************************************************************************* - void swap(ibitset& other) - { - etl::swap_ranges(pdata, pdata + Number_Of_Elements, other.pdata); - } - -#if ETL_USING_CPP11 - //************************************************************************* - /// span - /// Returns a span of the underlying data. - //************************************************************************* - span_type span() - { - return span_type(pdata, pdata + Number_Of_Elements); - } - - //************************************************************************* - /// span - /// Returns a const span of the underlying data. - //************************************************************************* - const_span_type span() const - { - return const_span_type(pdata, pdata + Number_Of_Elements); - } -#endif - - protected: - - //************************************************************************* - /// Initialise from an unsigned long long. - //************************************************************************* - ibitset& initialise(unsigned long long value) - { - reset(); - - const size_t Shift = (integral_limits::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element; - - // Can we do it in one hit? - if (Shift == 0) - { - pdata[0] = element_t(value); - } - else - { - size_t i = 0UL; - - while ((value != 0) && (i < Number_Of_Elements)) - { - pdata[i++] = value & ALL_SET; - value = value >> Shift; - } - } - - adjust_top_bits(); - - return *this; - } - - //************************************************************************* - /// Invert - //************************************************************************* - void invert() - { - for (size_t i = 0UL; i < Number_Of_Elements; ++i) - { - pdata[i] = ~pdata[i]; - } - - adjust_top_bits(); - } - - //************************************************************************* - /// Gets a reference to the specified bit. - //************************************************************************* - bit_reference get_bit_reference(size_t position) - { - return bit_reference(*this, position); - } - - //************************************************************************* - /// Constructor. - //************************************************************************* - ibitset(size_t nbits_, size_t size_, element_t* pdata_) - : Total_Bits(nbits_) - , Number_Of_Elements(size_) - , pdata(pdata_) - { - const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element; - const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Total_Bits)) % Bits_Per_Element); - Top_Mask = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); - } - - //************************************************************************* - /// Compare bitsets. - //************************************************************************* - static bool is_equal(const ibitset& lhs, const ibitset&rhs) - { - return etl::equal(lhs.pdata, lhs.pdata + lhs.Number_Of_Elements, rhs.pdata); - } - - element_t Top_Mask; - - private: - - //************************************************************************* - /// Correct the unused top bits after bit manipulation. - //************************************************************************* - void adjust_top_bits() - { - pdata[Number_Of_Elements - 1U] &= Top_Mask; - } - - // Disable copy construction. - ibitset(const ibitset&); - - const size_t Total_Bits; - const size_t Number_Of_Elements; - element_t* pdata; - - //************************************************************************* - /// Destructor. - //************************************************************************* -#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS) - public: - virtual ~ibitset() - { - } -#else - protected: - ~ibitset() - { - } -#endif - }; - - //************************************************************************* - /// The class emulates an array of bool elements, but optimized for space allocation. - /// Will accommodate any number of bits. - /// Does not use std::string. - ///\tparam MaxN The number of bits. - ///\ingroup bitset - //************************************************************************* - template - class bitset : public etl::ibitset - { - - static ETL_CONSTANT size_t Array_Size = (MaxN % Bits_Per_Element == 0) ? MaxN / Bits_Per_Element : MaxN / Bits_Per_Element + 1; - - public: - - static ETL_CONSTANT size_t ALLOCATED_BITS = Array_Size * Bits_Per_Element; - - public: - - //************************************************************************* - /// Default constructor. - //************************************************************************* - bitset() - : etl::ibitset(MaxN, Array_Size, data) - { - reset(); - } - - //************************************************************************* - /// Copy constructor. - //************************************************************************* - bitset(const bitset& other) - : etl::ibitset(MaxN, Array_Size, data) - { - etl::copy_n(other.data, Array_Size, data); - } - - //************************************************************************* - /// Construct from a value. - //************************************************************************* - bitset(unsigned long long value) - : etl::ibitset(MaxN, Array_Size, data) - { - initialise(value); - } - - //************************************************************************* - /// Construct from a string. - //************************************************************************* - bitset(const char* text) - : etl::ibitset(MaxN, Array_Size, data) - { - set(text); - } - - //************************************************************************* - /// Construct from a string. - //************************************************************************* - bitset(const wchar_t* text) - : etl::ibitset(MaxN, Array_Size, data) - { - set(text); - } - - //************************************************************************* - /// Construct from a string. - //************************************************************************* - bitset(const char16_t* text) - : etl::ibitset(MaxN, Array_Size, data) - { - set(text); - } - - //************************************************************************* - /// Construct from a string. - //************************************************************************* - bitset(const char32_t* text) - : etl::ibitset(MaxN, Array_Size, data) - { - set(text); - } - - //************************************************************************* - /// Set all of the bits. - //************************************************************************* - bitset& set() - { - etl::ibitset::set(); - return *this; - } - - //************************************************************************* - /// Set the bit at the position. - //************************************************************************* - bitset& set(size_t position, bool value = true) - { - etl::ibitset::set(position, value); - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& set(const char* text) - { - ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); - etl::ibitset::set(text); - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& set(const wchar_t* text) - { - ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); - etl::ibitset::set(text); - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& set(const char16_t* text) - { - ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); - etl::ibitset::set(text); - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& set(const char32_t* text) - { - ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); - etl::ibitset::set(text); - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& from_string(const char* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a wide string. - //************************************************************************* - bitset& from_string(const wchar_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u16 string. - //************************************************************************* - bitset& from_string(const char16_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u32 string. - //************************************************************************* - bitset& from_string(const char32_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Put to a value. - //************************************************************************* - template - typename etl::enable_if::value, T>::type - value() const - { - ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Array_Size * Bits_Per_Element), "Type too small"); - - return ibitset::value(); - } - - //************************************************************************* - /// Reset all of the bits. - //************************************************************************* - bitset& reset() - { - ibitset::reset(); - return *this; - } - - //************************************************************************* - /// Reset the bit at the position. - //************************************************************************* - bitset& reset(size_t position) - { - etl::ibitset::reset(position); - return *this; - } - - //************************************************************************* - /// Flip all of the bits. - //************************************************************************* - bitset& flip() - { - ibitset::flip(); - return *this; - } - - //************************************************************************* - /// Flip the bit at the position. - //************************************************************************* - bitset& flip(size_t position) - { - etl::ibitset::flip(position); - return *this; - } - - //************************************************************************* - /// Returns a string representing the bitset. - //************************************************************************* -#if ETL_USING_CPP11 - template > -#else - template -#endif - TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const - { - TString result; - - result.resize(MaxN, '\0'); - - ETL_ASSERT_AND_RETURN_VALUE((result.size() == MaxN), ETL_ERROR(etl::bitset_overflow), result); - - for (size_t i = MaxN; i > 0; --i) - { - result[MaxN - i] = test(i - 1) ? one : zero; - } - - return result; - } - - //************************************************************************* - /// operator = - //************************************************************************* - bitset& operator =(const bitset& other) - { - if (this != &other) - { - etl::copy_n(other.data, Array_Size, data); - } - - return *this; - } - - //************************************************************************* - /// operator &= - //************************************************************************* - bitset& operator &=(const bitset& other) - { - etl::ibitset::operator &=(other); - return *this; - } - - //************************************************************************* - /// operator |= - //************************************************************************* - bitset& operator |=(const bitset& other) - { - etl::ibitset::operator |=(other); - return *this; - } - - //************************************************************************* - /// operator ^= - //************************************************************************* - bitset& operator ^=(const bitset& other) - { - ibitset::operator ^=(other); - return *this; - } - - //************************************************************************* - /// operator ~ - //************************************************************************* - bitset operator ~() const - { - etl::bitset temp(*this); - - temp.invert(); - - return temp; - } - - //************************************************************************* - /// operator << - //************************************************************************* - bitset operator<<(size_t shift) const - { - etl::bitset temp(*this); - - temp <<= shift; - - return temp; - } - - //************************************************************************* - /// operator <<= - //************************************************************************* - bitset& operator<<=(size_t shift) - { - etl::ibitset::operator <<=(shift); - return *this; - } - - //************************************************************************* - /// operator >> - //************************************************************************* - bitset operator>>(size_t shift) const - { - bitset temp(*this); - - temp >>= shift; - - return temp; - } - - //************************************************************************* - /// operator >>= - //************************************************************************* - bitset& operator>>=(size_t shift) - { - etl::ibitset::operator >>=(shift); - return *this; - } - - //************************************************************************* - /// operator == - //************************************************************************* - friend bool operator == (const bitset& lhs, const bitset& rhs) - { - return etl::ibitset::is_equal(lhs, rhs); - } - - private: - - element_t data[Array_Size > 0U ? Array_Size : 1U]; - }; - - //*************************************************************************** - /// operator & - ///\ingroup bitset - //*************************************************************************** - template - bitset operator & (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp &= rhs; - return temp; - } - - //*************************************************************************** - /// operator | - ///\ingroup bitset - //*************************************************************************** - template - bitset operator | (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp |= rhs; - return temp; - } - - //*************************************************************************** - /// operator ^ - ///\ingroup bitset - //*************************************************************************** - template - bitset operator ^ (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp ^= rhs; - return temp; - } - - //*************************************************************************** - /// operator != - ///\ingroup bitset - //*************************************************************************** - template - bool operator != (const bitset& lhs, const bitset& rhs) - { - return !(lhs == rhs); - } -} - -//************************************************************************* -/// swap -//************************************************************************* -template -void swap(etl::bitset& lhs, etl::bitset& rhs) -{ - lhs.swap(rhs); -} - -#include "private/minmax_pop.h" - #endif diff --git a/include/etl/private/bitset_legacy.h b/include/etl/private/bitset_legacy.h new file mode 100644 index 00000000..64d010aa --- /dev/null +++ b/include/etl/private/bitset_legacy.h @@ -0,0 +1,1494 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_BITSET_LEGACY_INCLUDED +#define ETL_BITSET_LEGACY_INCLUDED + +#include +#include +#include + +#include "../platform.h" +#include "../algorithm.h" +#include "../iterator.h" +#include "../integral_limits.h" +#include "../algorithm.h" +#include "../nullptr.h" +#include "../log.h" +#include "../exception.h" +#include "../integral_limits.h" +#include "../binary.h" +#include "../char_traits.h" +#include "../static_assert.h" +#include "../error_handler.h" +#include "../span.h" +#include "../string.h" + +#include "minmax_push.h" + +#if defined(ETL_COMPILER_KEIL) +#pragma diag_suppress 1300 +#endif + +#if ETL_USING_CPP11 + #define ETL_STR(x) x + #define ETL_STRL(x) L##x + #define ETL_STRu(x) u##x + #define ETL_STRU(x) U##x +#else + #define ETL_STR(x) x + #define ETL_STRL(x) x + #define ETL_STRu(x) x + #define ETL_STRU(x) x +#endif + +//***************************************************************************** +///\defgroup bitset bitset +/// Similar to std::bitset but without requiring std::string. +///\ingroup containers +//***************************************************************************** + +namespace etl +{ + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset null pointer exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_nullptr : public bitset_exception + { + public: + + bitset_nullptr(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset type_too_small exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_type_too_small : public bitset_exception + { + public: + + bitset_type_too_small(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset overflow exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_overflow : public bitset_exception + { + public: + + bitset_overflow(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_) + { + } + }; + + //************************************************************************* + /// The base class for etl::bitset + ///\ingroup bitset + //************************************************************************* + class ibitset + { + protected: + + // The type used for each element in the array. +#if !defined(ETL_BITSET_ELEMENT_TYPE) + typedef uint_least8_t element_t; +#else + typedef typename etl::make_unsigned::type element_t; +#endif + + public: + + static ETL_CONSTANT element_t ALL_SET = etl::integral_limits::max; + static ETL_CONSTANT element_t ALL_CLEAR = 0; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + +#if ETL_USING_CPP11 + typedef etl::span span_type; + typedef etl::span const_span_type; +#endif + + enum + { + npos = etl::integral_limits::max + }; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class ibitset; + + //******************************* + /// Conversion operator. + //******************************* + operator bool() const + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + bit_reference& operator = (bool b) + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + bit_reference& operator = (const bit_reference& r) + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + bit_reference& flip() + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + bool operator~() const + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + bit_reference() + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + bit_reference(ibitset& r_bitset, size_t position_) + : p_bitset(&r_bitset) + , position(position_) + { + } + + ibitset* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + size_t size() const + { + return Total_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + size_t count() const + { + size_t n = 0UL; + + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + n += etl::count_bits(pdata[i]); + } + + return n; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + bool test(size_t position) const + { + size_t index; + element_t mask; + + if (Number_Of_Elements == 0) + { + return false; + } + else if (Number_Of_Elements == 1) + { + index = 0; + mask = element_t(1) << position; + } + else + { + index = position >> etl::log2::value; + mask = element_t(1) << (position & (Bits_Per_Element - 1)); + } + + return (pdata[index] & mask) != 0; + } + + //************************************************************************* + /// Set all bits. + //************************************************************************* + ibitset& set() + { + ::memset(pdata, 0xFF, Number_Of_Elements); + pdata[Number_Of_Elements - 1U] = Top_Mask; + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ibitset& set(size_t position, bool value = true) + { + size_t index; + element_t bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_t(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_t(1) << (position & (Bits_Per_Element - 1)); + } + + if (value) + { + pdata[index] |= bit; + } + else + { + pdata[index] &= ~bit; + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ibitset& from_string(const char* text) + { + reset(); + + size_t i = etl::min(Total_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRL('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ibitset& from_string(const wchar_t* text) + { + reset(); + + size_t i = etl::min(Total_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRL('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ibitset& from_string(const char16_t* text) + { + reset(); + + size_t i = etl::min(Total_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRu('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ibitset& from_string(const char32_t* text) + { + reset(); + + size_t i = etl::min(Total_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRU('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ibitset& set(const char* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a wstring. + //************************************************************************* + ibitset& set(const wchar_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u16string. + //************************************************************************* + ibitset& set(const char16_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u32string. + //************************************************************************* + ibitset& set(const char32_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Put to a value. + //************************************************************************* + template + typename etl::enable_if::value, T>::type + value() const + { + for (size_t i = sizeof(long long) / sizeof(element_t); i < Number_Of_Elements; ++i) + { + ETL_ASSERT_AND_RETURN_VALUE(!(pdata[i]), ETL_ERROR(etl::bitset_overflow), T(0)); + } + + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element); + + ETL_ASSERT_AND_RETURN_VALUE(OK, ETL_ERROR(etl::bitset_type_too_small), T(0)); + + if (OK) + { + uint_least8_t shift = 0U; + + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + v |= T(typename etl::make_unsigned::type(pdata[i]) << shift); + shift += uint_least8_t(Bits_Per_Element); + } + } + + return v; + } + + //************************************************************************* + /// Put to a unsigned long. + //************************************************************************* + unsigned long to_ulong() const + { + return value(); + } + + //************************************************************************* + /// Put to a unsigned long long. + //************************************************************************* + unsigned long long to_ullong() const + { + return value(); + } + + //************************************************************************* + /// Resets the bitset. + //************************************************************************* + ibitset& reset() + { + ::memset(pdata, 0x00, Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ibitset& reset(size_t position) + { + size_t index; + element_t bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_t(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_t(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] &= ~bit; + + return *this; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ibitset& flip() + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] = ~pdata[i]; + } + + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ibitset& flip(size_t position) + { + if (position < Total_Bits) + { + size_t index; + element_t bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_t(1) << position; + } + else + { + index = position >> log2::value; + bit = element_t(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] ^= bit; + } + + return *this; + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + bool all() const + { + if (Number_Of_Elements == 0UL) + { + return true; + } + + // All but the last. + for (size_t i = 0UL; i < (Number_Of_Elements - 1U); ++i) + { + if (pdata[i] != ALL_SET) + { + return false; + } + } + + // The last. + if (pdata[Number_Of_Elements - 1U] != (ALL_SET & Top_Mask)) + { + return false; + } + + return true; + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + bool any() const + { + return !none(); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + bool none() const + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + if (pdata[i] != 0) + { + return false; + } + } + + return true; + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or Number_Of_Elements if none were found. + //************************************************************************* + size_t find_first(bool state) const + { + return find_next(state, 0); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or ibitset::npos if none were found. + //************************************************************************* + size_t find_next(bool state, size_t position) const + { + // Where to start. + size_t index; + size_t bit; + + if (Number_Of_Elements == 0) + { + return ibitset::npos; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = position; + } + else + { + index = position >> log2::value; + bit = position & (Bits_Per_Element - 1); + } + + element_t mask = 1 << bit; + + // For each element in the bitset... + while (index < Number_Of_Elements) + { + element_t value = pdata[index]; + + // Needs checking? + if ((state && (value != ALL_CLEAR)) || + (!state && (value != ALL_SET))) + { + // For each bit in the element... + while ((bit < Bits_Per_Element) && (position < Total_Bits)) + { + // Equal to the required state? + if (((value & mask) != 0) == state) + { + return position; + } + + // Move on to the next bit. + mask <<= 1; + ++position; + ++bit; + } + } + else + { + position += (Bits_Per_Element - bit); + } + + // Start at the beginning for all other elements. + bit = 0; + mask = 1; + + ++index; + } + + return ibitset::npos; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + bool operator[] (size_t position) const + { + return test(position); + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + bit_reference operator [] (size_t position) + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ibitset& operator &=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] &= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ibitset& operator |=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] |= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ibitset& operator ^=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] ^= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ibitset& operator<<=(size_t shift) + { + if (shift >= Total_Bits) + { + reset(); + } + else if (Number_Of_Elements != 0UL) + { + // Just one element? + if (Number_Of_Elements == 1UL) + { + pdata[0] <<= shift; + } + else if (shift == Bits_Per_Element) + { + etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements); + pdata[0] = 0; + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); + + // Where we are shifting from. + int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U); + + // Where we are shifting to. + int dst_index = int(Number_Of_Elements - 1U); + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_t lsb_mask = element_t(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_t msb_mask = etl::integral_limits::max - lsb_mask; + const element_t lsb_shifted_mask = element_t(lsb_mask << lsb_shift); + + // First lsb. + element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + + // Now do the shifting. + while (src_index >= 0) + { + // Shift msb. + element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); + pdata[dst_index] = pdata[dst_index] | msb; + --dst_index; + + // Shift lsb. + element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + } + + // Clear the remaining bits. + // First lsb. + pdata[dst_index] &= lsb_shifted_mask; + --dst_index; + + // The other remaining bytes on the right. + while (dst_index >= 0) + { + pdata[dst_index] = 0; + --dst_index; + } + } + + // Truncate any bits shifted to the left. + clear_unused_bits_in_msb(); + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ibitset& operator>>=(size_t shift) + { + if (shift >= Total_Bits) + { + reset(); + } + else if (Number_Of_Elements != 0UL) + { + // Just one element? + if (Number_Of_Elements == 1UL) + { + pdata[0] >>= shift; + } + // Shift is the size of an element? + else if (shift == Bits_Per_Element) + { + etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata); + pdata[Number_Of_Elements - 1U] = 0; + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = shift % Bits_Per_Element; + + // Where we are shifting from. + int src_index = int(shift / Bits_Per_Element); + + // Where we are shifting to. + int dst_index = 0; + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_t lsb_mask = element_t(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_t msb_mask = etl::integral_limits::max - lsb_mask; + const element_t msb_shifted_mask = element_t(msb_mask >> msb_shift); + + // Now do the shifting. + while (src_index < int(Number_Of_Elements - 1)) + { + // Shift msb. + element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); + ++src_index; + + // Shift lsb. + element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift); + + // Combine them. + pdata[dst_index] = lsb | msb; + ++dst_index; + } + + // Final msb. + element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift); + pdata[dst_index] = msb; + + // Clear the remaining bits. + // First msb. + pdata[dst_index] &= msb_shifted_mask; + ++dst_index; + + // The other remaining bytes. + while (dst_index < int(Number_Of_Elements)) + { + pdata[dst_index] = 0; + ++dst_index; + } + } + } + + return *this; + } + + //************************************************************************* + /// operator = + //************************************************************************* + ibitset& operator =(const ibitset& other) + { + if (this != &other) + { + etl::copy_n(other.pdata, Number_Of_Elements, pdata); + } + + return *this; + } + + //************************************************************************* + /// swap + //************************************************************************* + void swap(ibitset& other) + { + etl::swap_ranges(pdata, pdata + Number_Of_Elements, other.pdata); + } + +#if ETL_USING_CPP11 + //************************************************************************* + /// span + /// Returns a span of the underlying data. + //************************************************************************* + span_type span() + { + return span_type(pdata, pdata + Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying data. + //************************************************************************* + const_span_type span() const + { + return const_span_type(pdata, pdata + Number_Of_Elements); + } +#endif + + protected: + + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ibitset& initialise(unsigned long long value) + { + reset(); + + const size_t Shift = (integral_limits::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element; + + // Can we do it in one hit? + if (Shift == 0) + { + pdata[0] = element_t(value); + } + else + { + size_t i = 0UL; + + while ((value != 0) && (i < Number_Of_Elements)) + { + pdata[i++] = value & ALL_SET; + value = value >> Shift; + } + } + + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Invert + //************************************************************************* + void invert() + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] = ~pdata[i]; + } + + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Gets a reference to the specified bit. + //************************************************************************* + bit_reference get_bit_reference(size_t position) + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Constructor. + //************************************************************************* + ibitset(size_t nbits_, size_t size_, element_t* pdata_) + : Total_Bits(nbits_) + , Number_Of_Elements(size_) + , pdata(pdata_) + { + const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element; + const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Total_Bits)) % Bits_Per_Element); + Top_Mask = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); + } + + //************************************************************************* + /// Compare bitsets. + //************************************************************************* + static bool is_equal(const ibitset& lhs, const ibitset&rhs) + { + return etl::equal(lhs.pdata, lhs.pdata + lhs.Number_Of_Elements, rhs.pdata); + } + + element_t Top_Mask; + + private: + + //************************************************************************* + /// Correct the unused top bits after bit manipulation. + //************************************************************************* + void clear_unused_bits_in_msb() + { + pdata[Number_Of_Elements - 1U] &= Top_Mask; + } + + // Disable copy construction. + ibitset(const ibitset&); + + const size_t Total_Bits; + const size_t Number_Of_Elements; + element_t* pdata; + + //************************************************************************* + /// Destructor. + //************************************************************************* +#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS) + public: + virtual ~ibitset() + { + } +#else + protected: + ~ibitset() + { + } +#endif + }; + + //************************************************************************* + /// The class emulates an array of bool elements, but optimized for space allocation. + /// Will accommodate any number of bits. + /// Does not use std::string. + ///\tparam MaxN The number of bits. + ///\ingroup bitset + //************************************************************************* + template + class bitset : public etl::ibitset + { + + static ETL_CONSTANT size_t Array_Size = (MaxN % Bits_Per_Element == 0) ? MaxN / Bits_Per_Element : MaxN / Bits_Per_Element + 1; + + public: + + static ETL_CONSTANT size_t ALLOCATED_BITS = Array_Size * Bits_Per_Element; + static ETL_CONSTANT size_t Allocated_Bits = ALLOCATED_BITS; + + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + bitset() + : etl::ibitset(MaxN, Array_Size, data) + { + reset(); + } + + //************************************************************************* + /// Copy constructor. + //************************************************************************* + bitset(const bitset& other) + : etl::ibitset(MaxN, Array_Size, data) + { + etl::copy_n(other.data, Array_Size, data); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + bitset(unsigned long long value) + : etl::ibitset(MaxN, Array_Size, data) + { + initialise(value); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const wchar_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char16_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char32_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + bitset& set() + { + etl::ibitset::set(); + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + bitset& set(size_t position, bool value = true) + { + etl::ibitset::set(position, value); + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const wchar_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char16_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char32_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& from_string(const char* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + bitset& from_string(const wchar_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + bitset& from_string(const char16_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + bitset& from_string(const char32_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Put to a value. + //************************************************************************* + template + typename etl::enable_if::value, T>::type + value() const + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Array_Size * Bits_Per_Element), "Type too small"); + + return ibitset::value(); + } + + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + bitset& reset() + { + ibitset::reset(); + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + bitset& reset(size_t position) + { + etl::ibitset::reset(position); + return *this; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + bitset& flip() + { + ibitset::flip(); + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + bitset& flip(size_t position) + { + etl::ibitset::flip(position); + return *this; + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const + { + TString result; + + result.resize(MaxN, '\0'); + + ETL_ASSERT_AND_RETURN_VALUE((result.size() == MaxN), ETL_ERROR(etl::bitset_overflow), result); + + for (size_t i = MaxN; i > 0; --i) + { + result[MaxN - i] = test(i - 1) ? one : zero; + } + + return result; + } + + //************************************************************************* + /// operator = + //************************************************************************* + bitset& operator =(const bitset& other) + { + if (this != &other) + { + etl::copy_n(other.data, Array_Size, data); + } + + return *this; + } + + //************************************************************************* + /// operator &= + //************************************************************************* + bitset& operator &=(const bitset& other) + { + etl::ibitset::operator &=(other); + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + bitset& operator |=(const bitset& other) + { + etl::ibitset::operator |=(other); + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + bitset& operator ^=(const bitset& other) + { + ibitset::operator ^=(other); + return *this; + } + + //************************************************************************* + /// operator ~ + //************************************************************************* + bitset operator ~() const + { + etl::bitset temp(*this); + + temp.invert(); + + return temp; + } + + //************************************************************************* + /// operator << + //************************************************************************* + bitset operator<<(size_t shift) const + { + etl::bitset temp(*this); + + temp <<= shift; + + return temp; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + bitset& operator<<=(size_t shift) + { + etl::ibitset::operator <<=(shift); + return *this; + } + + //************************************************************************* + /// operator >> + //************************************************************************* + bitset operator>>(size_t shift) const + { + bitset temp(*this); + + temp >>= shift; + + return temp; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + bitset& operator>>=(size_t shift) + { + etl::ibitset::operator >>=(shift); + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend bool operator == (const bitset& lhs, const bitset& rhs) + { + return etl::ibitset::is_equal(lhs, rhs); + } + + private: + + element_t data[Array_Size > 0U ? Array_Size : 1U]; + }; + + //*************************************************************************** + /// operator & + ///\ingroup bitset + //*************************************************************************** + template + bitset operator & (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp &= rhs; + return temp; + } + + //*************************************************************************** + /// operator | + ///\ingroup bitset + //*************************************************************************** + template + bitset operator | (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp |= rhs; + return temp; + } + + //*************************************************************************** + /// operator ^ + ///\ingroup bitset + //*************************************************************************** + template + bitset operator ^ (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp ^= rhs; + return temp; + } + + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + bool operator != (const bitset& lhs, const bitset& rhs) + { + return !(lhs == rhs); + } +} + +//************************************************************************* +/// swap +//************************************************************************* +template +void swap(etl::bitset& lhs, etl::bitset& rhs) +{ + lhs.swap(rhs); +} + +#include "minmax_pop.h" + +#endif diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h new file mode 100644 index 00000000..2a406a6e --- /dev/null +++ b/include/etl/private/bitset_new.h @@ -0,0 +1,1540 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_BITSET_NEW_INCLUDED +#define ETL_BITSET_NEW_INCLUDED + +#include +#include +#include + +#include "../platform.h" +#include "../algorithm.h" +#include "../iterator.h" +#include "../integral_limits.h" +#include "../algorithm.h" +#include "../nullptr.h" +#include "../log.h" +#include "../exception.h" +#include "../integral_limits.h" +#include "../binary.h" +#include "../char_traits.h" +#include "../static_assert.h" +#include "../error_handler.h" +#include "../span.h" +#include "../string.h" + +#include "minmax_push.h" + +#if defined(ETL_COMPILER_KEIL) +#pragma diag_suppress 1300 +#endif + +#if ETL_USING_CPP11 + #define ETL_STR(x) x + #define ETL_STRL(x) L##x + #define ETL_STRu(x) u##x + #define ETL_STRU(x) U##x +#else + #define ETL_STR(x) x + #define ETL_STRL(x) x + #define ETL_STRu(x) x + #define ETL_STRU(x) x +#endif + +//***************************************************************************** +///\defgroup bitset bitset +/// Similar to std::bitset but without requiring std::string. +///\ingroup containers +//***************************************************************************** + +namespace etl +{ + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset null pointer exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_nullptr : public bitset_exception + { + public: + + bitset_nullptr(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset type_too_small exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_type_too_small : public bitset_exception + { + public: + + bitset_type_too_small(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset overflow exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_overflow : public bitset_exception + { + public: + + bitset_overflow(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_) + { + } + }; + + //************************************************************************* + /// The base class for etl::bitset + ///\ingroup bitset + //************************************************************************* + template + class ibitset + { + protected: + + typedef typename etl::make_unsigned::type element_type; + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + static ETL_CONSTANT element_type All_Set = etl::integral_limits::type>::max; + static ETL_CONSTANT element_type All_Clear = element_type(0); + +#if ETL_USING_CPP11 + typedef etl::span span_type; + typedef etl::span const_span_type; +#endif + + enum + { + npos = etl::integral_limits::max + }; + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count(const_pointer pdata, size_t Number_Of_Elements) const + { + size_t n = 0UL; + + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + n += etl::count_bits(pdata[i]); + } + + return n; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(const_pointer pdata, size_t Number_Of_Elements, size_t position) const + { + size_t index = 0U; + element_type mask = element_type(0); + + if (Number_Of_Elements == 0) + { + return false; + } + else if (Number_Of_Elements == 1) + { + index = 0; + mask = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + mask = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + return (pdata[index] & mask) != 0; + } + + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pdata, size_t Number_Of_Elements, size_t position, bool value = true) + { + size_t index = 0; + element_type bit = 0; + + if (Number_Of_Elements == 0) + { + return; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + if (value) + { + pdata[index] |= bit; + } + else + { + pdata[index] &= ~bit; + } + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + void from_string(pointer pdata, size_t number_of_elements, size_t total_bits, const char* text) + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pdata[element_index++] = All_Clear; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pdata, number_of_elements, --i, *text++ == ETL_STR('1')); + } + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + void from_string(pointer pdata, size_t number_of_elements, size_t total_bits, const wchar_t* text) + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pdata[element_index++] = All_Clear; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pdata, number_of_elements, --i, *text++ == ETL_STRL('1')); + } + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + void from_string(pointer pdata, size_t number_of_elements, size_t total_bits, const char16_t* text) + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pdata[element_index++] = All_Clear; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pdata, number_of_elements, --i, *text++ == ETL_STRu('1')); + } + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + void from_string(pointer pdata, size_t number_of_elements, size_t total_bits, const char32_t* text) + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pdata[element_index++] = All_Clear; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pdata, number_of_elements, --i, *text++ == ETL_STRU('1')); + } + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pdata, size_t number_of_elements, size_t total_bits, const char* text) + { + from_string(pdata, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a wstring. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pdata, size_t number_of_elements, size_t total_bits, const wchar_t* text) + { + from_string(pdata, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a u16string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pdata, size_t number_of_elements, size_t total_bits, const char16_t* text) + { + from_string(pdata, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a u32string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pdata, size_t number_of_elements, size_t total_bits, const char32_t* text) + { + from_string(pdata, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Get as a value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value(const_pointer pdata, size_t number_of_elements) const + { + for (size_t i = sizeof(long long) / sizeof(element_type); i < number_of_elements; ++i) + { + ETL_ASSERT_AND_RETURN_VALUE(!(pdata[i]), ETL_ERROR(etl::bitset_overflow), T(0)); + } + + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= (number_of_elements * Bits_Per_Element); + + ETL_ASSERT_AND_RETURN_VALUE(OK, ETL_ERROR(etl::bitset_type_too_small), T(0)); + + if (OK) + { + uint_least8_t shift = 0U; + + for (size_t i = 0UL; i < number_of_elements; ++i) + { + v |= T(typename etl::make_unsigned::type(pdata[i]) << shift); + shift += uint_least8_t(Bits_Per_Element); + } + } + + return v; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void reset(pointer pdata, size_t number_of_elements, size_t position) + { + size_t index = 0U; + element_type bit = element_type(0); + + if (number_of_elements == 0) + { + return; + } + else if (number_of_elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] &= ~bit; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 void flip(pointer pdata, size_t number_of_elements) + { + for (size_t i = 0UL; i < number_of_elements; ++i) + { + pdata[i] = ~pdata[i]; + } + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void flip(pointer pdata, size_t number_of_elements, size_t total_bits, size_t position) + { + if (position < total_bits) + { + size_t index = 0U; + element_type bit = element_type(0); + + if (number_of_elements == 0) + { + return; + } + else if (number_of_elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] ^= bit; + } + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all(const_pointer pdata, size_t number_of_elements, element_type top_mask) const ETL_NOEXCEPT + { + if (number_of_elements == 0UL) + { + return true; + } + + // All but the last. + for (size_t i = 0UL; i < (number_of_elements - 1U); ++i) + { + if (pdata[i] != All_Set) + { + return false; + } + } + + // The last. + if (pdata[number_of_elements - 1U] != (All_Set & top_mask)) + { + return false; + } + + return true; + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none(const_pointer pdata, size_t number_of_elements) const ETL_NOEXCEPT + { + for (size_t i = 0UL; i < number_of_elements; ++i) + { + if (pdata[i] != 0) + { + return false; + } + } + + return true; + } +// +// //************************************************************************* +// /// Finds the first bit in the specified state. +// ///\param state The state to search for. +// ///\returns The position of the bit or Number_Of_Elements if none were found. +// //************************************************************************* +// size_t find_first(bool state) const +// { +// return find_next(state, 0); +// } +// +// //************************************************************************* +// /// Finds the next bit in the specified state. +// ///\param state The state to search for. +// ///\param position The position to start from. +// ///\returns The position of the bit or etl::ibitset::npos if none were found. +// //************************************************************************* +// size_t find_next(bool state, size_t position) const +// { +// // Where to start. +// size_t index; +// size_t bit; +// +// if (Number_Of_Elements == 0) +// { +// return etl::ibitset::npos; +// } +// else if (Number_Of_Elements == 1) +// { +// index = 0; +// bit = position; +// } +// else +// { +// index = position >> log2::value; +// bit = position & (Bits_Per_Element - 1); +// } +// +// element_type mask = 1 << bit; +// +// // For each element in the bitset... +// while (index < Number_Of_Elements) +// { +// element_type value = pdata[index]; +// +// // Needs checking? +// if ((state && (value != ALL_CLEAR)) || +// (!state && (value != ALL_SET))) +// { +// // For each bit in the element... +// while ((bit < Bits_Per_Element) && (position < Total_Bits)) +// { +// // Equal to the required state? +// if (((value & mask) != 0) == state) +// { +// return position; +// } +// +// // Move on to the next bit. +// mask <<= 1; +// ++position; +// ++bit; +// } +// } +// else +// { +// position += (Bits_Per_Element - bit); +// } +// +// // Start at the beginning for all other elements. +// bit = 0; +// mask = 1; +// +// ++index; +// } +// +// return etl::ibitset::npos; +// } +// + +// +// //************************************************************************* +// /// operator &= +// //************************************************************************* +// ibitset& operator &=(const ibitset& other) +// { +// for (size_t i = 0UL; i < Number_Of_Elements; ++i) +// { +// pdata[i] &= other.pdata[i]; +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator |= +// //************************************************************************* +// ibitset& operator |=(const ibitset& other) +// { +// for (size_t i = 0UL; i < Number_Of_Elements; ++i) +// { +// pdata[i] |= other.pdata[i]; +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator ^= +// //************************************************************************* +// ibitset& operator ^=(const ibitset& other) +// { +// for (size_t i = 0UL; i < Number_Of_Elements; ++i) +// { +// pdata[i] ^= other.pdata[i]; +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator <<= +// //************************************************************************* +// ibitset& operator<<=(size_t shift) +// { +// if (shift >= Total_Bits) +// { +// reset(); +// } +// else if (Number_Of_Elements != 0UL) +// { +// // Just one element? +// if (Number_Of_Elements == 1UL) +// { +// pdata[0] <<= shift; +// } +// else if (shift == Bits_Per_Element) +// { +// etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements); +// pdata[0] = 0; +// } +// else +// { +// // The place where the elements are split when shifting. +// const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); +// +// // Where we are shifting from. +// int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U); +// +// // Where we are shifting to. +// int dst_index = int(Number_Of_Elements - 1U); +// +// // Shift control constants. +// const size_t lsb_shift = Bits_Per_Element - split_position; +// const size_t msb_shift = split_position; +// +// const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); +// const element_type msb_mask = etl::integral_limits::max - lsb_mask; +// const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift); +// +// // First lsb. +// element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); +// pdata[dst_index] = lsb; +// --src_index; +// +// // Now do the shifting. +// while (src_index >= 0) +// { +// // Shift msb. +// element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); +// pdata[dst_index] = pdata[dst_index] | msb; +// --dst_index; +// +// // Shift lsb. +// element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); +// pdata[dst_index] = lsb; +// --src_index; +// } +// +// // Clear the remaining bits. +// // First lsb. +// pdata[dst_index] &= lsb_shifted_mask; +// --dst_index; +// +// // The other remaining bytes on the right. +// while (dst_index >= 0) +// { +// pdata[dst_index] = 0; +// --dst_index; +// } +// } +// +// // Truncate any bits shifted to the left. +// clear_unused_bits_in_msb(); +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator >>= +// //************************************************************************* +// ibitset& operator>>=(size_t shift) +// { +// if (shift >= Total_Bits) +// { +// reset(); +// } +// else if (Number_Of_Elements != 0UL) +// { +// // Just one element? +// if (Number_Of_Elements == 1UL) +// { +// pdata[0] >>= shift; +// } +// // Shift is the size of an element? +// else if (shift == Bits_Per_Element) +// { +// etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata); +// pdata[Number_Of_Elements - 1U] = 0; +// } +// else +// { +// // The place where the elements are split when shifting. +// const size_t split_position = shift % Bits_Per_Element; +// +// // Where we are shifting from. +// int src_index = int(shift / Bits_Per_Element); +// +// // Where we are shifting to. +// int dst_index = 0; +// +// // Shift control constants. +// const size_t lsb_shift = Bits_Per_Element - split_position; +// const size_t msb_shift = split_position; +// +// const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); +// const element_type msb_mask = etl::integral_limits::max - lsb_mask; +// const element_type msb_shifted_mask = element_type(msb_mask >> msb_shift); +// +// // Now do the shifting. +// while (src_index < int(Number_Of_Elements - 1)) +// { +// // Shift msb. +// element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); +// ++src_index; +// +// // Shift lsb. +// element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); +// +// // Combine them. +// pdata[dst_index] = lsb | msb; +// ++dst_index; +// } +// +// // Final msb. +// element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); +// pdata[dst_index] = msb; +// +// // Clear the remaining bits. +// // First msb. +// pdata[dst_index] &= msb_shifted_mask; +// ++dst_index; +// +// // The other remaining bytes. +// while (dst_index < int(Number_Of_Elements)) +// { +// pdata[dst_index] = 0; +// ++dst_index; +// } +// } +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator = +// //************************************************************************* +// ibitset& operator =(const ibitset& other) +// { +// if (this != &other) +// { +// etl::copy_n(other.pdata, Number_Of_Elements, pdata); +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// swap +// //************************************************************************* +// void swap(ibitset& other) +// { +// etl::swap_ranges(pdata, pdata + Number_Of_Elements, other.pdata); +// } +// +//#if ETL_USING_CPP11 +// //************************************************************************* +// /// span +// /// Returns a span of the underlying data. +// //************************************************************************* +// span_type span() +// { +// return span_type(pdata, pdata + Number_Of_Elements); +// } +// +// //************************************************************************* +// /// span +// /// Returns a const span of the underlying data. +// //************************************************************************* +// const_span_type span() const +// { +// return const_span_type(pdata, pdata + Number_Of_Elements); +// } +//#endif + + protected: + + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 void initialise(pointer pdata, size_t number_of_elements, unsigned long long value) + { + const size_t Shift = (etl::integral_limits::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element; + + // Can we do it in one hit? + if (Shift == 0) + { + pdata[0] = element_type(value); + } + else + { + size_t i = 0UL; + + // Set the non-zero elements. + while ((value != 0) && (i != number_of_elements)) + { + pdata[i++] = value & All_Set; + value = value >> Shift; + } + + // Clear the remaining elements. + while (i != number_of_elements) + { + pdata[i++] = All_Clear; + } + } + } + + ////************************************************************************* + ///// Invert + ////************************************************************************* + //void invert() + //{ + // for (size_t i = 0UL; i < Number_Of_Elements; ++i) + // { + // pdata[i] = ~pdata[i]; + // } + + // clear_unused_bits_in_msb(); + //} + + ////************************************************************************* + ///// Gets a reference to the specified bit. + ////************************************************************************* + //bit_reference get_bit_reference(size_t position) + //{ + // return bit_reference(*this, position); + //} + + //************************************************************************* + /// Constructor. + //************************************************************************* + //ibitset(size_t nbits_, size_t size_, element_type* pdata_) + // : Total_Bits(nbits_) + // , Number_Of_Elements(size_) + // , pdata(pdata_) + //{ + // const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element; + // const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Total_Bits)) % Bits_Per_Element); + // Top_Mask = element_type(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); + //} + + ////************************************************************************* + ///// Compare bitsets. + ////************************************************************************* + //static bool is_equal(const ibitset& lhs, const ibitset&rhs) + //{ + // return etl::equal(lhs.pdata, lhs.pdata + lhs.Number_Of_Elements, rhs.pdata); + //} + + //element_type Top_Mask; + + //************************************************************************* + ETL_CONSTEXPR14 void copy_elements(const_pointer sb, pointer db, size_t count) + { + while (count != 0) + { + *db = *sb; + ++db; + ++sb; + --count; + } + } + +// +// // Disable copy construction. +// ibitset(const ibitset&); +// +// size_t Total_Bits; +// const size_t Number_Of_Elements; +// element_type* pdata; +// +// //************************************************************************* +// /// Destructor. +// //************************************************************************* +//#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS) +// public: +// virtual ~ibitset() +// { +// } +//#else +// protected: +// ~ibitset() +// { +// } +//#endif + }; + + //************************************************************************* + /// The class emulates an array of bool elements, but optimized for space allocation. + /// Will accommodate any number of bits. + ///\tparam Total_Bits The number of bits. + ///\ingroup bitset + //************************************************************************* + template + class bitset : public etl::ibitset + { + public: + + typedef typename etl::ibitset::element_type element_type; + typedef typename etl::ibitset::pointer pointer; + typedef typename etl::ibitset::const_pointer const_pointer; + + static ETL_CONSTANT size_t Number_Of_Elements = (Total_Bits % Bits_Per_Element == 0) ? Total_Bits / Bits_Per_Element : Total_Bits / Bits_Per_Element + 1; + static ETL_CONSTANT size_t Allocated_Bits = Number_Of_Elements * Bits_Per_Element; + static ETL_CONSTANT size_t Top_Mask_Shift = ((Bits_Per_Element - (Allocated_Bits - Total_Bits)) % Bits_Per_Element); + static ETL_CONSTANT element_type Top_Mask = element_type(Top_Mask_Shift == 0 ? All_Set : ~(All_Set << Top_Mask_Shift)); + + static ETL_CONSTANT size_t ALLOCATED_BITS = Allocated_Bits; ///< For backward compatibility. + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class bitset; + + //******************************* + /// Conversion operator. + //******************************* + ETL_CONSTEXPR14 operator bool() const + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (bool b) + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (const bit_reference& r) + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + ETL_CONSTEXPR14 bit_reference& flip() + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + ETL_CONSTEXPR14 bool operator~() const + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference() + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference(bitset& r_bitset, size_t position_) + : p_bitset(&r_bitset) + , position(position_) + { + } + + bitset* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset() ETL_NOEXCEPT + : data() + { + reset(); + } + + //************************************************************************* + /// Copy constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const bitset& other) ETL_NOEXCEPT + : data() + { + copy_elements(other.data, data, Number_Of_Elements); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset(unsigned long long value) ETL_NOEXCEPT + : data() + { + initialise(data, Number_Of_Elements, value); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char* text) + : data() + { + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const wchar_t* text) + : data() + { + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char16_t* text) + : data() + { + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char32_t* text) + : data() + { + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set() + { + etl::fill_n(data, ETL_OR_STD::size(data), All_Set); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(size_t position, bool value = true) ETL_NOEXCEPT + { + etl::ibitset::set(data, Number_Of_Elements, position, value); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const wchar_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char16_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char32_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& from_string(const char* text) + { + etl::ibitset::from_string(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + bitset& from_string(const wchar_t* text) + { + etl::ibitset::from_string(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + bitset& from_string(const char16_t* text) + { + etl::ibitset::from_string(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + bitset& from_string(const char32_t* text) + { + etl::ibitset::from_string(data, Number_Of_Elements, Total_Bits, text); + + return *this; + } + + //************************************************************************* + /// Get as an integral value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value() const + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element), "Type too small"); + + return etl::ibitset::value(data, Number_Of_Elements); + } + + //************************************************************************* + /// Get as an unsigned long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long to_ulong() const + { + return value(); + } + + //************************************************************************* + /// Get as an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long long to_ullong() const + { + return value(); + } + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset() ETL_NOEXCEPT + { + etl::fill_n(data, Number_Of_Elements, All_Clear); + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset(size_t position) ETL_NOEXCEPT + { + etl::ibitset::reset(data, Number_Of_Elements, position); + return *this; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(size_t position) const + { + return etl::ibitset::test(data, Number_Of_Elements, position); + } +// + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT + { + return Total_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count() const ETL_NOEXCEPT + { + return etl::ibitset::count(data, Number_Of_Elements); + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all() const ETL_NOEXCEPT + { + return etl::ibitset::all(data, Number_Of_Elements, Top_Mask); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none() const ETL_NOEXCEPT + { + return etl::ibitset::none(data, Number_Of_Elements); + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any() const ETL_NOEXCEPT + { + return !none(); + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip() + { + etl::ibitset::flip(data, Number_Of_Elements); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip(size_t position) + { + etl::ibitset::flip(data, Number_Of_Elements, Total_Bits, position); + + return *this; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bool operator[] (size_t position) const + { + return etl::ibitset::test(data, Number_Of_Elements, position); + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bit_reference operator [] (size_t position) + { + return bit_reference(*this, position); + } + +// //************************************************************************* +// /// Returns a string representing the bitset. +// //************************************************************************* +//#if ETL_USING_CPP11 +// template > +//#else +// template +//#endif +// TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const +// { +// TString result; +// +// result.resize(Total_Bits, '\0'); +// +// ETL_ASSERT_AND_RETURN_VALUE((result.size() == Total_Bits), ETL_ERROR(etl::bitset_overflow), result); +// +// for (size_t i = Total_Bits; i > 0; --i) +// { +// result[Total_Bits - i] = test(i - 1) ? one : zero; +// } +// +// return result; +// } +// +// //************************************************************************* +// /// operator = +// //************************************************************************* +// bitset& operator =(const bitset& other) +// { +// if (this != &other) +// { +// etl::copy_n(other.data, Number_Of_Elements, data); +// } +// +// return *this; +// } +// +// //************************************************************************* +// /// operator &= +// //************************************************************************* +// bitset& operator &=(const bitset& other) +// { +// etl::ibitset::operator &=(other); +// return *this; +// } +// +// //************************************************************************* +// /// operator |= +// //************************************************************************* +// bitset& operator |=(const bitset& other) +// { +// etl::ibitset::operator |=(other); +// return *this; +// } +// +// //************************************************************************* +// /// operator ^= +// //************************************************************************* +// bitset& operator ^=(const bitset& other) +// { +// etl::ibitset::operator ^=(other); +// return *this; +// } +// +// //************************************************************************* +// /// operator ~ +// //************************************************************************* +// bitset operator ~() const +// { +// etl::bitset temp(*this); +// +// temp.invert(); +// +// return temp; +// } +// +// //************************************************************************* +// /// operator << +// //************************************************************************* +// bitset operator<<(size_t shift) const +// { +// etl::bitset temp(*this); +// +// temp <<= shift; +// +// return temp; +// } +// +// //************************************************************************* +// /// operator <<= +// //************************************************************************* +// bitset& operator<<=(size_t shift) +// { +// etl::ibitset::operator <<=(shift); +// return *this; +// } +// +// //************************************************************************* +// /// operator >> +// //************************************************************************* +// bitset operator>>(size_t shift) const +// { +// bitset temp(*this); +// +// temp >>= shift; +// +// return temp; +// } +// +// //************************************************************************* +// /// operator >>= +// //************************************************************************* +// bitset& operator>>=(size_t shift) +// { +// etl::ibitset::operator >>=(shift); +// return *this; +// } + + //************************************************************************* + /// operator == + //************************************************************************* + friend ETL_CONSTEXPR14 bool operator == (const bitset& lhs, const bitset& rhs) + { + return etl::equal(lhs.data, + lhs.data + lhs.Number_Of_Elements, + rhs.data); + } + + private: + + //************************************************************************* + /// Correct the unused top bits after bit manipulation. + //************************************************************************* + ETL_CONSTEXPR14 void clear_unused_bits_in_msb() ETL_NOEXCEPT + { + data[Number_Of_Elements - 1U] &= Top_Mask; + } + + element_type data[Number_Of_Elements > 0U ? Number_Of_Elements : 1U]; + }; + + //*************************************************************************** + /// operator & + ///\ingroup bitset + //*************************************************************************** + template + bitset operator & (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp &= rhs; + return temp; + } + + //*************************************************************************** + /// operator | + ///\ingroup bitset + //*************************************************************************** + template + bitset operator | (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp |= rhs; + return temp; + } + + //*************************************************************************** + /// operator ^ + ///\ingroup bitset + //*************************************************************************** + template + bitset operator ^ (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp ^= rhs; + return temp; + } + + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator != (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } +} + +//************************************************************************* +/// swap +//************************************************************************* +template +ETL_CONSTEXPR14 void swap(etl::bitset& lhs, etl::bitset& rhs) ETL_NOEXCEPT +{ + lhs.swap(rhs); +} + +#include "minmax_pop.h" + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 040097c4..0d42c60f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -44,7 +44,8 @@ set(TEST_SOURCE_FILES test_binary.cpp test_bip_buffer_spsc_atomic.cpp test_bit.cpp - test_bitset.cpp + test_bitset_legacy.cpp + test_bitset_new.cpp test_bit_stream.cpp test_bit_stream_reader_big_endian.cpp test_bit_stream_reader_little_endian.cpp diff --git a/test/UnitTest++/CheckMacros.h b/test/UnitTest++/CheckMacros.h index c193bf2c..bdb9e658 100644 --- a/test/UnitTest++/CheckMacros.h +++ b/test/UnitTest++/CheckMacros.h @@ -75,6 +75,48 @@ }) \ UNITTEST_MULTILINE_MACRO_END +#define UNITTEST_CHECK_NOT_EQUAL(expected, actual) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckNotEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + +#define UNITTEST_CHECK_NOT_EQUAL_HEX(expected, actual) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + UnitTest::CheckNotEqualHex(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + #define UNITTEST_CHECK_CLOSE(expected, actual, tolerance) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ @@ -173,10 +215,22 @@ #endif #ifdef CHECK_EQUAL_HEX - #error CHECK_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL instead + #error CHECK_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL_HEX instead #else #define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX - #endif + #endif + + #ifdef CHECK_NOT_EQUAL + #error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead + #else + #define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL + #endif + + #ifdef CHECK_NOT_EQUAL_HEX + #error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead + #else + #define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX + #endif #ifdef CHECK_CLOSE #error CHECK_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_CLOSE instead diff --git a/test/UnitTest++/Checks.h b/test/UnitTest++/Checks.h index 31c8aa92..ee7672d6 100644 --- a/test/UnitTest++/Checks.h +++ b/test/UnitTest++/Checks.h @@ -50,6 +50,30 @@ namespace UnitTest { } } + template< typename Expected, typename Actual > + void CheckNotEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + { + if (expected == actual) + { + UnitTest::MemoryOutStream stream; + stream << "Expected not equal, but both values are" << actual; + + results.OnTestFailure(details, stream.GetText()); + } + } + + template< typename Expected, typename Actual > + void CheckNotEqualHex(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + { + if (expected == actual) + { + UnitTest::MemoryOutStream stream; + stream << std::hex << std::uppercase << std::setfill('0') << std::setw(2 * sizeof(Actual)) << "Expected not equal, but both values are " << actual; + + results.OnTestFailure(details, stream.GetText()); + } + } + UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details); UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details); diff --git a/test/sanity-check/bitset_legacy.h.t.cpp b/test/sanity-check/bitset_legacy.h.t.cpp new file mode 100644 index 00000000..7aec2c9e --- /dev/null +++ b/test/sanity-check/bitset_legacy.h.t.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 Bo Rydberg, John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include diff --git a/test/sanity-check/bitset.h.t.cpp b/test/sanity-check/bitset_new.h.t.cpp similarity index 94% rename from test/sanity-check/bitset.h.t.cpp rename to test/sanity-check/bitset_new.h.t.cpp index 2bd9e0d5..9cafe84f 100644 --- a/test/sanity-check/bitset.h.t.cpp +++ b/test/sanity-check/bitset_new.h.t.cpp @@ -5,7 +5,7 @@ Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com -Copyright(c) 2021 Bo Rydberg +Copyright(c) 2022 Bo Rydberg, John Wellbelove Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal @@ -26,4 +26,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include +#include diff --git a/test/sanity-check/c++03/CMakeLists.txt b/test/sanity-check/c++03/CMakeLists.txt index 32229217..973e0748 100644 --- a/test/sanity-check/c++03/CMakeLists.txt +++ b/test/sanity-check/c++03/CMakeLists.txt @@ -55,7 +55,8 @@ target_sources(t98 PRIVATE etl_profile.h ../binary.h.t.cpp ../bip_buffer_spsc_atomic.h.t.cpp ../bit.h.t.cpp - ../bitset.h.t.cpp + ../bitset_legacy.h.t.cpp + ../bitset_new.h.t.cpp ../bit_stream.h.t.cpp ../byte.h.t.cpp ../byte_stream.h.t.cpp diff --git a/test/sanity-check/c++11/CMakeLists.txt b/test/sanity-check/c++11/CMakeLists.txt index 0d412554..49d20a97 100644 --- a/test/sanity-check/c++11/CMakeLists.txt +++ b/test/sanity-check/c++11/CMakeLists.txt @@ -55,7 +55,8 @@ target_sources(t11 PRIVATE etl_profile.h ../binary.h.t.cpp ../bip_buffer_spsc_atomic.h.t.cpp ../bit.h.t.cpp - ../bitset.h.t.cpp + ../bitset_legacy.h.t.cpp + ../bitset_new.h.t.cpp ../bit_stream.h.t.cpp ../byte.h.t.cpp ../byte_stream.h.t.cpp diff --git a/test/sanity-check/c++14/CMakeLists.txt b/test/sanity-check/c++14/CMakeLists.txt index 099dda8d..710c5559 100644 --- a/test/sanity-check/c++14/CMakeLists.txt +++ b/test/sanity-check/c++14/CMakeLists.txt @@ -55,7 +55,8 @@ target_sources(t14 PRIVATE etl_profile.h ../binary.h.t.cpp ../bip_buffer_spsc_atomic.h.t.cpp ../bit.h.t.cpp - ../bitset.h.t.cpp + ../bitset_legacy.h.t.cpp + ../bitset_new.h.t.cpp ../bit_stream.h.t.cpp ../byte.h.t.cpp ../byte_stream.h.t.cpp diff --git a/test/sanity-check/c++17/CMakeLists.txt b/test/sanity-check/c++17/CMakeLists.txt index bdb3c91c..5ee2865f 100644 --- a/test/sanity-check/c++17/CMakeLists.txt +++ b/test/sanity-check/c++17/CMakeLists.txt @@ -55,7 +55,8 @@ target_sources(t17 PRIVATE etl_profile.h ../binary.h.t.cpp ../bip_buffer_spsc_atomic.h.t.cpp ../bit.h.t.cpp - ../bitset.h.t.cpp + ../bitset_legacy.h.t.cpp + ../bitset_new.h.t.cpp ../bit_stream.h.t.cpp ../byte.h.t.cpp ../byte_stream.h.t.cpp diff --git a/test/test_bitset.cpp b/test/test_bitset_legacy.cpp similarity index 99% rename from test/test_bitset.cpp rename to test/test_bitset_legacy.cpp index 58be9f73..92982e49 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset_legacy.cpp @@ -32,11 +32,11 @@ SOFTWARE. #include #include -#include "etl/bitset.h" +#include "etl/private/bitset_legacy.h" namespace { - SUITE(test_bitset) + SUITE(test_bitset_legacy) { //************************************************************************* TEST(test_constructor) diff --git a/test/test_bitset_new.cpp b/test/test_bitset_new.cpp new file mode 100644 index 00000000..af0e6838 --- /dev/null +++ b/test/test_bitset_new.cpp @@ -0,0 +1,1390 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include +#include +#include + +#include "etl/private/bitset_new.h" + +namespace +{ + using ull = unsigned long long; + + SUITE(test_bitset_new) + { + //************************************************************************* + TEST(test_default_constructor) + { + constexpr std::bitset<60> compare; + constexpr etl::bitset<60> data; + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_value) + { + constexpr std::bitset<60> compare(0x123456731234567ULL); + constexpr etl::bitset<60> data(0x123456731234567ULL); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_copy_construct) + { + constexpr std::bitset<60> compare(0x123456731234567ULL); + constexpr etl::bitset<60> data(0x123456731234567ULL); + constexpr etl::bitset<60> data_copy(data); + + CHECK_EQUAL(compare.size(), data_copy.size()); + CHECK_EQUAL(compare.count(), data_copy.count()); + + for (size_t i = 0UL; i < data_copy.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data_copy.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_excess_value) + { + constexpr std::bitset<60> compare(0x8765432187654321ULL); + constexpr etl::bitset<60> data(0x8765432187654321ULL); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_char_string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data("110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_wchar_t_string) + { + std::bitset<60> compare(L"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data(L"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_char16_t_string) + { + std::bitset<60> compare(u"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data(u"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_char32_t_string) + { + std::bitset<60> compare(U"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data(U"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_construct_from_excess_string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001111100001"); + etl::bitset<60> data("110001001000110100010101100111001100010010001101000101011001111100001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + constexpr etl::bitset<60> test_set_helper() + { + etl::bitset<60> data; + data.set(); + + return data; + } + + TEST(test_set) + { + std::bitset<60> compare; + constexpr etl::bitset<60> data(test_set_helper()); + + compare.set(); + + constexpr auto size = data.size(); + constexpr auto count = data.count(); + constexpr auto none = data.none(); + constexpr auto any = data.any(); + constexpr auto all = data.all(); + + CHECK_EQUAL(compare.size(), size); + CHECK_EQUAL(compare.count(), count); + CHECK_EQUAL(compare.none(), none); + CHECK_EQUAL(compare.any(), any); + CHECK_EQUAL(compare.all(), all); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_char_string_set) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.set("110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_wchar_t_string_set) + { + std::bitset<60> compare(L"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.set(L"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_char16_t_string_set) + { + std::bitset<60> compare(u"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.set(u"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_char32_t_string_set) + { + std::bitset<60> compare(U"110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.set(U"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_from_char_string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.from_string("110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_from_wchar_t_string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.from_string(L"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_from_char16_t_6string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.from_string(u"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_from_char32_t_string) + { + std::bitset<60> compare("110001001000110100010101100111001100010010001101000101011001"); + etl::bitset<60> data; + + data.from_string(U"110001001000110100010101100111001100010010001101000101011001"); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_value_u8_min) + { + constexpr etl::bitset<8> data((unsigned long long)etl::integral_limits::min); + constexpr uint8_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_u8_max) + { + constexpr etl::bitset<8> data((unsigned long long)etl::integral_limits::max); + constexpr uint8_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_s8_min) + { + constexpr etl::bitset<8> data((unsigned long long)etl::integral_limits::min); + constexpr int8_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_s8_max) + { + constexpr etl::bitset<8> data((unsigned long long)etl::integral_limits::max); + constexpr int8_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_u16_min) + { + constexpr etl::bitset<16> data((unsigned long long)etl::integral_limits::min); + constexpr uint16_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_u16_max) + { + constexpr etl::bitset<16> data((unsigned long long)etl::integral_limits::max); + constexpr uint16_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_s16_min) + { + constexpr etl::bitset<16> data((unsigned long long)etl::integral_limits::min); + constexpr int16_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_s16_max) + { + etl::bitset<16> data((unsigned long long)etl::integral_limits::max); + int16_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_u32_min) + { + constexpr etl::bitset<32> data((unsigned long long)etl::integral_limits::min); + constexpr uint32_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_u32_max) + { + constexpr etl::bitset<32> data((unsigned long long)etl::integral_limits::max); + constexpr uint32_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_s32_min) + { + constexpr etl::bitset<32> data((unsigned long long)etl::integral_limits::min); + constexpr int32_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_s32_max) + { + constexpr etl::bitset<32> data((unsigned long long)etl::integral_limits::max); + constexpr int32_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_u64_min) + { + constexpr etl::bitset<64> data((unsigned long long)etl::integral_limits::min); + constexpr uint64_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_u64_max) + { + constexpr etl::bitset<64> data((unsigned long long)etl::integral_limits::max); + constexpr uint64_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_value_s64_min) + { + constexpr etl::bitset<64> data((unsigned long long)etl::integral_limits::min); + constexpr int64_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::min(), value); + } + + //************************************************************************* + TEST(test_value_s64_max) + { + constexpr etl::bitset<64> data((unsigned long long)etl::integral_limits::max); + constexpr int64_t value = data.value(); + + CHECK_EQUAL(std::numeric_limits::max(), value); + } + + //************************************************************************* + TEST(test_using_element_type_int8_t) + { + std::bitset<60> compare(ull(0x0C48D159CC48D159)); + etl::bitset<60, int8_t> data(ull(0x0C48D159CC48D159)); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + + CHECK_EQUAL_HEX(compare.to_ullong(), data.to_ullong()); + } + + //************************************************************************* + TEST(test_using_element_type_int16_t) + { + std::bitset<60> compare(ull(0x0C48D159CC48D159)); + etl::bitset<60, int16_t> data(ull(0x0C48D159CC48D159)); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + + CHECK_EQUAL_HEX(compare.to_ullong(), data.to_ullong()); + } + + //************************************************************************* + TEST(test_using_element_type_int32_t) + { + std::bitset<60> compare(ull(0x0C48D159CC48D159)); + etl::bitset<60, int32_t> data(ull(0x0C48D159CC48D159)); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + + CHECK_EQUAL_HEX(compare.to_ullong(), data.to_ullong()); + } + + //************************************************************************* + TEST(test_using_element_type_int64_t) + { + std::bitset<60> compare(ull(0x0C48D159CC48D159)); + etl::bitset<60, int64_t> data(ull(0x0C48D159CC48D159)); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + + CHECK_EQUAL_HEX(compare.to_ullong(), data.to_ullong()); + } + + //************************************************************************* + TEST(test_position_set) + { + std::bitset<60> compare; + etl::bitset<60> data; + + for (size_t i = 0UL; i < data.size(); ++i) + { + compare.set(i, (i % 2) == 0); + data.set(i, (i % 2) == 0); + } + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + constexpr etl::bitset<60> test_reset_helper() + { + etl::bitset<60> data(0xFFFFFFFFFFFFFFFULL); + data.reset(); + + return data; + } + + TEST(test_reset) + { + std::bitset<60> compare(0xFFFFFFFFFFFFFFFULL); + constexpr etl::bitset<60> data(test_reset_helper()); + + compare.reset(); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + constexpr etl::bitset<60> test_position_reset_helper() + { + etl::bitset<60> data(0xFFFFFFFFFFFFFFFULL); + data.reset(1); + data.reset(3); + data.reset(7); + data.reset(13); + + return data; + } + + TEST(test_position_reset) + { + std::bitset<60> compare(0xFFFFFFFFFFFFFFFULL); + constexpr etl::bitset<60> data(test_position_reset_helper()); + + compare.reset(1); + compare.reset(3); + compare.reset(7); + compare.reset(13); + + CHECK_EQUAL(compare.size(), data.size()); + CHECK_EQUAL(compare.count(), data.count()); + CHECK_EQUAL(compare.none(), data.none()); + CHECK_EQUAL(compare.any(), data.any()); + CHECK_EQUAL(compare.all(), data.all()); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + ////************************************************************************* + //TEST(test_index_operator_read) + //{ + // std::bitset<60> compare(0x3123456731234567ULL); + // etl::bitset<60> data(0x3123456731234567ULL); + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // CHECK_EQUAL(compare[i], data[i]); + // } + //} + + ////************************************************************************* + //TEST(test_index_operator_write) + //{ + // std::bitset<60> compare; + // etl::bitset<60> data; + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // compare[i] = (i % 2) == 0; + // data[i] = (i % 2) == 0; + // } + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // CHECK_EQUAL(compare[i], data[i]); + // } + //} + + ////************************************************************************* + //TEST(test_any) + //{ + // std::bitset<60> compare; + // etl::bitset<60> data; + + // // Set all bits + // compare.set(); + // data.set(); + + // // Reset them all. + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // compare.reset(i); + // data.reset(i); + // } + + // CHECK_EQUAL(compare.any(), data.any()); + + // compare.set(3); + // data.set(3); + + // CHECK_EQUAL(compare.any(), data.any()); + //} + + ////************************************************************************* + //TEST(test_none) + //{ + // std::bitset<62> compare; + // etl::bitset<62> data; + + // CHECK_EQUAL(compare.none(), data.none()); + + // compare.set(3); + // data.set(3); + + // CHECK_EQUAL(compare.none(), data.none()); + //} + + ////************************************************************************* + //TEST(test_all) + //{ + // std::bitset<60> compare; + // etl::bitset<60> data; + + // CHECK_EQUAL(compare.all(), data.all()); + + // compare.set(); + // data.set(); + + // CHECK_EQUAL(compare.all(), data.all()); + //} + + //************************************************************************* + constexpr etl::bitset<60> test_flip_helper() + { + etl::bitset<60> data; + data.flip(); + + return data; + } + + TEST(test_flip) + { + std::bitset<60> compare; + constexpr etl::bitset<60> data(test_flip_helper()); + + compare.flip(); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + constexpr etl::bitset<60> test_flip_position_helper() + { + etl::bitset<60> data; + data.flip(1); + data.flip(3); + data.flip(7); + data.flip(13); + + return data; + } + + TEST(test_flip_position) + { + std::bitset<60> compare; + constexpr etl::bitset<60> data(test_flip_position_helper()); + + compare.flip(1); + compare.flip(3); + compare.flip(7); + compare.flip(13); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + constexpr etl::bitset<60> test_flip_reference_helper() + { + etl::bitset<60> data; + data[1].flip(); + data[3].flip(); + data[7].flip(); + data[13].flip(); + + return data; + } + + TEST(test_flip_reference) + { + std::bitset<60> compare; + constexpr etl::bitset<60> data(test_flip_reference_helper()); + + compare[1].flip(); + compare[3].flip(); + compare[7].flip(); + compare[13].flip(); + + for (size_t i = 0UL; i < data.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data.test(i)); + } + } + + //************************************************************************* + TEST(test_invert_reference) + { + std::bitset<60> compare; + etl::bitset<60> data; + + bool bc = ~compare[3]; + bool bd = ~data[3]; + CHECK_EQUAL(bc, bd); + } + + //************************************************************************* + TEST(test_assignment_operator) + { + std::bitset<60> compare(0xFFFFFFFFFFFFFFFULL); + etl::bitset<60> data1(0xFFFFFFFFFFFFFFFULL); + etl::bitset<60> data2; + + data2 = data1; + + for (size_t i = 0UL; i < data2.size(); ++i) + { + CHECK_EQUAL(compare.test(i), data2.test(i)); + } + } + + //************************************************************************* + TEST(test_equality_operator) + { + constexpr etl::bitset<60> data1(0x123456781234567ULL); + constexpr etl::bitset<60> data2(0x123456781234567ULL); + constexpr etl::bitset<60> data3; + + constexpr bool equal = (data1 == data2); + constexpr bool not_equal = !(data1 == data3); + + CHECK(equal); + CHECK(not_equal); + } + + //************************************************************************* + TEST(test_inequality_operator) + { + constexpr etl::bitset<60> data1(0x123456781234567ULL); + constexpr etl::bitset<60> data2(0x123456781234567ULL); + constexpr etl::bitset<60> data3; + + constexpr bool equal = !(data1 != data2); + constexpr bool not_equal = (data1 != data3); + + CHECK(!(data1 != data2)); + CHECK(data1 != data3); + } + + ////************************************************************************* + //TEST(test_shift_left_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2; + // etl::bitset<60> shift1(0x2468ACF0UL); + // etl::bitset<60> shift2(0x48D159E0UL); + // etl::bitset<60> shift11(0x91A2B3C000ULL); + + // data2 = data1; + // data2 <<= 1U; + // CHECK(data2 == shift1); + + // data2 = data1; + // data2 <<= 2U; + // CHECK(data2 == shift2); + + // data2 = data1; + // data2 <<= 11U; + // CHECK(data2 == shift11); + //} + + ////************************************************************************* + //TEST(test_shift_left_operator_shift_element_size) + //{ + // etl::bitset<60> data(0x12345678UL); + // etl::bitset<60> shift(0x1234567800UL); + + // data <<= 8U; + // CHECK_EQUAL_HEX(shift.value(), data.value()); + //} + + ////************************************************************************* + //TEST(test_shift_left_operator_overflow) + //{ + // etl::bitset<31> data(0x7FFFFFFFUL); + // etl::bitset<31> shifted(0x7FFFFFFEUL); + + // data <<= 1U; + // CHECK(data == shifted); + //} + + ////************************************************************************* + //TEST(test_shift_left_copy_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2; + // etl::bitset<60> shift1(0x2468ACF0UL); + // etl::bitset<60> shift2(0x48D159E0UL); + // etl::bitset<60> shift11(0x91A2B3C000ULL); + + // data2 = data1 << 1U; + // CHECK(data2 == shift1); + + // data2 = data1 << 2U; + // CHECK(data2 == shift2); + + // data2 = data1 << 11U; + // CHECK(data2 == shift11); + //} + + ////************************************************************************* + //TEST(test_shift_left_operator_all_shifts_full_size) + //{ + // constexpr uint64_t value = 0x0123456789ABCDEFULL; + + // for (int shift = 0; shift < 64; ++shift) + // { + // etl::bitset<64> data(value); + + // CHECK_EQUAL_HEX((value << shift), (data << shift).value()); + // } + + // etl::bitset<64> data(value); + // CHECK_EQUAL_HEX(0, (data << 64).value()); + //} + + ////************************************************************************* + //TEST(test_shift_left_operator_all_shifts_partial_size) + //{ + // constexpr uint64_t value = 0x0123456789ABCDEFULL; + // constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL; + + // for (int shift = 0; shift < 64; ++shift) + // { + // etl::bitset<60> data(value); + + // CHECK_EQUAL_HEX(((value << shift) & mask), (data << shift).value()); + // } + + // etl::bitset<64> data(value); + // CHECK_EQUAL_HEX(0, (data << 64).value()); + //} + + ////************************************************************************* + //TEST(test_shift_right_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2; + // etl::bitset<60> shift1(0x91A2B3CUL); + // etl::bitset<60> shift2(0x48D159EUL); + // etl::bitset<60> shift11(0x2468AUL); + + // data2 = data1; + // data2 >>= 1U; + // CHECK(data2 == shift1); + + // data2 = data1; + // data2 >>= 2U; + // CHECK(data2 == shift2); + + // data2 = data1; + // data2 >>= 11U; + // CHECK(data2 == shift11); + //} + + ////************************************************************************* + //TEST(test_shift_right_operator_all_shifts_full_size) + //{ + // constexpr uint64_t value = 0x0123456789ABCDEFULL; + // + // for (int shift = 0; shift < 64; ++shift) + // { + // etl::bitset<64> data(value); + + // CHECK_EQUAL_HEX((value >> shift), (data >> shift).value()); + // } + + // etl::bitset<64> data(value); + // CHECK_EQUAL_HEX(0, (data >> 64).value()); + //} + + ////************************************************************************* + //TEST(test_shift_right_operator_all_shifts_partial_size) + //{ + // constexpr uint64_t value = 0x0123456789ABCDEFULL; + // constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL; + + // for (int shift = 0; shift < 64; ++shift) + // { + // etl::bitset<60> data(value); + + // CHECK_EQUAL_HEX(((value >> shift) & mask), (data >> shift).value()); + // } + + // etl::bitset<64> data(value); + // CHECK_EQUAL_HEX(0, (data >> 64).value()); + //} + + ////************************************************************************* + //TEST(test_shift_right_operator_shift_element_size) + //{ + // etl::bitset<60> data(0x12345678UL); + // etl::bitset<60> shift(0x123456UL); + + // data >>= 8U; + // CHECK_EQUAL_HEX(shift.value(), data.value()); + //} + + ////************************************************************************* + //TEST(test_shift_right_copy_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2; + // etl::bitset<60> shift1(0x91A2B3CUL); + // etl::bitset<60> shift2(0x48D159EUL); + // etl::bitset<60> shift11(0x2468AUL); + + // data2 = data1 >> 1U; + // CHECK(data2 == shift1); + + // data2 = data1 >> 2U; + // CHECK(data2 == shift2); + + // data2 = data1 >> 11U; + // CHECK(data2 == shift11); + //} + + ////************************************************************************* + //TEST(test_and_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3; + // etl::bitset<60> data4(0x12345678UL & 0x23456789UL); + + // data3 = data1 & data2; + // CHECK(data3 == data4); + //} + + ////************************************************************************* + //TEST(test_and_equals_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3(0x12345678UL & 0x23456789UL); + + // data2 &= data1; + // CHECK(data2 == data3); + //} + + ////************************************************************************* + //TEST(test_or_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3; + // etl::bitset<60> data4(0x12345678UL | 0x23456789UL); + + // data3 = data1 | data2; + // CHECK(data3 == data4); + //} + + ////************************************************************************* + //TEST(test_or_equals_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3(0x12345678UL | 0x23456789UL); + + // data2 |= data1; + // CHECK(data2 == data3); + //} + + ////************************************************************************* + //TEST(test_xor_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3; + // etl::bitset<60> data4(0x12345678UL ^ 0x23456789UL); + + // data3 = data1 ^ data2; + // CHECK(data3 == data4); + //} + + ////************************************************************************* + //TEST(test_xor_equals_operator) + //{ + // etl::bitset<60> data1(0x12345678UL); + // etl::bitset<60> data2(0x23456789UL); + // etl::bitset<60> data3(0x12345678UL ^ 0x23456789UL); + + // data2 ^= data1; + // CHECK(data2 == data3); + //} + + ////************************************************************************* + //TEST(test_index_operator) + //{ + // etl::bitset<60> data1(0x123456781234567ULL); + // etl::bitset<60> data2; + + // for (size_t i = 0UL; i < data1.size(); ++i) + // { + // data2[i] = data1[i]; + // } + + // CHECK(data1 == data2); + //} + + ////************************************************************************* + //TEST(test_big_bitset) + //{ + // std::bitset<10000> compare; + // etl::bitset<10000> data; + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // compare.set(i, (i % 2) == 0); + // data.set(i, (i % 2) == 0); + // } + + // CHECK_EQUAL(compare.test(64), data.test(64)); + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // CHECK_EQUAL(compare.test(i), data.test(i)); + // } + + // compare.flip(); + // data.flip(); + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // CHECK_EQUAL(compare.test(i), data.test(i)); + // } + //} + + ////************************************************************************* + //TEST(test_small_bitset) + //{ + // std::bitset<7> compare; + // etl::bitset<7> data; + + // compare.flip(); + // data.flip(); + + // for (size_t i = 0UL; i < data.size(); ++i) + // { + // CHECK_EQUAL(compare.test(i), data.test(i)); + // } + //} + + ////************************************************************************* + //TEST(test_find_first) + //{ + // etl::bitset<6> data; + + // data.set("000000"); + // CHECK_EQUAL(0U, data.find_first(false)); + // CHECK_EQUAL(etl::ibitset::npos, data.find_first(true)); + + // data.set("111111"); + // CHECK_EQUAL(etl::ibitset::npos, data.find_first(false)); + // CHECK_EQUAL(0U, data.find_first(true)); + + // data.set("000001"); + // CHECK_EQUAL(1U, data.find_first(false)); + // CHECK_EQUAL(0U, data.find_first(true)); + + // data.set("100000"); + // CHECK_EQUAL(0U, data.find_first(false)); + // CHECK_EQUAL(5U, data.find_first(true)); + + // data.set("100001"); + // CHECK_EQUAL(1U, data.find_first(false)); + // CHECK_EQUAL(0U, data.find_first(true)); + + // data.set("001110"); + // CHECK_EQUAL(0U, data.find_first(false)); + // CHECK_EQUAL(1U, data.find_first(true)); + + // data.set("110001"); + // CHECK_EQUAL(1U, data.find_first(false)); + // CHECK_EQUAL(0U, data.find_first(true)); + //} + + ////************************************************************************* + //TEST(test_find_next) + //{ + // etl::bitset<6> data; + + // data.set("000000"); + // CHECK_EQUAL(0U, data.find_next(false, 0)); + // CHECK_EQUAL(1U, data.find_next(false, 1)); + // CHECK_EQUAL(etl::ibitset::npos, data.find_next(true, 2)); + + // data.set("111111"); + // CHECK_EQUAL(0U, data.find_next(true, 0)); + // CHECK_EQUAL(1U, data.find_next(true, 1)); + // CHECK_EQUAL(etl::ibitset::npos, data.find_next(false, 2)); + + // data.set("001110"); + // CHECK_EQUAL(0U, data.find_next(false, 0)); + // CHECK_EQUAL(1U, data.find_next(true, 0)); + // CHECK_EQUAL(4U, data.find_next(false, 1)); + + // data.set("110001"); + // CHECK_EQUAL(0U, data.find_next(true, 0)); + // CHECK_EQUAL(1U, data.find_next(false, 0)); + // CHECK_EQUAL(4U, data.find_next(true, 1)); + //} + + ////************************************************************************* + //TEST(test_find_next_multi_byte_bitset_github_issue_336) + //{ + // etl::bitset<24> data; + // data.set(12); + // data.set(22); + // CHECK_EQUAL(12U, data.find_next(true, 3)); + // CHECK_EQUAL(12U, data.find_next(true, 10)); + + // // set first ten bytes + // data.set("1111111111"); + // CHECK_EQUAL(10U, data.find_next(false, 3)); + // CHECK_EQUAL(10U, data.find_next(false, 9)); + //} + + ////************************************************************************* + //TEST(test_find_next_github_issue_336) + //{ + // etl::bitset<16> bits16; + // bits16.set(12); + + // etl::bitset<24> bits24; + // bits24.set(12); + + // CHECK_EQUAL(12, bits16.find_first(true)); + // CHECK_EQUAL(12, bits16.find_next(true, 4)); + // CHECK_EQUAL(etl::ibitset::npos, bits16.find_next(true, 13)); + + // CHECK_EQUAL(12, bits24.find_first(true)); + // CHECK_EQUAL(12, bits24.find_next(true, 4)); + // CHECK_EQUAL(etl::ibitset::npos, bits24.find_next(true, 13)); + //} + + ////************************************************************************* + //TEST(test_swap) + //{ + // etl::bitset<6> compare1("101010"); + // etl::bitset<6> compare2("010101"); + + // etl::bitset<6> data1(compare1); + // etl::bitset<6> data2(compare2); + + // swap(data1, data2); + + // CHECK(data1 == compare2); + // CHECK(data2 == compare1); + //} + + ////************************************************************************* + //TEST(test_span) + //{ + // using span_t = etl::ibitset::span_type; + + // etl::bitset<32> b(0x12345678UL); + + // span_t s = b.span(); + // CHECK_EQUAL(0x78U, s[0]); + // CHECK_EQUAL(0x56U, s[1]); + // CHECK_EQUAL(0x34U, s[2]); + // CHECK_EQUAL(0x12U, s[3]); + + // s[2] = 0x9AU; + // uint32_t value = b.value(); + // CHECK_EQUAL(0x129A5678UL, value); + //} + + ////************************************************************************* + //TEST(test_const_span) + //{ + // using span_t = etl::ibitset::const_span_type; + + // const etl::bitset<32> b(0x12345678UL); + + // span_t s = b.span(); + // CHECK_EQUAL(0x78U, s[0]); + // CHECK_EQUAL(0x56U, s[1]); + // CHECK_EQUAL(0x34U, s[2]); + // CHECK_EQUAL(0x12U, s[3]); + //} + + ////************************************************************************* + //TEST(test_to_string) + //{ + // etl::bitset<32> b(0x12345678UL); + + // etl::string<32> text = b.to_string('.', '*'); + // std::string stdtext = b.to_string('.', '*'); + + // CHECK_THROW(etl::string<32> text1 = b.to_string>('.', '*'), etl::bitset_overflow); + // CHECK_EQUAL("...*..*...**.*...*.*.**..****...", text.c_str()); + // CHECK_EQUAL("...*..*...**.*...*.*.**..****...", stdtext.c_str()); + //} + + ////************************************************************************* + //TEST(test_issue_497_count_inverted_bits) + //{ + // etl::bitset<5U> bits; + // std::bitset<5U> stdbits; + // etl::bitset<5U> negbits = ~bits; + // std::bitset<5U> stdnegbits = ~stdbits; + + // CHECK_EQUAL(stdbits.count(), bits.count()); + // CHECK_EQUAL(stdbits.all(), bits.all()); + // CHECK_EQUAL(stdnegbits.count(), negbits.count()); + // CHECK_EQUAL(stdnegbits.all(), negbits.all()); + //} + + ////************************************************************************* + //TEST(test_issue_497_shifted_zero_sized_bitset) + //{ + // etl::bitset<0> bits; + // std::bitset<0> stdbits; + + // CHECK_EQUAL(stdbits.size(), bits.size()); + // CHECK_EQUAL(stdbits.none(), bits.none()); + // CHECK_EQUAL(stdbits.all(), bits.all()); + // CHECK_EQUAL(stdbits.any(), bits.any()); + + // CHECK_EQUAL(stdbits.count(), bits.count()); + // CHECK_EQUAL(stdbits.to_ulong(), bits.to_ulong()); + // CHECK_EQUAL(stdbits.to_ullong(), bits.to_ullong()); + + // etl::bitset<0> shiftbits = bits << 1; // No exception. + //} + }; +} diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index ad1e9363..286677b2 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -2439,6 +2439,8 @@ + + @@ -2602,7 +2604,6 @@ - @@ -3377,7 +3378,7 @@ true true - + true true true @@ -3410,6 +3411,34 @@ true true + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -11223,6 +11252,7 @@ + @@ -11330,7 +11360,7 @@ - + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 572aa061..b0773cc1 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -285,9 +285,6 @@ ETL\Containers - - ETL\Containers - ETL\Utilities @@ -1326,6 +1323,12 @@ ETL\Messaging + + ETL\Private + + + ETL\Private + @@ -1883,7 +1886,7 @@ Tests\Binary - + Tests\Binary @@ -2288,7 +2291,7 @@ Tests\Sanity Checks\Source - + Tests\Sanity Checks\Source @@ -3338,6 +3341,12 @@ Tests\Misc + + Tests\Binary + + + Tests\Sanity Checks\Source +