Go to the documentation of this file.
9 #ifndef EAGINE_BITESET_HPP
10 #define EAGINE_BITESET_HPP
18 #include <type_traits>
26 template <
typename std::
size_t B>
36 std::conditional_t<(B <= 64), std::uint_least64_t,
void>>>>;
38 template <std::
size_t N, std::
size_t B,
typename T = biteset_cell_type<B>>
45 template <
typename BiS>
53 template <
typename BiS>
70 constexpr
auto is_valid() const noexcept ->
bool {
71 return (_ptr !=
nullptr) && (_pos < _ptr->size());
77 return EAGINE_CONSTEXPR_ASSERT(
is_valid(), _ptr->get(_pos));
83 EAGINE_CONSTEXPR_ASSERT(
is_valid(), _ptr->set(_pos, val));
86 void swap(
self& other) noexcept {
88 EAGINE_ASSERT(_ptr !=
nullptr);
89 EAGINE_ASSERT(_ptr == other._ptr);
105 friend constexpr
auto operator==(
const self& a,
const self& b) noexcept {
106 return a.get() == b.get();
110 friend constexpr
auto operator!=(
const self& a,
const self& b) noexcept {
111 return a.get() != b.get();
115 friend constexpr
auto operator<(
const self& a,
const self& b) noexcept {
116 return a.get() < b.get();
120 friend constexpr
auto operator<=(
const self& a,
const self& b) noexcept {
121 return a.get() <= b.get();
125 friend constexpr
auto operator>(
const self& a,
const self& b) noexcept {
126 return a.get() > b.get();
130 friend constexpr
auto operator>=(
const self& a,
const self& b) noexcept {
131 return a.get() >= b.get();
143 template <std::
size_t N, std::
size_t B,
typename T>
154 size_type pos) noexcept
162 template <std::
size_t N, std::
size_t B,
typename T>
178 std::is_nothrow_move_constructible_v<_base>) =
default;
180 std::is_nothrow_copy_constructible_v<_base>) =
delete;
184 this->set(temp.get());
188 std::is_nothrow_copy_assignable_v<_base>) =
delete;
199 template <
typename BiS>
201 swap(biteset_value_proxy<BiS>&& a, biteset_value_proxy<BiS>&& b) noexcept {
205 template <
typename BiS>
206 class biteset_iterator;
208 template <
typename BiS>
209 class biteset_iterator_base {
211 using self = biteset_iterator_base;
212 using derived = biteset_iterator<BiS>;
213 using size_type =
typename BiS::size_type;
214 using difference_type =
typename BiS::difference_type;
216 void swap(
self& other) noexcept {
218 EAGINE_ASSERT(_ptr == other._ptr);
219 swap(_pos, other._pos);
222 auto operator++() noexcept -> auto& {
224 return *
static_cast<derived*
>(
this);
227 auto operator++(
int) noexcept ->
const derived {
228 derived that = *
static_cast<derived*
>(
this);
233 auto operator--() noexcept -> auto& {
235 return *
static_cast<derived*
>(
this);
238 auto operator--(
int) noexcept ->
const derived {
239 derived that = *
static_cast<derived*
>(
this);
244 auto operator+=(size_type n) noexcept ->
auto& {
246 return *
static_cast<derived*
>(
this);
249 auto operator-=(size_type n) noexcept ->
auto& {
251 return *
static_cast<derived*
>(
this);
254 friend auto operator+(
const self& a, difference_type n) noexcept {
255 return derived(*a._ptr, a._pos + n);
258 friend auto operator+(difference_type n,
const self& a) noexcept {
259 return derived(*a._ptr, n + a._pos);
262 friend auto operator-(
const self& a, difference_type n) noexcept {
263 return derived(*a._ptr, a._pos - n);
266 friend auto operator-(
const self& a,
const self& b) noexcept
268 return a._pos - b._pos;
271 friend constexpr
auto operator==(
const self& a,
const self& b) noexcept {
272 return _cmp(a, b) == 0;
275 friend constexpr
auto operator!=(
const self& a,
const self& b) noexcept {
276 return _cmp(a, b) != 0;
279 friend constexpr
auto operator<(
const self& a,
const self& b) noexcept {
280 return _cmp(a, b) < 0;
283 friend constexpr
auto operator<=(
const self& a,
const self& b) noexcept {
284 return _cmp(a, b) <= 0;
287 friend constexpr
auto operator>(
const self& a,
const self& b) noexcept {
288 return _cmp(a, b) > 0;
291 friend constexpr
auto operator>=(
const self& a,
const self& b) noexcept {
292 return _cmp(a, b) >= 0;
296 constexpr biteset_iterator_base(BiS& bs, size_type pos) noexcept
300 constexpr biteset_iterator_base() noexcept = default;
302 constexpr auto is_valid() const noexcept {
303 return (_ptr !=
nullptr) && (_pos < _ptr->size());
306 static constexpr
auto _cmp(
const self& a,
const self& b) noexcept
308 return EAGINE_CONSTEXPR_ASSERT(
309 (a._ptr !=
nullptr) && (a._ptr == b._ptr), a._pos - b._pos);
316 template <
typename BiS>
318 swap(biteset_iterator_base<BiS>& a, biteset_iterator_base<BiS>& b) noexcept {
322 template <std::
size_t N, std::
size_t B,
typename T>
323 class biteset_iterator<const biteset<N, B, T>>
324 :
public biteset_iterator_base<const biteset<N, B, T>> {
325 using _base = biteset_iterator_base<const biteset<N, B, T>>;
328 using _base::is_valid;
334 using const_proxy = biteset_value_proxy<const biteset<N, B, T>>;
335 using reference = const_proxy;
336 using const_reference = const_proxy;
337 using pointer = const_proxy;
338 using const_pointer = const_proxy;
339 using iterator_category = std::random_access_iterator_tag;
340 using self = biteset_iterator;
342 constexpr biteset_iterator(
343 const biteset<N, B, T>& bs,
344 size_type pos) noexcept
347 constexpr biteset_iterator() =
default;
349 constexpr
auto operator*() const noexcept -> const_proxy {
350 return EAGINE_CONSTEXPR_ASSERT(is_valid(), const_proxy(*_ptr, _pos));
357 template <std::
size_t N, std::
size_t B,
typename T>
359 :
public biteset_iterator_base<biteset<N, B, T>> {
360 using _base = biteset_iterator_base<biteset<N, B, T>>;
364 using _base::is_valid;
367 using self = biteset_iterator;
384 constexpr biteset_iterator() noexcept = default;
386 constexpr auto operator*() noexcept -> proxy {
387 return EAGINE_CONSTEXPR_ASSERT(is_valid(), proxy(*_ptr, _pos));
390 constexpr
auto operator*() const noexcept -> const_proxy {
391 return EAGINE_CONSTEXPR_ASSERT(is_valid(), const_proxy(*_ptr, _pos));
394 constexpr
auto operator->() noexcept -> proxy {
395 return EAGINE_CONSTEXPR_ASSERT(is_valid(), proxy(*_ptr, _pos));
398 auto operator->() const noexcept -> const_proxy {
399 return EAGINE_CONSTEXPR_ASSERT(is_valid(), const_proxy(*_ptr, _pos));
409 template <std::
size_t N, std::
size_t B,
typename T>
412 static constexpr
const std::size_t store_size =
413 ((N * B) / CHAR_BIT) + (((N * B) % CHAR_BIT != 0) ? 1 : 0);
416 using _bytes_t = byteset<store_size>;
419 static constexpr
const std::size_t _bite_s = B;
421 static constexpr
const std::size_t _byte_s = CHAR_BIT;
423 static constexpr
const std::size_t _cell_s =
sizeof(T) * CHAR_BIT;
426 static_assert((B > 0),
"bite size must be greater than zero");
427 static_assert((N > 0),
"bite count must be greater than zero");
429 (_cell_s >= _bite_s),
430 "bite with B bits size does not fit into type T");
431 static_assert(std::is_integral_v<T>,
"T must be integral type");
449 constexpr
biteset() noexcept = default;
454 typename = std::enable_if_t<
455 (sizeof...(P) == N) &&
456 std::conjunction_v<std::true_type, std::is_convertible<P, T>...>>>
458 : _bytes{_make_bytes(T(p)...)} {}
460 explicit constexpr
biteset(_bytes_t init) noexcept
464 template <
typename UIntT>
478 return _get_cell(std::size_t(i));
484 _set_cell(std::size_t(i), value);
520 friend constexpr
auto
522 return a.bytes() == b.bytes();
526 friend constexpr
auto
528 return a.bytes() != b.bytes();
532 friend constexpr
auto
534 return a.bytes() < b.bytes();
538 friend constexpr
auto
540 return a.bytes() <= b.bytes();
544 friend constexpr
auto
546 return a.bytes() > b.bytes();
550 friend constexpr
auto
552 return a.bytes() >= b.bytes();
563 static constexpr
auto _min_s(std::size_t x, std::size_t y) noexcept
565 return (x < y) ? x : y;
568 static constexpr
auto
569 _extract_init_bits(T init, std::size_t ofs, std::size_t len) noexcept
572 return static_cast<byte>(init >> (_bite_s - ofs - len)) &
574 static_cast<byte>((1U << len) - 1U);
577 template <std::
size_t L>
578 static constexpr
auto _do_get_byte_bits(
587 size_constant<L>) noexcept {
588 return _get_byte_bits(
590 static_cast<byte>(state << bl) |
591 _extract_init_bits(cb < N ? init[cb] : T(0), bo, bl),
596 size_constant<L + 1>{});
599 static constexpr
auto _get_byte_bits(
606 size_constant<_byte_s>) noexcept {
610 template <std::
size_t L>
611 static constexpr
auto _get_byte_bits(
618 size_constant<L> l) noexcept {
625 _min_s((be - bb), (_bite_s - (bb - cb * _bite_s))),
633 static constexpr
auto
634 _get_byte_bits(
const T (&init)[N], std::size_t bb, std::size_t be) noexcept {
635 return _get_byte_bits(
636 init,
byte(0), bb, be, bb / _bite_s, be / _bite_s, size_constant<1>{});
639 static constexpr
auto _get_byte(
const T (&init)[N], std::size_t i) noexcept {
640 return (B == _byte_s)
641 ?
static_cast<byte>(init[i])
642 : _get_byte_bits(init, (i + 0) * _byte_s, (i + 1) * _byte_s);
645 static constexpr
auto
646 _extract_cell_bits(
byte by, std::size_t ofs, std::size_t len) noexcept
649 return T(by >> (_byte_s - ofs - len)) & T((1 << len) - 1);
652 template <std::
size_t L>
653 constexpr
auto _do_get_cell_bits(
661 size_constant<L>)
const noexcept -> T {
662 return _get_cell_bits(
663 T(state << bl) | _extract_cell_bits(_bytes[
size_type(cb)], bo, bl),
668 size_constant<L + 1>{});
671 static constexpr
auto _get_cell_bits(
677 size_constant<_byte_s>) noexcept -> T {
681 template <std::
size_t L>
682 constexpr
auto _get_cell_bits(
688 size_constant<L> l)
const noexcept -> T {
694 _min_s((be - bb), (_byte_s - (bb - cb * _byte_s))),
702 constexpr
auto _get_cell_bits(std::size_t bb, std::size_t be)
const noexcept
704 return _get_cell_bits(
705 byte(0), bb, be, bb / _byte_s, be / _byte_s, size_constant<1>{});
708 constexpr
auto _get_cell(std::size_t i)
const noexcept -> T {
709 return (B == _byte_s)
711 : _get_cell_bits((i + 0) * _bite_s, (i + 1) * _bite_s);
714 static constexpr
void
715 _store_cell_bits(T v,
byte& by, std::size_t ofs, std::size_t len) noexcept {
718 static_cast<byte>(((1U << len) - 1U) << (_byte_s - ofs - len));
721 by |= (v << (_byte_s - ofs - len));
724 template <std::
size_t L>
725 void _do_set_cell_bits(
733 size_constant<L>) noexcept {
735 (state >> (_cell_s - bl)), _bytes[
size_type(cb)], bo, bl);
736 return _set_cell_bits(
737 T(state << bl), bb + bl, be, cb + 1, ce, size_constant<L + 1>{});
740 static constexpr
void _set_cell_bits(
746 size_constant<_byte_s>) noexcept {}
748 template <std::
size_t L>
755 size_constant<L> l) noexcept {
760 _min_s((be - bb), (_byte_s - (bb - cb * _byte_s))),
769 void _set_cell_bits(T state, std::size_t bb, std::size_t be) noexcept {
770 return _set_cell_bits(
771 state, bb, be, bb / _byte_s, be / _byte_s, size_constant<1>{});
774 void _set_cell(std::size_t i, T value) noexcept {
779 T(value << (_cell_s - _bite_s)),
785 template <std::size_t... I>
786 static constexpr
auto
787 _do_make_bytes(
const T (&init)[N], std::index_sequence<I...>) noexcept {
788 return _bytes_t{_get_byte(init, size_constant<I>{})...};
791 template <
typename... P>
792 static constexpr
auto _make_bytes(P... p) noexcept {
793 return _do_make_bytes(
794 {T(p)...}, std::make_index_sequence<store_size>{});
800 #endif // EAGINE_BITESET_HPP
constexpr friend auto operator==(const self &a, const self &b) noexcept
Equality comparison.
Definition: biteset.hpp:105
value_type
Value tree value element data type enumeration.
Definition: interface.hpp:27
auto begin() const noexcept -> const_iterator
Returns an iterator to the start of the sequence.
Definition: biteset.hpp:488
constexpr friend auto operator==(const biteset &a, const biteset &b) noexcept
Equality comparison.
Definition: biteset.hpp:521
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
biteset_iterator< const biteset > const_iterator
Alias for const iterator type.
Definition: biteset.hpp:446
static constexpr auto operator>=(const valid_if< T, P1 > &v1, const valid_if< T, P2 > &v2) noexcept -> tribool
Greater-equal comparison of two conditionally valid values.
Definition: decl.hpp:213
void set(size_type i, T value) noexcept
Sets the i-th element in this biteset.
Definition: biteset.hpp:483
static constexpr auto operator>(const valid_if< T, P1 > &v1, const valid_if< T, P2 > &v2) noexcept -> tribool
Greater-than comparison of two conditionally valid values.
Definition: decl.hpp:191
constexpr friend auto operator>(const self &a, const self &b) noexcept
Greater-than comparison.
Definition: biteset.hpp:125
Common code is placed in this namespace.
Definition: eagine.hpp:21
constexpr auto get(size_type i) const noexcept
Returns the i-th element in this biteset.
Definition: biteset.hpp:477
static constexpr auto operator<=(const valid_if< T, P1 > &v1, const valid_if< T, P2 > &v2) noexcept -> tribool
Less-equal comparison of two conditionally valid values.
Definition: decl.hpp:202
constexpr biteset() noexcept=default
Default constructor.
auto operator=(const T &v) noexcept -> self &
Assigns the specified value to the referenceb biteset element.
Definition: biteset.hpp:193
Specialization of biteset proxy for const biteset values.
Definition: biteset.hpp:144
constexpr friend auto operator<=(const biteset &a, const biteset &b) noexcept
Less-equal comparison.
Definition: biteset.hpp:539
constexpr friend auto operator<=(const self &a, const self &b) noexcept
Less-equal comparison.
Definition: biteset.hpp:120
constexpr friend auto operator<(const self &a, const self &b) noexcept
Less-than comparison.
Definition: biteset.hpp:115
static constexpr auto from_value(UIntT init) noexcept
Constructs a biteset from the specified values splitting bit groups of size=B.
Definition: biteset.hpp:465
biteset_iterator< biteset > iterator
Alias for iterator type.
Definition: biteset.hpp:443
constexpr auto bytes() const noexcept -> const byteset< store_size > &
Converts this biteset into a byteset.
Definition: biteset.hpp:556
span_size_t difference_type
Alias for difference type.
Definition: biteset.hpp:437
constexpr auto size() const noexcept -> size_type
Returns the number of elements in this biteset.
Definition: biteset.hpp:471
std::random_access_iterator_tag iterator_category
Iterator category.
Definition: biteset.hpp:379
T value_type
Alias for element value type.
Definition: biteset.hpp:440
static auto operator+(const fixed_size_string< N1 > &s1, const fixed_size_string< N2 > &s2) noexcept
Concatenation operator for fixed_size_string.
Definition: fixed_size_str.hpp:135
constexpr auto operator[](size_type i) noexcept -> biteset_value_proxy< biteset >
Subscript operator.
Definition: biteset.hpp:514
static constexpr auto operator!=(const valid_if< T, P1 > &v1, const valid_if< T, P2 > &v2) noexcept -> tribool
Non-equality comparison of two conditionally valid values.
Definition: decl.hpp:169
unsigned char byte
Byte type alias.
Definition: types.hpp:24
constexpr friend auto operator>=(const self &a, const self &b) noexcept
Greater-equal comparison.
Definition: biteset.hpp:130
auto end() const noexcept -> const_iterator
Returns an iterator past the end of the sequence.
Definition: biteset.hpp:493
constexpr friend auto operator>=(const biteset &a, const biteset &b) noexcept
Greater-equal comparison.
Definition: biteset.hpp:551
constexpr friend auto operator!=(const self &a, const self &b) noexcept
Non-equality comparison.
Definition: biteset.hpp:110
Specialization of biteset proxy for mutable biteset values.
Definition: biteset.hpp:163
constexpr friend auto operator<(const biteset &a, const biteset &b) noexcept
Less-than comparison.
Definition: biteset.hpp:533
std::conditional_t<(B<=8), std::uint_least8_t, std::conditional_t<(B<=16), std::uint_least16_t, std::conditional_t<(B<=32), std::uint_least32_t, std::conditional_t<(B<=64), std::uint_least64_t, void > >> > biteset_cell_type
Selects the appropriate type for biteset element representation.
Definition: biteset.hpp:36
void set(value_type val) noexcept
Sets the value of the referenced biteset element.
Definition: biteset.hpp:82
constexpr friend auto operator>(const biteset &a, const biteset &b) noexcept
Greater-than comparison.
Definition: biteset.hpp:545
auto operator==(message_id l, static_message_id< ClassId, MethodId > r) noexcept
Equality comparison between message_id and static_message_id.
Definition: message_id.hpp:131
auto begin() noexcept -> iterator
Returns a const iterator to the start of the sequence.
Definition: biteset.hpp:498
constexpr auto operator[](size_type i) const noexcept -> biteset_value_proxy< const biteset >
Subscript operator.
Definition: biteset.hpp:508
auto end() noexcept -> iterator
Returns a const iterator past the end of the sequence.
Definition: biteset.hpp:503
typename biteset< N, B, T > ::size_type size_type
Alias for size type.
Definition: biteset.hpp:57
Proxy class that can be used to access elements in a biteset.
Definition: biteset.hpp:46
typename biteset< N, B, T > ::value_type value_type
Alias for element value type.
Definition: biteset.hpp:60
Sequence of unsigned integer values with specified number bits.
Definition: biteset.hpp:39
Base class for biteset value proxy.
Definition: biteset.hpp:54
span_size_t size_type
Alias for size type.
Definition: biteset.hpp:434
static constexpr auto operator<(const valid_if< T, P1 > &v1, const valid_if< T, P2 > &v2) noexcept -> tribool
Less-than comparison of two conditionally valid values.
Definition: decl.hpp:180
constexpr auto get() const noexcept -> value_type
Gets the value of the referenced biteset element.
Definition: biteset.hpp:76
constexpr auto is_valid() const noexcept -> bool
Indicates if this is a valid proxy object that can be used for access.
Definition: biteset.hpp:70
constexpr friend auto operator!=(const biteset &a, const biteset &b) noexcept
Non-equality comparison.
Definition: biteset.hpp:527