├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── flags
│ └── flags.ino
└── test
│ └── test.ino
├── keywords.txt
├── library.properties
└── src
├── BitFlags.h
└── BitPack.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/BitPack/releases/latest/download/BitPack.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/BitPack)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/BitPack?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # BitPack
10 | Библиотека для упаковки битовых флагов в байтовый массив (экономия места) для Arduino
11 |
12 | ### Совместимость
13 | Совместима со всеми Arduino платформами (используются Arduino-функции)
14 |
15 | ## Содержание
16 | - [Инициализация](#init)
17 | - [Использование](#usage)
18 | - [Пример](#example)
19 | - [Версии](#versions)
20 | - [Установка](#install)
21 | - [Баги и обратная связь](#feedback)
22 |
23 |
24 | ## Инициализация
25 |
26 | ```cpp
27 | // указываем количество флагов
28 | BitPack<10> pack; // static буфер внутри
29 | BitPackDyn pack(10); // динамическое выделение
30 |
31 | uint8_t buf[2]; // 1 байт - 8 флагов
32 | BitPackExt pack(buf, 10); // 10 флагов
33 | ```
34 |
35 |
36 | ## Использование
37 |
38 | ```cpp
39 | // методы
40 | void set(uint16_t num); // установить
41 | void clear(uint16_t num); // сбросить
42 | void toggle(uint16_t num); // переключить
43 | void write(uint16_t num, bool state); // записать
44 | bool read(uint16_t num); // прочитать
45 | void setAll(); // установить все
46 | void clearAll(); // сбросить все
47 | bool copyTo(любой пак); // копировать в
48 | bool copyFrom(любой пак); // копировать из
49 |
50 | uint16_t amount(); // количество флагов
51 | uint16_t size(); // размер pack в байтах
52 |
53 | uint8_t* pack; // доступ к буферу
54 |
55 | // макросы
56 | BP_SET(pack, idx)
57 | BP_CLEAR(pack, idx)
58 | BP_READ(pack, idx)
59 | BP_TOGGLE(pack, idx)
60 | BP_WRITE(pack, idx)
61 |
62 | // настройки (до подключения библиотеки)
63 | #define BP_NO_ARRAY // убрать доступ через [] - экономит 2 байта RAM
64 | ```
65 |
66 | #### BitPackExt
67 | ```cpp
68 | BitPackExt() {}
69 |
70 | // передать буфер и его размер в количестве флагов (8 флагов - 1 байт)
71 | BitPackExt(uint8_t* pack, uint16_t amount, bool clear = true);
72 |
73 | // передать буфер и его размер в количестве флагов (8 флагов - 1 байт)
74 | void setBuffer(uint8_t* pack, uint16_t amount, bool clear = true);
75 | ```
76 |
77 | #### BitPackDyn
78 | ```cpp
79 | BitPackDyn() {}
80 |
81 | // указать количество флагов
82 | BitPackDyn(uint16_t amount);
83 |
84 | // указать количество флагов
85 | void init(uint16_t amount);
86 | ```
87 |
88 | ### Доступ через []
89 | В библиотеке реализован удобный доступ к битам через образение как к массиву `[]`. Этот способ *чуть медленнее* использования функций set/read/write!
90 | ```cpp
91 | BitPack<10> flags;
92 | flags[0] = 1;
93 | Serial.println(flags[0]);
94 | bool f = flags[0];
95 |
96 | BitPack<10> flags2;
97 | flags[0] = flags2[0];
98 |
99 | // примечание:
100 | // такое приравнивание некорректно! Используй copyTo/copyFrom
101 | flags = flags2;
102 |
103 | flags.copyTo(flags2); // копировать весь пакет
104 | ```
105 |
106 | ### BitFlags
107 | ```cpp
108 | // пакет флагов
109 | T flags = 0;
110 |
111 | // прочитать бит
112 | bool read(const T x);
113 |
114 | // установить биты маской
115 | void set(const T x);
116 |
117 | // очистить биты маской
118 | void clear(const T x);
119 |
120 | // записать бит
121 | void write(const T x, const bool v);
122 |
123 | // получить маску
124 | T mask(const T x);
125 |
126 | // стоят все биты в маске
127 | bool isSet(const T x);
128 |
129 | // очищены все биты в маске
130 | bool isClear(const T x);
131 |
132 | // сравнить маску со значением
133 | bool compare(const T x, const T y);
134 | ```
135 |
136 | Ещё три пакета фиксированного количества флагов `BitFlags8`, `BitFlags16`, `BitFlags32` на 8/16/32 флагов соответственно. Они работают чуть иначе, как регистры. Можно ставить и читать несколько флагов за одно действие, что сильно повышает производительность. Для удобства можно объявить флаги как биты:
137 | ```cpp
138 | #define MY_FLAG_0 bit(0)
139 | #define KEK_FLAG bit(1)
140 | #define SOME_F bit(2)
141 |
142 | BitFlags8 flags;
143 | flags.set(KEK_FLAG | SOME_F); // установить два флага
144 | if (flags.read(KEK_FLAG | SOME_F)); // проверить два флага
145 |
146 | // операция compare берёт маску по первому аргументу и сравнивает со вторым
147 | // фактически смысл такой: определение ситуации, когда из указанных флагов подняты только определённые
148 | // здесь - из флагов KEK_FLAG и SOME_F поднят только SOME_F (KEK_FLAG опущен)
149 | if (flags.compare(KEK_FLAG | SOME_F, SOME_F));
150 | ```
151 |
152 |
153 | ## Пример
154 | Остальные примеры смотри в **examples**!
155 |
156 | ```cpp
157 | #include "BitPack.h"
158 |
159 | // указываем количество флагов
160 | BitPack<10> flags;
161 |
162 | void setup() {
163 | Serial.begin(9600);
164 | flags.clearAll(); // опустить все
165 | flags.set(1); // поднять флаг
166 | flags.set(3);
167 | flags.write(3, 1);
168 | Serial.println(flags.read(0)); // прочитать флаг
169 | Serial.println(flags.read(1));
170 | Serial.println(flags.read(2));
171 |
172 | flags[3] = 0; // можно писать через []
173 | Serial.println(flags[3]); // можно читать через []
174 |
175 | BitPack<10> flags2;
176 | flags[0] = flags2[1]; // копировать бит
177 | flags.copyTo(flags2); // копировать весь пакет
178 | }
179 |
180 | void loop() {
181 | }
182 | ```
183 |
184 |
185 |
186 | ## Версии
187 | - v1.0
188 | - v1.1 - пофикшен доступ через [], добавлены новые инструменты
189 | - v1.1.1 - перезалив
190 | - v1.2 - добавлены copy методы, упрощён доступ через массив
191 | - v1.3 - добавлена отдельная инициализация для BitPackExt и BitPackDyn
192 | - v1.3.1 - добавлен copy и move конструктор для BitPackDyn. Добавлены инструменты BitFlags8, BitFlags16, BitFlags32
193 |
194 |
195 | ## Установка
196 | - Библиотеку можно найти по названию **BitPack** и установить через менеджер библиотек в:
197 | - Arduino IDE
198 | - Arduino IDE v2
199 | - PlatformIO
200 | - [Скачать библиотеку](https://github.com/GyverLibs/BitPack/archive/refs/heads/main.zip) .zip архивом для ручной установки:
201 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
202 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
203 | - Распаковать и положить в *Документы/Arduino/libraries/*
204 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
205 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
206 | ### Обновление
207 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
208 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
209 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
210 |
211 |
212 | ## Баги и обратная связь
213 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
214 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
215 |
216 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
217 | - Версия библиотеки
218 | - Какой используется МК
219 | - Версия SDK (для ESP)
220 | - Версия Arduino IDE
221 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
222 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
223 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
224 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Bitpack
4 | Library for packing bit flags in the byte array (saving space) for Arduino
5 |
6 | ## compatibility
7 | Compatible with all arduino platforms (used arduino functions)
8 |
9 | ## Content
10 | - [initialization] (#init)
11 | - [use] (#usage)
12 | - [Example] (# Example)
13 | - [versions] (#varsions)
14 | - [installation] (# Install)
15 | - [bugs and feedback] (#fedback)
16 |
17 |
18 | ## initialization
19 |
20 | `` `CPP
21 | // indicate the number of flags
22 | Bitpack <10> Pack;// static buffer inside
23 | Bitpackdyn Pack (10);// Dynamic discharge
24 |
25 | uint8_t buf [2];// 1 byte - 8 flags
26 | Bitpackext Pack (BUF, 10);// 10 flags
27 | `` `
28 |
29 |
30 | ## Usage
31 |
32 | `` `CPP
33 | // Methods
34 | VOID set (uint8_t num);// install
35 | Void Clear (Uint8_t Num);// reset
36 | VOID TOGGLE (UINT8_T NUM);// switch
37 | VOID Write (Uint8_t Num, Bool State);// Record
38 | Bool Read (uint8_t num);// Read
39 | VOID setall ();// install everything
40 | VOID CLEARALL ();// throw everything
41 | uint16_t amount ();// number of flags
42 | uint16_t size ();// Pack size in bytes
43 |
44 | uint8_t* pack;// access to the buffer
45 |
46 | // Macro
47 | BP_SET (PACK, IDX)
48 | BP_Clear (Pack, IDX)
49 | Bp_read (Pack, IDX)
50 | BP_TOGGLE (PACK, IDX)
51 | BP_WRITE (PACK, IDX)
52 |
53 | // Settings (before connecting the library)
54 | #define bp_no_arry // Remove access through [] - saves 2 bytes RAM
55 | `` `
56 |
57 |
58 | ## Example
59 | The rest of the examples look at ** Examples **!
60 |
61 | `` `CPP
62 | #include "Bitpack.h"
63 |
64 | // indicate the number of flags
65 | Bitpack <10> Flags;
66 |
67 | VOID setup () {
68 | Serial.Begin (9600);
69 | Flags.clerall ();// lower everything
70 | Flags.Set (1);// raise the flag
71 | Flags.Set (3);
72 | Flags.write (3, 1);
73 | Serial.println (Flags.read (0));// Read the flag
74 | Serial.println (Flags.read (1));
75 | Serial.println (Flags.read (2));
76 |
77 | Flags [3] = 0;// can be written through []
78 | Serial.println (Flags [3]);// can be read through []
79 | }
80 |
81 | VOID loop () {
82 | }
83 | `` `
84 |
85 |
86 |
87 | ## versions
88 | - V1.0
89 | - v1.1 - access for [], new tools have been added
90 | - V1.1.1 - REB
91 |
92 |
93 | ## Installation
94 | - The library can be found by the name ** bitpack ** and installed through the library manager in:
95 | - Arduino ide
96 | - Arduino ide v2
97 | - Platformio
98 | - [download the library] (https://github.com/gyverlibs/bitpack/archive/refs/heads/main.zip). Zip archive for manual installation:
99 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
100 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
101 | - unpack and put in *documents/arduino/libraries/ *
102 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
103 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
104 | ### Update
105 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
106 | - Through the IDE library manager:Find the library how to install and click "update"
107 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
108 |
109 |
110 | ## bugs and feedback
111 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
112 | The library is open for refinement and your ** pull Request ** 'ow!
113 |
114 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
115 | - The version of the library
116 | - What is MK used
117 | - SDK version (for ESP)
118 | - version of Arduino ide
119 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
120 | - what code has been loaded, what work was expected from it and how it works in reality
121 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/flags/flags.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define MY_FLAG_0 bit(0)
5 | #define KEK_FLAG bit(1)
6 | #define SOME_F bit(2)
7 |
8 | enum class Flags {
9 | f1 = bit(0),
10 | f2 = bit(1),
11 | f3 = bit(2),
12 | };
13 |
14 | void setup() {
15 | Serial.begin(115200);
16 | {
17 | BitFlags8 f;
18 | f.set(Flags::f1);
19 | f.set(Flags::f2);
20 |
21 | Serial.println(f.read(Flags::f1));
22 | Serial.println(f.read(Flags::f2));
23 | Serial.println(f.read(Flags::f3));
24 | }
25 | {
26 | BitFlags8 flags;
27 | flags.set(KEK_FLAG | SOME_F); // установить два флага
28 | Serial.println(flags.read(KEK_FLAG | SOME_F)); // стоит один из флагов
29 | Serial.println(flags.isSet(KEK_FLAG | SOME_F)); // стоят все флаги
30 |
31 | // операция compare берёт маску по первому аргументу и сравнивает со вторым
32 | // фактически смысл такой: определение ситуации, когда из указанных флагов подняты только определённые
33 | // здесь - из флагов KEK_FLAG и SOME_F поднят только SOME_F (KEK_FLAG опущен)
34 | Serial.println(flags.compare(KEK_FLAG | SOME_F, SOME_F));
35 | }
36 | }
37 |
38 | void loop() {
39 | }
--------------------------------------------------------------------------------
/examples/test/test.ino:
--------------------------------------------------------------------------------
1 | #include "BitPack.h"
2 |
3 | // указываем количество флагов
4 | BitPack<10> flags;
5 |
6 | void setup() {
7 | Serial.begin(9600);
8 | flags.clearAll(); // опустить все
9 | flags.set(1); // поднять флаг
10 | flags.set(3);
11 | flags.write(3, 1);
12 | Serial.println(flags.read(0)); // прочитать флаг
13 | Serial.println(flags.read(1));
14 | Serial.println(flags.read(2));
15 | flags[3] = 0; // можно писать через []
16 | Serial.println(flags[3]); // можно читать через []
17 | }
18 |
19 | void loop() {
20 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For BitPack
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | BitPack KEYWORD1
10 | BitPackExt KEYWORD1
11 | BitPackDyn KEYWORD1
12 | BitFlags8 KEYWORD1
13 | BitFlags16 KEYWORD1
14 | BitFlags32 KEYWORD1
15 |
16 | #######################################
17 | # Methods and Functions (KEYWORD2)
18 | #######################################
19 |
20 | set KEYWORD2
21 | clear KEYWORD2
22 | toggle KEYWORD2
23 | write KEYWORD2
24 | read KEYWORD2
25 | setAll KEYWORD2
26 | clearAll KEYWORD2
27 | size KEYWORD2
28 | amount KEYWORD2
29 | copyTo KEYWORD2
30 | copyFrom KEYWORD2
31 | init KEYWORD2
32 | setBuffer KEYWORD2
33 | mask KEYWORD2
34 | compare KEYWORD2
35 |
36 | BP_BYTE KEYWORD2
37 | BP_BIT KEYWORD2
38 | BP_SET KEYWORD2
39 | BP_CLEAR KEYWORD2
40 | BP_READ KEYWORD2
41 | BP_TOGGLE KEYWORD2
42 | BP_WRITE KEYWORD2
43 |
44 | #######################################
45 | # Constants (LITERAL1)
46 | #######################################
47 |
48 | BP_NO_ARRAY LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=BitPack
2 | version=1.3.5
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Library for packing bit flags into byte array
6 | paragraph=Library for packing bit flags into byte array
7 | category=Data Processing
8 | url=https://github.com/GyverLibs/BitPack
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/src/BitFlags.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | // ================= BIT FLAGS =================
5 | template
6 | struct BitFlags {
7 | // пакет флагов
8 | T flags = 0;
9 |
10 | // прочитать бит
11 | template
12 | inline bool read(const T1 x) const {
13 | return flags & (T)x;
14 | }
15 |
16 | // установить биты маской
17 | template
18 | inline void set(const T1 x) {
19 | flags |= (T)x;
20 | }
21 |
22 | // очистить биты маской
23 | template
24 | inline void clear(const T1 x) {
25 | flags &= ~((T)x);
26 | }
27 |
28 | // записать бит
29 | template
30 | inline void write(const T1 x, const bool v) {
31 | v ? set(x) : clear(x);
32 | }
33 |
34 | // получить маску
35 | template
36 | inline T mask(const T1 x) const {
37 | return flags & (T)x;
38 | }
39 |
40 | // стоят все биты в маске
41 | template
42 | inline bool isSet(const T1 x) const {
43 | return (flags & (T)x) == (T)x;
44 | }
45 |
46 | // очищены все биты в маске
47 | template
48 | inline bool isClear(const T1 x) const {
49 | return !(flags & (T)x);
50 | }
51 |
52 | // сравнить маску со значением
53 | template
54 | inline bool compare(const T1 x, const T2 y) const {
55 | return (flags & (T)x) == (T)y;
56 | }
57 | };
58 |
59 | struct BitFlags8 : public BitFlags {};
60 | struct BitFlags16 : public BitFlags {};
61 | struct BitFlags32 : public BitFlags {};
--------------------------------------------------------------------------------
/src/BitPack.h:
--------------------------------------------------------------------------------
1 | /*
2 | BitPack - библиотека для упаковки битовых флагов в байтовый массив (экономия места)
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/BitPack
5 |
6 | AlexGyver, alex@alexgyver.ru
7 | https://alexgyver.ru/
8 | MIT License
9 | */
10 |
11 | #pragma once
12 | #include
13 | #include "BitFlags.h"
14 |
15 | #define BP_BYTE(pack, idx) pack[(idx) >> 3]
16 | #define BP_BIT(pack, idx) ((idx) & 0b111)
17 | #define BP_SET(pack, idx) (BP_BYTE(pack, idx) |= 1 << BP_BIT(pack, idx))
18 | #define BP_CLEAR(pack, idx) (BP_BYTE(pack, idx) &= ~(1 << BP_BIT(pack, idx)))
19 | #define BP_READ(pack, idx) ((BP_BYTE(pack, idx) >> BP_BIT(pack, idx)) & 1)
20 | #define BP_TOGGLE(pack, idx) (BP_BYTE(pack, idx) ^= 1 << BP_BIT(pack, idx))
21 | #define BP_WRITE(pack, idx, val) (val) ? BP_SET(pack, idx) : BP_CLEAR(pack, idx)
22 |
23 | // ============== STATIC PACK ==============
24 | template
25 | class BitPack {
26 | public:
27 | uint8_t pack[(flag_amount + 8 - 1) >> 3]; // round up
28 |
29 | BitPack() {
30 | clearAll();
31 | }
32 |
33 | // размер pack в байтах
34 | uint16_t size() const {
35 | return (flag_amount + 8 - 1) >> 3;
36 | }
37 |
38 | // количество флагов
39 | uint16_t amount() const {
40 | return flag_amount;
41 | }
42 |
43 | // установить
44 | void set(uint16_t idx) {
45 | if (idx < flag_amount) BP_SET(pack, idx);
46 | }
47 |
48 | // снять
49 | void clear(uint16_t idx) {
50 | if (idx < flag_amount) BP_CLEAR(pack, idx);
51 | }
52 |
53 | // инвертировать
54 | void toggle(uint16_t idx) {
55 | if (idx < flag_amount) BP_TOGGLE(pack, idx);
56 | }
57 |
58 | // записать
59 | void write(uint16_t idx, bool state) {
60 | if (idx < flag_amount) BP_WRITE(pack, idx, state);
61 | }
62 |
63 | // прочитать
64 | bool read(uint16_t idx) const {
65 | if (idx < flag_amount) return BP_READ(pack, idx);
66 | else return 0;
67 | }
68 |
69 | // установить все
70 | void setAll() {
71 | memset(pack, 255, size());
72 | }
73 |
74 | // очистить все
75 | void clearAll() {
76 | memset(pack, 0, size());
77 | }
78 |
79 | // копировать в
80 | bool copyTo(BitPack& bp) {
81 | if (amount() != bp.amount()) return 0;
82 | memcpy(bp.pack, pack, size());
83 | return 1;
84 | }
85 |
86 | // копировать из
87 | bool copyFrom(BitPack& bp) {
88 | if (amount() != bp.amount()) return 0;
89 | memcpy(pack, bp.pack, size());
90 | return 1;
91 | }
92 |
93 | #ifndef BP_NO_ARRAY
94 | BitPack& operator[](uint16_t idx) {
95 | _idx = idx;
96 | return *this;
97 | }
98 | void operator=(bool val) {
99 | write(_idx, val);
100 | }
101 | operator bool() const {
102 | return read(_idx);
103 | }
104 | void operator=(BitPack& bp) {
105 | write(_idx, (bool)bp);
106 | }
107 | #endif
108 |
109 | private:
110 | #ifndef BP_NO_ARRAY
111 | uint16_t _idx;
112 | #endif
113 | };
114 |
115 | // ============== EXTERNAL BUFFER ==============
116 | class BitPackExt {
117 | public:
118 | uint8_t* pack = nullptr;
119 |
120 | BitPackExt() {}
121 |
122 | // передать буфер и его размер в количестве флагов (8 флагов - 1 байт)
123 | BitPackExt(uint8_t* pack, uint16_t amount, bool clear = true) {
124 | setBuffer(pack, amount, clear);
125 | }
126 |
127 | // передать буфер и его размер в количестве флагов (8 флагов - 1 байт)
128 | void setBuffer(uint8_t* pack, uint16_t amount, bool clear = true) {
129 | this->pack = pack;
130 | this->_amount = amount;
131 | if (clear) clearAll();
132 | }
133 |
134 | // размер pack в байтах
135 | uint16_t size() const {
136 | return (_amount + 8 - 1) >> 3; // round up
137 | }
138 |
139 | // количество флагов
140 | uint16_t amount() const {
141 | return _amount;
142 | }
143 |
144 | // установить
145 | void set(uint16_t idx) {
146 | if (pack && idx < _amount) BP_SET(pack, idx);
147 | }
148 |
149 | // снять
150 | void clear(uint16_t idx) {
151 | if (pack && idx < _amount) BP_CLEAR(pack, idx);
152 | }
153 |
154 | // инвертировать
155 | void toggle(uint16_t idx) {
156 | if (pack && idx < _amount) BP_TOGGLE(pack, idx);
157 | }
158 |
159 | // записать
160 | void write(uint16_t idx, bool state) {
161 | if (pack && idx < _amount) BP_WRITE(pack, idx, state);
162 | }
163 |
164 | // прочитать
165 | bool read(uint16_t idx) const {
166 | if (pack && idx < _amount) return BP_READ(pack, idx);
167 | else return 0;
168 | }
169 |
170 | // установить все
171 | void setAll() {
172 | if (pack) memset(pack, 255, size());
173 | }
174 |
175 | // очистить все
176 | void clearAll() {
177 | if (pack) memset(pack, 0, size());
178 | }
179 |
180 | // копировать в
181 | bool copyTo(BitPackExt& bp) {
182 | if (!pack || amount() != bp.amount()) return 0;
183 | memcpy(bp.pack, pack, size());
184 | return 1;
185 | }
186 |
187 | // копировать из
188 | bool copyFrom(BitPackExt& bp) {
189 | if (!pack || amount() != bp.amount()) return 0;
190 | memcpy(pack, bp.pack, size());
191 | return 1;
192 | }
193 |
194 | #ifndef BP_NO_ARRAY
195 | BitPackExt& operator[](uint16_t idx) {
196 | _idx = idx;
197 | return *this;
198 | }
199 | void operator=(bool val) {
200 | write(_idx, val);
201 | }
202 | operator bool() const {
203 | return read(_idx);
204 | }
205 | void operator=(BitPackExt& bp) {
206 | write(_idx, (bool)bp);
207 | }
208 | #endif
209 |
210 | protected:
211 | uint16_t _amount;
212 |
213 | private:
214 | #ifndef BP_NO_ARRAY
215 | uint16_t _idx;
216 | #endif
217 | };
218 |
219 | // ============== DYNAMIC BUFFER ==============
220 | class BitPackDyn : public BitPackExt {
221 | public:
222 | BitPackDyn() {}
223 |
224 | // указать количество флагов
225 | BitPackDyn(uint16_t amount) {
226 | init(amount);
227 | }
228 |
229 | BitPackDyn(const BitPackDyn& val) {
230 | copy(val);
231 | }
232 | void operator=(const BitPackDyn& val) {
233 | copy(val);
234 | }
235 |
236 | #if __cplusplus >= 201103L
237 | BitPackDyn(BitPackExt&&) = delete;
238 | BitPackDyn& operator=(BitPackExt&&) = delete;
239 |
240 | BitPackDyn(BitPackDyn&& rval) noexcept {
241 | move(rval);
242 | }
243 | void operator=(BitPackDyn&& rval) noexcept {
244 | move(rval);
245 | }
246 | #endif
247 |
248 | ~BitPackDyn() {
249 | delete[] pack;
250 | }
251 |
252 | // указать количество флагов
253 | void init(uint16_t amount) {
254 | delete[] pack;
255 | _amount = amount; // need for size()
256 | pack = new uint8_t[size()];
257 | if (!pack) _amount = 0;
258 | clearAll();
259 | }
260 |
261 | // удалить буфер
262 | void reset() {
263 | delete[] pack;
264 | pack = nullptr;
265 | _amount = 0;
266 | }
267 |
268 | // копировать из
269 | void copy(const BitPackDyn& val) {
270 | if (this == &val || pack == val.pack) return;
271 | if (!val.pack) {
272 | reset();
273 | return;
274 | }
275 | memcpy(pack, val.pack, val.size());
276 | _amount = val._amount;
277 | }
278 |
279 | // переместить из
280 | void move(BitPackDyn& rval) noexcept {
281 | delete[] pack;
282 | pack = rval.pack;
283 | _amount = rval._amount;
284 | rval.pack = nullptr;
285 | }
286 | };
--------------------------------------------------------------------------------