Embedded Template Library 1.0
Loading...
Searching...
No Matches
bitset_legacy.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_BITSET_LEGACY_INCLUDED
32#define ETL_BITSET_LEGACY_INCLUDED
33
34#include "../platform.h"
35#include "../algorithm.h"
36#include "../binary.h"
37#include "../char_traits.h"
38#include "../error_handler.h"
39#include "../exception.h"
40#include "../integral_limits.h"
41#include "../iterator.h"
42#include "../log.h"
43#include "../nullptr.h"
44#include "../span.h"
45#include "../static_assert.h"
46#include "../string.h"
47
48#include <stddef.h>
49#include <stdint.h>
50#include <string.h>
51
52#include "minmax_push.h"
53
54#if defined(ETL_COMPILER_KEIL)
55 #pragma diag_suppress 1300
56#endif
57
58#if ETL_USING_CPP11
59 #define ETL_STR(x) x
60 #define ETL_STRL(x) L##x
61 #define ETL_STRu(x) u##x
62 #define ETL_STRU(x) U##x
63#else
64 #define ETL_STR(x) x
65 #define ETL_STRL(x) x
66 #define ETL_STRu(x) x
67 #define ETL_STRU(x) x
68#endif
69
70//*****************************************************************************
74//*****************************************************************************
75
76namespace etl
77{
78 //***************************************************************************
81 //***************************************************************************
82 class bitset_exception : public etl::exception
83 {
84 public:
85
86 bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
87 : exception(reason_, file_name_, line_number_)
88 {
89 }
90 };
91
92 //***************************************************************************
95 //***************************************************************************
96 class bitset_nullptr : public bitset_exception
97 {
98 public:
99
100 bitset_nullptr(string_type file_name_, numeric_type line_number_)
101 : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_)
102 {
103 }
104 };
105
106 //***************************************************************************
109 //***************************************************************************
110 class bitset_type_too_small : public bitset_exception
111 {
112 public:
113
114 bitset_type_too_small(string_type file_name_, numeric_type line_number_)
115 : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_)
116 {
117 }
118 };
119
120 //***************************************************************************
123 //***************************************************************************
124 class bitset_overflow : public bitset_exception
125 {
126 public:
127
128 bitset_overflow(string_type file_name_, numeric_type line_number_)
129 : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_)
130 {
131 }
132 };
133
134 //*************************************************************************
137 //*************************************************************************
139 {
140 protected:
141
142 // The type used for each element in the array.
143#if !defined(ETL_BITSET_ELEMENT_TYPE)
144 #define ETL_BITSET_ELEMENT_TYPE uint_least8_t
145#endif
146
147 public:
148
149 typedef size_t size_type;
150
151 typedef typename etl::make_unsigned<ETL_BITSET_ELEMENT_TYPE>::type element_type;
152 typedef element_type element_t; // Backward compatibility
153
154 static ETL_CONSTANT element_type ALL_SET = etl::integral_limits<element_type>::max;
155 static ETL_CONSTANT element_type ALL_CLEAR = 0;
156
157 static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits<element_type>::bits;
158
159#if ETL_USING_CPP11
160 typedef etl::span<element_type> span_type;
161 typedef etl::span<const element_type> const_span_type;
162#endif
163
164 enum
165 {
167 };
168
169 //*************************************************************************
171 //*************************************************************************
173 {
174 public:
175
176 friend class ibitset;
177
178 //*******************************
180 //*******************************
181 operator bool() const
182 {
183 return p_bitset->test(position);
184 }
185
186 //*******************************
188 //*******************************
190 : p_bitset(other.p_bitset)
191 , position(other.position)
192 {
193 }
194
195 //*******************************
197 //*******************************
199 {
200 p_bitset->set(position, b);
201 return *this;
202 }
203
204 //*******************************
206 //*******************************
208 {
209 p_bitset->set(position, bool(r));
210 return *this;
211 }
212
213 //*******************************
215 //*******************************
217 {
218 p_bitset->flip(position);
219 return *this;
220 }
221
222 //*******************************
224 //*******************************
225 bool operator~() const
226 {
227 return !p_bitset->test(position);
228 }
229
230 private:
231
232 //*******************************
234 //*******************************
236 : p_bitset(ETL_NULLPTR)
237 , position(0)
238 {
239 }
240
241 //*******************************
243 //*******************************
244 bit_reference(ibitset& r_bitset, size_t position_)
245 : p_bitset(&r_bitset)
246 , position(position_)
247 {
248 }
249
250 ibitset* p_bitset;
251 size_t position;
252 };
253
254 //*************************************************************************
256 //*************************************************************************
257 size_t size() const
258 {
259 return Active_Bits;
260 }
261
262 //*************************************************************************
264 //*************************************************************************
265 size_t count() const
266 {
267 size_t n = 0UL;
268
269 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
270 {
271 n += etl::count_bits(pdata[i]);
272 }
273
274 return n;
275 }
276
277 //*************************************************************************
281 //*************************************************************************
282 bool test(size_t position) const
283 {
284 ETL_ASSERT_OR_RETURN_VALUE(position < Active_Bits, ETL_ERROR(bitset_overflow), false);
285 size_t index;
286 element_type mask;
287
288 if (position >= Active_Bits)
289 {
290 return false;
291 }
292 if (Number_Of_Elements == 0)
293 {
294 return false;
295 }
296 else if (Number_Of_Elements == 1)
297 {
298 index = 0;
299 mask = element_type(1) << position;
300 }
301 else
302 {
303 index = position >> etl::log2<Bits_Per_Element>::value;
304 mask = element_type(1) << (position & (Bits_Per_Element - 1));
305 }
306
307 return (pdata[index] & mask) != 0;
308 }
309
310 //*************************************************************************
312 //*************************************************************************
314 {
315 etl::fill_n(pdata, Number_Of_Elements - 1U, ALL_SET);
316 pdata[Number_Of_Elements - 1U] = Top_Mask;
317
318 return *this;
319 }
320
321 //*************************************************************************
323 //*************************************************************************
324 ibitset& set(size_t position, bool value = true)
325 {
326 ETL_ASSERT_OR_RETURN_VALUE(position < Active_Bits, ETL_ERROR(bitset_overflow), *this);
327 size_t index;
328 element_type bit;
329
330 if (position < Active_Bits)
331 {
332 if (Number_Of_Elements == 0)
333 {
334 return *this;
335 }
336 else if (Number_Of_Elements == 1)
337 {
338 index = 0;
339 bit = element_type(1) << position;
340 }
341 else
342 {
343 index = position >> etl::log2<Bits_Per_Element>::value;
344 bit = element_type(1) << (position & (Bits_Per_Element - 1));
345 }
346
347 if (value)
348 {
349 pdata[index] |= bit;
350 }
351 else
352 {
353 pdata[index] &= ~bit;
354 }
355 }
356
357 return *this;
358 }
359
360 //*************************************************************************
362 //*************************************************************************
363 ibitset& from_string(const char* text)
364 {
365 reset();
366
367 size_t i = etl::min(Active_Bits, etl::strlen(text));
368
369 while (i > 0)
370 {
371 set(--i, *text++ == ETL_STRL('1'));
372 }
373
374 return *this;
375 }
376
377 //*************************************************************************
379 //*************************************************************************
380 ibitset& from_string(const wchar_t* text)
381 {
382 reset();
383
384 size_t i = etl::min(Active_Bits, etl::strlen(text));
385
386 while (i > 0)
387 {
388 set(--i, *text++ == ETL_STRL('1'));
389 }
390
391 return *this;
392 }
393
394 //*************************************************************************
396 //*************************************************************************
397 ibitset& from_string(const char16_t* text)
398 {
399 reset();
400
401 size_t i = etl::min(Active_Bits, etl::strlen(text));
402
403 while (i > 0)
404 {
405 set(--i, *text++ == ETL_STRu('1'));
406 }
407
408 return *this;
409 }
410
411 //*************************************************************************
413 //*************************************************************************
414 ibitset& from_string(const char32_t* text)
415 {
416 reset();
417
418 size_t i = etl::min(Active_Bits, etl::strlen(text));
419
420 while (i > 0)
421 {
422 set(--i, *text++ == ETL_STRU('1'));
423 }
424
425 return *this;
426 }
427
428 //*************************************************************************
430 //*************************************************************************
431 ibitset& set(const char* text)
432 {
433 if (text == ETL_NULLPTR)
434 {
435 reset();
436 }
437 else
438 {
439 from_string(text);
440 }
441
442 return *this;
443 }
444
445 //*************************************************************************
447 //*************************************************************************
448 ibitset& set(const wchar_t* text)
449 {
450 if (text == ETL_NULLPTR)
451 {
452 reset();
453 }
454 else
455 {
456 from_string(text);
457 }
458
459 return *this;
460 }
461
462 //*************************************************************************
464 //*************************************************************************
465 ibitset& set(const char16_t* text)
466 {
467 if (text == ETL_NULLPTR)
468 {
469 reset();
470 }
471 else
472 {
473 from_string(text);
474 }
475
476 return *this;
477 }
478
479 //*************************************************************************
481 //*************************************************************************
482 ibitset& set(const char32_t* text)
483 {
484 if (text == ETL_NULLPTR)
485 {
486 reset();
487 }
488 else
489 {
490 from_string(text);
491 }
492
493 return *this;
494 }
495
496 //*************************************************************************
498 //*************************************************************************
499 template <typename T>
500 typename etl::enable_if<etl::is_integral<T>::value, T>::type value() const
501 {
502 T v = T(0);
503
504 const bool OK = (sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element);
505
506 ETL_ASSERT_OR_RETURN_VALUE(OK, ETL_ERROR(etl::bitset_type_too_small), T(0));
507
508 if (OK)
509 {
510 uint_least8_t shift = 0U;
511
512 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
513 {
514 v |= T(typename etl::make_unsigned<T>::type(pdata[i]) << shift);
515 shift += uint_least8_t(Bits_Per_Element);
516 }
517 }
518
519 return v;
520 }
521
522 //*************************************************************************
524 //*************************************************************************
525 unsigned long to_ulong() const
526 {
527 return value<unsigned long>();
528 }
529
530 //*************************************************************************
532 //*************************************************************************
533 unsigned long long to_ullong() const
534 {
536 }
537
538 //*************************************************************************
540 //*************************************************************************
542 {
543 etl::fill_n(pdata, Number_Of_Elements, ALL_CLEAR);
544
545 return *this;
546 }
547
548 //*************************************************************************
550 //*************************************************************************
551 ibitset& reset(size_t position)
552 {
553 ETL_ASSERT_OR_RETURN_VALUE(position < Active_Bits, ETL_ERROR(bitset_overflow), *this);
554 size_t index;
555 element_type bit;
556
557 if (position < Active_Bits)
558 {
559 if (Number_Of_Elements == 0)
560 {
561 return *this;
562 }
563 else if (Number_Of_Elements == 1)
564 {
565 index = 0;
566 bit = element_type(1) << position;
567 }
568 else
569 {
570 index = position >> etl::log2<Bits_Per_Element>::value;
571 bit = element_type(1) << (position & (Bits_Per_Element - 1));
572 }
573
574 pdata[index] &= ~bit;
575 }
576
577 return *this;
578 }
579
580 //*************************************************************************
582 //*************************************************************************
584 {
585 etl::transform_n(pdata, Number_Of_Elements, pdata, etl::binary_not<element_type>());
586
587 clear_unused_bits_in_msb();
588
589 return *this;
590 }
591
592 //*************************************************************************
594 //*************************************************************************
595 ibitset& flip(size_t position)
596 {
597 ETL_ASSERT_OR_RETURN_VALUE(position < Active_Bits, ETL_ERROR(bitset_overflow), *this);
598 size_t index;
599 element_type bit;
600
601 if (Number_Of_Elements == 0)
602 {
603 return *this;
604 }
605 else if (Number_Of_Elements == 1)
606 {
607 index = 0;
608 bit = element_type(1) << position;
609 }
610 else
611 {
612 index = position >> log2<Bits_Per_Element>::value;
613 bit = element_type(1) << (position & (Bits_Per_Element - 1));
614 }
615
616 pdata[index] ^= bit;
617
618 return *this;
619 }
620
621 //*************************************************************************
622 // Are all the bits sets?
623 //*************************************************************************
624 bool all() const
625 {
626 if (Number_Of_Elements == 0UL)
627 {
628 return true;
629 }
630
631 // All but the last.
632 for (size_t i = 0UL; i < (Number_Of_Elements - 1U); ++i)
633 {
634 if (pdata[i] != ALL_SET)
635 {
636 return false;
637 }
638 }
639
640 // The last.
641 if (pdata[Number_Of_Elements - 1U] != (ALL_SET & Top_Mask))
642 {
643 return false;
644 }
645
646 return true;
647 }
648
649 //*************************************************************************
651 //*************************************************************************
652 bool any() const
653 {
654 return !none();
655 }
656
657 //*************************************************************************
659 //*************************************************************************
660 bool none() const
661 {
662 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
663 {
664 if (pdata[i] != 0)
665 {
666 return false;
667 }
668 }
669
670 return true;
671 }
672
673 //*************************************************************************
678 //*************************************************************************
679 size_t find_first(bool state) const
680 {
681 return find_next(state, 0);
682 }
683
684 //*************************************************************************
689 //*************************************************************************
690 size_t find_next(bool state, size_t position) const
691 {
692 // Where to start.
693 size_t index;
694 size_t bit;
695
696 if (Number_Of_Elements == 0)
697 {
698 return ibitset::npos;
699 }
700 else if (Number_Of_Elements == 1)
701 {
702 index = 0;
703 bit = position;
704 }
705 else
706 {
707 index = position >> log2<Bits_Per_Element>::value;
708 bit = position & (Bits_Per_Element - 1);
709 }
710
711 element_type mask = 1 << bit;
712
713 // For each element in the bitset...
714 while (index < Number_Of_Elements)
715 {
716 element_type value = pdata[index];
717
718 // Needs checking?
719 if ((state && (value != ALL_CLEAR)) || (!state && (value != ALL_SET)))
720 {
721 // For each bit in the element...
722 while ((bit < Bits_Per_Element) && (position < Active_Bits))
723 {
724 // Equal to the required state?
725 if (((value & mask) != 0) == state)
726 {
727 return position;
728 }
729
730 // Move on to the next bit.
731 mask <<= 1;
732 ++position;
733 ++bit;
734 }
735 }
736 else
737 {
738 position += (Bits_Per_Element - bit);
739 }
740
741 // Start at the beginning for all other elements.
742 bit = 0;
743 mask = 1;
744
745 ++index;
746 }
747
748 return ibitset::npos;
749 }
750
751 //*************************************************************************
753 //*************************************************************************
754 bool operator[](size_t position) const
755 {
756 return test(position);
757 }
758
759 //*************************************************************************
761 //*************************************************************************
762 bit_reference operator[](size_t position)
763 {
764 return bit_reference(*this, position);
765 }
766
767 //*************************************************************************
769 //*************************************************************************
771 {
772 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
773 {
774 pdata[i] &= other.pdata[i];
775 }
776
777 return *this;
778 }
779
780 //*************************************************************************
782 //*************************************************************************
784 {
785 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
786 {
787 pdata[i] |= other.pdata[i];
788 }
789
790 return *this;
791 }
792
793 //*************************************************************************
795 //*************************************************************************
797 {
798 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
799 {
800 pdata[i] ^= other.pdata[i];
801 }
802
803 return *this;
804 }
805
806 //*************************************************************************
808 //*************************************************************************
809 ibitset& operator<<=(size_t shift)
810 {
811 if (shift >= Active_Bits)
812 {
813 reset();
814 }
815 else if (Number_Of_Elements != 0UL)
816 {
817 // Just one element?
818 if (Number_Of_Elements == 1UL)
819 {
820 pdata[0] <<= shift;
821 }
822 else if (shift == Bits_Per_Element)
823 {
824 etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements);
825 pdata[0] = 0;
826 }
827 else
828 {
829 // The place where the elements are split when shifting.
830 const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element);
831
832 // Where we are shifting from.
833 int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U);
834
835 // Where we are shifting to.
836 int dst_index = int(Number_Of_Elements - 1U);
837
838 // Shift control constants.
839 const size_t lsb_shift = Bits_Per_Element - split_position;
840 const size_t msb_shift = split_position;
841
842 const element_type lsb_mask = element_type(etl::integral_limits<element_type>::max >> (Bits_Per_Element - split_position));
844 const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift);
845
846 // First lsb.
847 element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift);
848 pdata[dst_index] = lsb;
849 --src_index;
850
851 // Now do the shifting.
852 while (src_index >= 0)
853 {
854 // Shift msb.
855 element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift);
856 pdata[dst_index] = pdata[dst_index] | msb;
857 --dst_index;
858
859 // Shift lsb.
860 lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift);
861 pdata[dst_index] = lsb;
862 --src_index;
863 }
864
865 // Clear the remaining bits.
866 // First lsb.
867 pdata[dst_index] &= lsb_shifted_mask;
868 --dst_index;
869
870 // The other remaining elements.
871 for (int i = 0; i <= dst_index; ++i)
872 {
873 pdata[i] = 0;
874 }
875 }
876
877 // Truncate any bits shifted to the left.
878 clear_unused_bits_in_msb();
879 }
880
881 return *this;
882 }
883
884 //*************************************************************************
886 //*************************************************************************
887 ibitset& operator>>=(size_t shift)
888 {
889 if (shift >= Active_Bits)
890 {
891 reset();
892 }
893 else if (Number_Of_Elements != 0UL)
894 {
895 // Just one element?
896 if (Number_Of_Elements == 1UL)
897 {
898 pdata[0] >>= shift;
899 }
900 // Shift is the size of an element?
901 else if (shift == Bits_Per_Element)
902 {
903 etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata);
904 pdata[Number_Of_Elements - 1U] = 0;
905 }
906 else
907 {
908 // The place where the elements are split when shifting.
909 const size_t split_position = shift % Bits_Per_Element;
910
911 // Where we are shifting from.
912 int src_index = int(shift / Bits_Per_Element);
913
914 // Where we are shifting to.
915 int dst_index = 0;
916
917 // Shift control constants.
918 const size_t lsb_shift = Bits_Per_Element - split_position;
919 const size_t msb_shift = split_position;
920
921 const element_type lsb_mask = element_type(etl::integral_limits<element_type>::max >> (Bits_Per_Element - split_position));
923 const element_type msb_shifted_mask = element_type(msb_mask >> msb_shift);
924
925 // Now do the shifting.
926 while (src_index < int(Number_Of_Elements - 1))
927 {
928 // Shift msb.
929 element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift);
930 ++src_index;
931
932 // Shift lsb.
933 element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift);
934
935 // Combine them.
936 pdata[dst_index] = lsb | msb;
937 ++dst_index;
938 }
939
940 // Final msb.
941 element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift);
942 pdata[dst_index] = msb;
943
944 // Clear the remaining bits.
945 // First msb.
946 pdata[dst_index] &= msb_shifted_mask;
947 ++dst_index;
948
949 // The other remaining elements.
950 for (int i = dst_index; i < int(Number_Of_Elements); ++i)
951 {
952 pdata[i] = 0;
953 }
954 }
955 }
956
957 return *this;
958 }
959
960 //*************************************************************************
962 //*************************************************************************
963 ibitset& operator=(const ibitset& other)
964 {
965 if (this != &other)
966 {
967 etl::copy_n(other.pdata, Number_Of_Elements, pdata);
968 }
969
970 return *this;
971 }
972
973 //*************************************************************************
975 //*************************************************************************
976 void swap(ibitset& other)
977 {
978 etl::swap_ranges(pdata, pdata + Number_Of_Elements, other.pdata);
979 }
980
981#if ETL_USING_CPP11
982 //*************************************************************************
985 //*************************************************************************
986 span_type span()
987 {
988 return span_type(pdata, pdata + Number_Of_Elements);
989 }
990
991 //*************************************************************************
994 //*************************************************************************
995 const_span_type span() const
996 {
997 return const_span_type(pdata, pdata + Number_Of_Elements);
998 }
999#endif
1000
1001 protected:
1002
1003 //*************************************************************************
1005 //*************************************************************************
1006 ibitset& initialise(unsigned long long value)
1007 {
1008 reset();
1009
1010 const size_t Shift = (integral_limits<unsigned long long>::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element;
1011
1012 // Can we do it in one hit?
1013 if (Shift == 0)
1014 {
1015 pdata[0] = element_type(value);
1016 }
1017 else
1018 {
1019 size_t i = 0UL;
1020
1021 while ((value != 0) && (i < Number_Of_Elements))
1022 {
1023 pdata[i++] = value & ALL_SET;
1024 value = value >> Shift;
1025 }
1026 }
1027
1028 clear_unused_bits_in_msb();
1029
1030 return *this;
1031 }
1032
1033 //*************************************************************************
1035 //*************************************************************************
1036 void invert()
1037 {
1038 for (size_t i = 0UL; i < Number_Of_Elements; ++i)
1039 {
1040 pdata[i] = ~pdata[i];
1041 }
1042
1043 clear_unused_bits_in_msb();
1044 }
1045
1046 //*************************************************************************
1048 //*************************************************************************
1050 {
1051 return bit_reference(*this, position);
1052 }
1053
1054 //*************************************************************************
1056 //*************************************************************************
1057 ibitset(size_t nbits_, size_t size_, element_type* pdata_)
1058 : Active_Bits(nbits_)
1059 , Number_Of_Elements(size_)
1060 , pdata(pdata_)
1061 {
1062 const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element;
1063 const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Active_Bits)) % Bits_Per_Element);
1064 Top_Mask = element_type(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift));
1065 }
1066
1067 //*************************************************************************
1069 //*************************************************************************
1070 static bool is_equal(const ibitset& lhs, const ibitset& rhs)
1071 {
1072 return etl::equal(lhs.pdata, lhs.pdata + lhs.Number_Of_Elements, rhs.pdata);
1073 }
1074
1075 element_type Top_Mask;
1076
1077 private:
1078
1079 //*************************************************************************
1081 //*************************************************************************
1082 void clear_unused_bits_in_msb()
1083 {
1084 pdata[Number_Of_Elements - 1U] &= Top_Mask;
1085 }
1086
1087 // Disable copy construction.
1088 ibitset(const ibitset&);
1089
1090 const size_t Active_Bits;
1091 const size_t Number_Of_Elements;
1092 element_type* pdata;
1093
1094 //*************************************************************************
1096 //*************************************************************************
1097#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS)
1098
1099 public:
1100
1101 virtual ~ibitset() {}
1102#else
1103
1104 protected:
1105
1107#endif
1108 };
1109
1110 ETL_CONSTANT ibitset::element_type ibitset::ALL_SET;
1111
1112 ETL_CONSTANT ibitset::element_type ibitset::ALL_CLEAR;
1113
1114 ETL_CONSTANT size_t ibitset::Bits_Per_Element;
1115
1116 //*************************************************************************
1121 //*************************************************************************
1122 template <size_t MaxN>
1123 class bitset : public etl::ibitset
1124 {
1125 static ETL_CONSTANT size_t Array_Size = (MaxN % Bits_Per_Element == 0) ? MaxN / Bits_Per_Element : MaxN / Bits_Per_Element + 1;
1126
1127 public:
1128
1129 static ETL_CONSTANT size_t ALLOCATED_BITS = Array_Size * Bits_Per_Element;
1130 static ETL_CONSTANT size_t Allocated_Bits = ALLOCATED_BITS;
1131
1132 public:
1133
1134 //*************************************************************************
1136 //*************************************************************************
1138 : etl::ibitset(MaxN, Array_Size, data)
1139 {
1140 reset();
1141 }
1142
1143 //*************************************************************************
1145 //*************************************************************************
1146 bitset(const bitset<MaxN>& other)
1147 : etl::ibitset(MaxN, Array_Size, data)
1148 {
1149 etl::copy_n(other.data, Array_Size, data);
1150 }
1151
1152 //*************************************************************************
1154 //*************************************************************************
1155 bitset(unsigned long long value)
1156 : etl::ibitset(MaxN, Array_Size, data)
1157 {
1159 }
1160
1161 //*************************************************************************
1163 //*************************************************************************
1164 bitset(const char* text)
1165 : etl::ibitset(MaxN, Array_Size, data)
1166 {
1167 set(text);
1168 }
1169
1170 //*************************************************************************
1172 //*************************************************************************
1173 bitset(const wchar_t* text)
1174 : etl::ibitset(MaxN, Array_Size, data)
1175 {
1176 set(text);
1177 }
1178
1179 //*************************************************************************
1181 //*************************************************************************
1182 bitset(const char16_t* text)
1183 : etl::ibitset(MaxN, Array_Size, data)
1184 {
1185 set(text);
1186 }
1187
1188 //*************************************************************************
1190 //*************************************************************************
1191 bitset(const char32_t* text)
1192 : etl::ibitset(MaxN, Array_Size, data)
1193 {
1194 set(text);
1195 }
1196
1197 //*************************************************************************
1199 //*************************************************************************
1201 {
1203 return *this;
1204 }
1205
1206 //*************************************************************************
1208 //*************************************************************************
1209 bitset<MaxN>& set(size_t position, bool value = true)
1210 {
1211 etl::ibitset::set(position, value);
1212 return *this;
1213 }
1214
1215 //*************************************************************************
1217 //*************************************************************************
1218 bitset<MaxN>& set(const char* text)
1219 {
1220 etl::ibitset::set(text);
1221
1222 return *this;
1223 }
1224
1225 //*************************************************************************
1227 //*************************************************************************
1228 bitset<MaxN>& set(const wchar_t* text)
1229 {
1230 etl::ibitset::set(text);
1231
1232 return *this;
1233 }
1234
1235 //*************************************************************************
1237 //*************************************************************************
1238 bitset<MaxN>& set(const char16_t* text)
1239 {
1240 etl::ibitset::set(text);
1241
1242 return *this;
1243 }
1244
1245 //*************************************************************************
1247 //*************************************************************************
1248 bitset<MaxN>& set(const char32_t* text)
1249 {
1250 etl::ibitset::set(text);
1251
1252 return *this;
1253 }
1254
1255 //*************************************************************************
1257 //*************************************************************************
1258 bitset<MaxN>& from_string(const char* text)
1259 {
1261
1262 return *this;
1263 }
1264
1265 //*************************************************************************
1267 //*************************************************************************
1268 bitset<MaxN>& from_string(const wchar_t* text)
1269 {
1271
1272 return *this;
1273 }
1274
1275 //*************************************************************************
1277 //*************************************************************************
1278 bitset<MaxN>& from_string(const char16_t* text)
1279 {
1281
1282 return *this;
1283 }
1284
1285 //*************************************************************************
1287 //*************************************************************************
1288 bitset<MaxN>& from_string(const char32_t* text)
1289 {
1291
1292 return *this;
1293 }
1294
1295 //*************************************************************************
1297 //*************************************************************************
1298 template <typename T>
1299 typename etl::enable_if<etl::is_integral<T>::value, T>::type value() const
1300 {
1301 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Only integral types are supported");
1302 ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Array_Size * Bits_Per_Element), "Type too small");
1303
1304 return ibitset::value<T>();
1305 }
1306
1307 //*************************************************************************
1309 //*************************************************************************
1311 {
1313 return *this;
1314 }
1315
1316 //*************************************************************************
1318 //*************************************************************************
1319 bitset<MaxN>& reset(size_t position)
1320 {
1321 etl::ibitset::reset(position);
1322 return *this;
1323 }
1324
1325 //*************************************************************************
1327 //*************************************************************************
1329 {
1330 ibitset::flip();
1331 return *this;
1332 }
1333
1334 //*************************************************************************
1336 //*************************************************************************
1337 bitset<MaxN>& flip(size_t position)
1338 {
1339 etl::ibitset::flip(position);
1340 return *this;
1341 }
1342
1343 //*************************************************************************
1345 //*************************************************************************
1346#if ETL_USING_CPP11
1347 template <typename TString = etl::string<MaxN>>
1348#else
1349 template <typename TString>
1350#endif
1351 TString to_string(typename TString::value_type zero = typename TString::value_type('0'),
1352 typename TString::value_type one = typename TString::value_type('1')) const
1353 {
1354 TString result;
1355
1356 result.resize(MaxN, '\0');
1357
1358 ETL_ASSERT_OR_RETURN_VALUE((result.size() == MaxN), ETL_ERROR(etl::bitset_overflow), result);
1359
1360 for (size_t i = MaxN; i > 0; --i)
1361 {
1362 result[MaxN - i] = test(i - 1) ? one : zero;
1363 }
1364
1365 return result;
1366 }
1367
1368 //*************************************************************************
1370 //*************************************************************************
1372 {
1373 if (this != &other)
1374 {
1375 etl::copy_n(other.data, Array_Size, data);
1376 }
1377
1378 return *this;
1379 }
1380
1381 //*************************************************************************
1383 //*************************************************************************
1385 {
1387 return *this;
1388 }
1389
1390 //*************************************************************************
1392 //*************************************************************************
1394 {
1396 return *this;
1397 }
1398
1399 //*************************************************************************
1401 //*************************************************************************
1403 {
1404 ibitset::operator^=(other);
1405 return *this;
1406 }
1407
1408 //*************************************************************************
1410 //*************************************************************************
1412 {
1413 etl::bitset<MaxN> temp(*this);
1414
1415 temp.invert();
1416
1417 return temp;
1418 }
1419
1420 //*************************************************************************
1422 //*************************************************************************
1423 bitset<MaxN> operator<<(size_t shift) const
1424 {
1425 etl::bitset<MaxN> temp(*this);
1426
1427 temp <<= shift;
1428
1429 return temp;
1430 }
1431
1432 //*************************************************************************
1434 //*************************************************************************
1435 bitset<MaxN>& operator<<=(size_t shift)
1436 {
1438 return *this;
1439 }
1440
1441 //*************************************************************************
1443 //*************************************************************************
1444 bitset<MaxN> operator>>(size_t shift) const
1445 {
1446 bitset<MaxN> temp(*this);
1447
1448 temp >>= shift;
1449
1450 return temp;
1451 }
1452
1453 //*************************************************************************
1455 //*************************************************************************
1457 {
1459 return *this;
1460 }
1461
1462 //*************************************************************************
1464 //*************************************************************************
1465 friend bool operator==(const bitset<MaxN>& lhs, const bitset<MaxN>& rhs)
1466 {
1467 return etl::ibitset::is_equal(lhs, rhs);
1468 }
1469
1470 private:
1471
1472 element_type data[Array_Size > 0U ? Array_Size : 1U];
1473 };
1474
1475 template <size_t MaxN>
1476 ETL_CONSTANT size_t bitset<MaxN>::ALLOCATED_BITS;
1477
1478 template <size_t MaxN>
1479 ETL_CONSTANT size_t bitset<MaxN>::Allocated_Bits;
1480
1481 //***************************************************************************
1484 //***************************************************************************
1485 template <size_t MaxN>
1487 {
1488 bitset<MaxN> temp(lhs);
1489 temp &= rhs;
1490 return temp;
1491 }
1492
1493 //***************************************************************************
1496 //***************************************************************************
1497 template <size_t MaxN>
1499 {
1500 bitset<MaxN> temp(lhs);
1501 temp |= rhs;
1502 return temp;
1503 }
1504
1505 //***************************************************************************
1508 //***************************************************************************
1509 template <size_t MaxN>
1511 {
1512 bitset<MaxN> temp(lhs);
1513 temp ^= rhs;
1514 return temp;
1515 }
1516
1517 //***************************************************************************
1520 //***************************************************************************
1521 template <size_t MaxN>
1522 bool operator!=(const bitset<MaxN>& lhs, const bitset<MaxN>& rhs)
1523 {
1524 return !(lhs == rhs);
1525 }
1526} // namespace etl
1527
1528//*************************************************************************
1530//*************************************************************************
1531template <size_t MaxN>
1533{
1534 lhs.swap(rhs);
1535}
1536
1537#include "minmax_pop.h"
1538
1539#endif
void swap(etl::bitset< MaxN > &lhs, etl::bitset< MaxN > &rhs)
swap
Definition bitset_legacy.h:1532
The reference type returned.
Definition bitset_legacy.h:173
bit_reference & operator=(const bit_reference &r)
Assignment operator.
Definition bitset_legacy.h:207
bool operator~() const
Return the logical inverse of the bit.
Definition bitset_legacy.h:225
bit_reference(const bit_reference &other)
Copy constructor.
Definition bitset_legacy.h:189
bit_reference & operator=(bool b)
Assignment operator.
Definition bitset_legacy.h:198
bit_reference & flip()
Flip the bit.
Definition bitset_legacy.h:216
Definition binary.h:2196
Definition binary.h:2228
Span - Fixed Extent.
Definition span.h:208
ETL_CONSTEXPR14 void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function)
Definition algorithm.h:2960
ETL_CONSTEXPR14 etl::enable_if< etl::is_integral< T >::value &&etl::is_unsigned< T >::value &&(etl::integral_limits< T >::bits==16U), uint_least8_t >::type count_bits(T value)
Definition binary.h:918
Definition binary.h:2263
Definition binary.h:356
etl::enable_if< etl::is_integral< T >::value, T >::type value() const
Put to a value.
Definition bitset_legacy.h:500
ibitset & set()
Set all bits.
Definition bitset_legacy.h:313
bitset< MaxN > & set(size_t position, bool value=true)
Set the bit at the position.
Definition bitset_legacy.h:1209
ibitset & reset()
Resets the bitset.
Definition bitset_legacy.h:541
bitset< MaxN > & operator&=(const bitset< MaxN > &other)
operator &=
Definition bitset_legacy.h:1384
bitset(const char16_t *text)
Construct from a string.
Definition bitset_legacy.h:1182
size_t find_first(bool state) const
Definition bitset_legacy.h:679
size_t find_next(bool state, size_t position) const
Definition bitset_legacy.h:690
ibitset & initialise(unsigned long long value)
Initialise from an unsigned long long.
Definition bitset_legacy.h:1006
ibitset & from_string(const char16_t *text)
Set from a u16 string.
Definition bitset_legacy.h:397
bool any() const
Are any of the bits set?
Definition bitset_legacy.h:652
~ibitset()
Destructor.
Definition bitset_legacy.h:1106
friend bool operator==(const bitset< MaxN > &lhs, const bitset< MaxN > &rhs)
operator ==
Definition bitset_legacy.h:1465
bitset< MaxN > & flip()
Flip all of the bits.
Definition bitset_legacy.h:1328
bit_reference get_bit_reference(size_t position)
Gets a reference to the specified bit.
Definition bitset_legacy.h:1049
ibitset & operator|=(const ibitset &other)
operator |=
Definition bitset_legacy.h:783
bitset(const bitset< MaxN > &other)
Copy constructor.
Definition bitset_legacy.h:1146
ibitset(size_t nbits_, size_t size_, element_type *pdata_)
Constructor.
Definition bitset_legacy.h:1057
bitset< MaxN > & set(const char32_t *text)
Set from a string.
Definition bitset_legacy.h:1248
bitset< MaxN > & set(const wchar_t *text)
Set from a string.
Definition bitset_legacy.h:1228
bitset(const char *text)
Construct from a string.
Definition bitset_legacy.h:1164
void swap(ibitset &other)
swap
Definition bitset_legacy.h:976
ibitset & operator=(const ibitset &other)
operator =
Definition bitset_legacy.h:963
bitset< MaxN > & reset()
Reset all of the bits.
Definition bitset_legacy.h:1310
bitset(const wchar_t *text)
Construct from a string.
Definition bitset_legacy.h:1173
bit_reference operator[](size_t position)
Write [] operator.
Definition bitset_legacy.h:762
ibitset & operator>>=(size_t shift)
operator >>=
Definition bitset_legacy.h:887
ibitset & operator^=(const ibitset &other)
operator ^=
Definition bitset_legacy.h:796
etl::enable_if< etl::is_integral< T >::value, T >::type value() const
Put to a value.
Definition bitset_legacy.h:1299
bitset(unsigned long long value)
Construct from a value.
Definition bitset_legacy.h:1155
ETL_CONSTEXPR14 void swap(etl::bitset< Active_Bits, TElement > &other) ETL_NOEXCEPT
swap
Definition bitset_new.h:2454
bitset< MaxN > & reset(size_t position)
Reset the bit at the position.
Definition bitset_legacy.h:1319
size_t count() const
Count the number of bits set.
Definition bitset_legacy.h:265
ibitset & from_string(const wchar_t *text)
Set from a wide string.
Definition bitset_legacy.h:380
TString to_string(typename TString::value_type zero=typename TString::value_type('0'), typename TString::value_type one=typename TString::value_type('1')) const
Returns a string representing the bitset.
Definition bitset_legacy.h:1351
ibitset & set(const char32_t *text)
Set from a u32string.
Definition bitset_legacy.h:482
ibitset & from_string(const char32_t *text)
Set from a u32 string.
Definition bitset_legacy.h:414
ibitset & set(size_t position, bool value=true)
Set the bit at the position.
Definition bitset_legacy.h:324
ibitset & flip()
Flip all of the bits.
Definition bitset_legacy.h:583
bitset(const char32_t *text)
Construct from a string.
Definition bitset_legacy.h:1191
ibitset & operator&=(const ibitset &other)
operator &=
Definition bitset_legacy.h:770
bitset< MaxN > & from_string(const wchar_t *text)
Set from a wide string.
Definition bitset_legacy.h:1268
bitset< MaxN > & operator<<=(size_t shift)
operator <<=
Definition bitset_legacy.h:1435
bitset< MaxN > operator<<(size_t shift) const
operator <<
Definition bitset_legacy.h:1423
unsigned long to_ulong() const
Put to a unsigned long.
Definition bitset_legacy.h:525
bool operator[](size_t position) const
Read [] operator.
Definition bitset_legacy.h:754
unsigned long long to_ullong() const
Put to a unsigned long long.
Definition bitset_legacy.h:533
bitset< MaxN > & operator|=(const bitset< MaxN > &other)
operator |=
Definition bitset_legacy.h:1393
void invert()
Invert.
Definition bitset_legacy.h:1036
bitset()
Default constructor.
Definition bitset_legacy.h:1137
bitset< MaxN > operator~() const
operator ~
Definition bitset_legacy.h:1411
bitset< MaxN > operator>>(size_t shift) const
operator >>
Definition bitset_legacy.h:1444
bitset< MaxN > & from_string(const char16_t *text)
Set from a u16 string.
Definition bitset_legacy.h:1278
ibitset & reset(size_t position)
Reset the bit at the position.
Definition bitset_legacy.h:551
bitset< MaxN > & set(const char *text)
Set from a string.
Definition bitset_legacy.h:1218
ibitset & from_string(const char *text)
Set from a string.
Definition bitset_legacy.h:363
bitset< MaxN > & operator=(const bitset< MaxN > &other)
operator =
Definition bitset_legacy.h:1371
ibitset & set(const char16_t *text)
Set from a u16string.
Definition bitset_legacy.h:465
ibitset & set(const wchar_t *text)
Set from a wstring.
Definition bitset_legacy.h:448
ibitset & operator<<=(size_t shift)
operator <<=
Definition bitset_legacy.h:809
bitset< MaxN > & operator^=(const bitset< MaxN > &other)
operator ^=
Definition bitset_legacy.h:1402
ETL_CONSTEXPR14 bool test() const
Definition bitset_new.h:2091
bool none() const
Are none of the bits set?
Definition bitset_legacy.h:660
bitset< MaxN > & from_string(const char32_t *text)
Set from a u32 string.
Definition bitset_legacy.h:1288
bool test(size_t position) const
Definition bitset_legacy.h:282
size_t size() const
The number of bits in the bitset.
Definition bitset_legacy.h:257
bitset< MaxN > & set(const char16_t *text)
Set from a string.
Definition bitset_legacy.h:1238
ibitset & flip(size_t position)
Flip the bit at the position.
Definition bitset_legacy.h:595
bitset< MaxN > & flip(size_t position)
Flip the bit at the position.
Definition bitset_legacy.h:1337
ibitset & set(const char *text)
Set from a string.
Definition bitset_legacy.h:431
bitset< MaxN > & set()
Set all of the bits.
Definition bitset_legacy.h:1200
bitset< MaxN > & operator>>=(size_t shift)
operator >>=
Definition bitset_legacy.h:1456
static bool is_equal(const ibitset &lhs, const ibitset &rhs)
Compare bitsets.
Definition bitset_legacy.h:1070
bitset< MaxN > & from_string(const char *text)
Set from a string.
Definition bitset_legacy.h:1258
Bitset forward declaration.
Definition bitset_legacy.h:1124
Definition bitset_legacy.h:125
Definition bitset_legacy.h:111
Definition bitset_legacy.h:139
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
Definition integral_limits.h:518
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
etl::byte operator|(etl::byte lhs, etl::byte rhs)
Or.
Definition byte.h:250
etl::byte operator&(etl::byte lhs, etl::byte rhs)
And.
Definition byte.h:258
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
etl::byte operator^(etl::byte lhs, etl::byte rhs)
Exclusive Or.
Definition byte.h:266
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:293