-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] dynamic_bitset #1153
[FEATURE] dynamic_bitset #1153
Conversation
Just curious, why is 58 the upper limit? |
We use the most significant 6 bit of the |
A normal bitset can also be greater than 64bit, this one can't. I imagine you don't need this for your use case. |
6030df9
to
2df2476
Compare
Codecov Report
@@ Coverage Diff @@
## master #1153 +/- ##
=========================================
+ Coverage 96.72% 96.83% +0.1%
=========================================
Files 210 211 +1
Lines 8003 8280 +277
=========================================
+ Hits 7741 8018 +277
Misses 262 262
Continue to review full report at Codecov.
|
For now this is enough, main application will be the shapes, where 32 is fine. |
5a21b56
to
3b7cd9b
Compare
31d8fe9
to
8d0fd8e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A general design question:
If you want to encode the size
and value
into one integer, I think it would be better to use bitfields, because the compiler will do all the hard work for you and it is a standard feature!
8d0fd8e
to
005db2e
Compare
ddd9dec
to
048f99e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change for next push after review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm 👍
b8f20e0
to
5513d62
Compare
@marehr ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
* ### Thread safety | ||
* | ||
* This container provides no thread-safety beyond the promise given also by the STL that all | ||
* calls to `const` member function are safe from multiple threads (as long as no thread calls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* calls to `const` member function are safe from multiple threads (as long as no thread calls | |
* calls to `const` member functions are safe from multiple threads (as long as no thread calls |
1af3b21
to
bc0c267
Compare
bc0c267
to
9671c33
Compare
{ | ||
return !static_cast<bool>(internal.bits & mask); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double newline
|
||
//!\cond | ||
// this signals to range-v3 that something is a container :| | ||
using allocator_type = void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, the container concept of the ranges library does not check for a type allocator_type
. Can you give me an example where the expected behavior does not work without this type?
|
||
/*!\brief Construct from a different range. | ||
* \tparam other_range_t The type of range to be inserted; must satisfy std::ranges::InputRange and `value_type` | ||
* must be constructible from reference_t<other_range_t>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still open
/*!\brief Construct from a different range. | ||
* \tparam other_range_t The type of range to be inserted; must satisfy std::ranges::InputRange and `value_type` | ||
* must be constructible from reference_t<other_range_t>. | ||
* \param[in] range The sequence to construct/assign from. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, leave it as is right now but for the future please do not align different doxygen entities. That looks just awful.
|
||
/*!\brief Assign from pair of iterators. | ||
* \tparam begin_it_type Must satisfy std::ForwardIterator and the `value_type` must be constructible from | ||
* the reference type of begin_it_type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please check all comments again, i.e. that code expressions are wrapped in a code
-block. So that it is consistent through the documentation
* | ||
* \details | ||
* | ||
* Calling pop_back() on an empty container is undefined. In debug mode an assertion will be thrown. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Calling pop_back() on an empty container is undefined. In debug mode an assertion will be thrown. | |
* Calling `pop_back()` on an empty container is undefined. In debug mode an assertion will be thrown. |
} | ||
|
||
//!\overload | ||
constexpr void swap(dynamic_bitset && rhs) noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what are you saving? The constructor and the assignment are defaulted anyway. Non one us using the swap internally. the copy-n-swap idiom is not necessary here. Hence, std::swap would work already for this class and should be the preferred way.
Mhmm but I see know, that it is the stupid container requirement. I'll make this a discussion point in the next dev meeting
* | ||
* ### Thread-safety | ||
* | ||
* Not thread-safe. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no you don't need to mark them not-thread safe as it is clear by the top level documentation. In general if there is no explicit statement you always assume not thread-safe
@rrahn all the doc issues should be resolved now |
Immediate TODO:
to_string()
- with customdebug_stream
overload if this does not work automatically whento_string()
is defined. Standard range debug_stream'ing needs to be reversed.Maybe TODO:
Lavish features such as:
std::string to_string(CharT zero = CharT('0'), CharT one = CharT('1')) const;
which allows you to set specific characters for 0 and 1unsigned long to_ulong() const
andunsigned long long to_ullong() const
, but these are one-linersstd::hash
supportNote:
1️⃣
begin()
points to the least significant bit, i.e. right to left instead left to right.Example:
Future TODO:
operator>>
we have the line:I copied from the
small_string
implementation.It's used correctly in this context (we check
is.eof()
after we read EOF), but we only read up tomax(is.width(), arg.max_size())
many characters, which already ensures we never read EOF, so the branch is never reached. @smehringer