Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // enum.c
- // Řešení IJC-DU1, příklad a), 20.3.2111
- // Autor: Jároslav Cimrman, FIT
- // Přeloženo: gcc 8.2
- // ...popis příkladu - poznámky, atd
- #include <limits.h>
- #include "error.h"
- #include <assert.h>
- #ifndef IJC_LIBRARY_H
- #define IJC_LIBRARY_H 1
- #define Bi_Me (sizeof(unsigned long)*__CHAR_BIT__)
- typedef unsigned long *bit_array_t;
- //Velikost pole, odečtením 1L se mohu spolehnout, že po zprůměrování budou dva longy navíc stačit.
- //Na uložení velikosti v prvním bloku + pro přesah do dalšího bloku, po celočíselném dělení)
- #define SIZE(velikost) ((velikost/Bi_Me) + ((velikost%Bi_Me) ? 2L : 1L))
- //Určení pozice jedničky v masce. Budu se posouvat zprava doleva, tedy jdu druhou stranou, než jak jdu v poli.
- #define post(index) (index%Bi_Me)
- //Určení správného bloku v poli. Je tvořeno unsigned longy, každý má osm bitů. Podle hodnoty indexu se posouvám po celých blocích.
- //Indexace jde od nuly, proto poslední bit má index "počet prvnků v poli" -1. První blok v poli je vynechán, drží hodnotu s velikostí pole.
- #define INX(jmeno_pole, index) ((SIZE(jmeno_pole[0]) - (index/Bi_Me)) - 1L)
- #define bit_array_create(jmeno_pole, velikost) unsigned long jmeno_pole[SIZE(velikost)] = {(velikost)};\
- _Static_assert((velikost) > 0 && (velikost) < (ULONG_MAX), "bit_array_create: Chybně zadaná velikost pole.\n");
- #define bit_array_alloc(jmeno_pole, velikost) assert((velikost) > 0 && (velikost) < (ULONG_MAX)); bit_array_t (jmeno_pole) = calloc(SIZE((velikost), Bi_Me));\
- if((jmeno_pole) == NULL) {bit_array_free(jmeno_pole); error_exit("bit_array_alloc: Chyba alokace paměti.\n");} (jmeno_pole[0]) = (velikost);
- #define bit_array_free(jmeno_pole) free((jmeno_pole))
- //Pomocné makro k funkci bit_array_setbit, po splnění podmínky rozsahu nastaví hodnotu v "jmeno_pole" na místě označené "index" na hodnotu "výraz"
- // Indexace probíhá od nuly. Správný blok a index v poli poskytují příslušná makra.
- #define bit_array_setbit_pom(jmeno_pole, index, vyraz) ((vyraz!=0) ? (jmeno_pole[INX(jmeno_pole, index)] |= (1L << post(index))) : \
- (((jmeno_pole)[INX(jmeno_pole, index)]) &= ~(1L << post(index))))
- //Pomocné makro k funkci bit_array_getbit, po splnění podmínky rozsahu vrátí hodnotu v "jmeno_pole" na místě označeném "index". Vrací hodnuty nula nebo jedna.
- //Indexace probíhá od nuly. Správný blok a index v poli poskytují příslušná makra.
- #define bit_array_getbit_pom(jmeno_pole, index) (((unsigned long)(jmeno_pole)[INX(jmeno_pole, index)]) & (1L << post(index)) ? 1 : 0)
- //Konec maker
- #ifndef USE_INLINE
- #define bit_array_size(jmeno_pole) (unsigned long)(jmeno_pole[0])
- #define bit_array_getbit(jmeno_pole, index) ((index) < (((jmeno_pole)[0]/Bi_Me) + ((jmeno_pole)[0]%Bi_Me) ? 1 : 0)) ? (bit_array_getbit_pom((jmeno_pole), (index))):\
- (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)(index), (unsigned long)bit_array_size(jmeno_pole)), -1)
- #define bit_array_setbit(jmeno_pole, index, vyraz) ((index) < (((jmeno_pole)[0]/Bi_Me) + ((jmeno_pole)[0]%Bi_Me) ? 1 : 0)) ? (bit_array_setbit_pom((jmeno_pole), (index), (vyraz))):\
- ((error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)(index), (unsigned long)bit_array_size(jmeno_pole)), -1)))
- //Konec inline funkcí
- #else
- inline int bit_array_getbit(bit_array_t jmeno_pole, unsigned long index){
- if(index+1 > jmeno_pole[0]){
- (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu",(unsigned long)index, (unsigned long)jmeno_pole[0]));
- return -1; //Vyletí už na error_exit
- }
- else{ return bit_array_getbit_pom(jmeno_pole, index); }
- }
- inline void bit_array_setbit(bit_array_t jmeno_pole, unsigned long index, int vyraz){
- if(index+1 > jmeno_pole[0]){
- (error_exit("bit_array_getbit: Index %lu mimo rozsah 0..%lu", (unsigned long)index, (unsigned long)jmeno_pole[0]));
- return;
- }
- else{ bit_array_setbit_pom(jmeno_pole, index, vyraz); }
- }
- inline unsigned long bit_array_size(bit_array_t jmeno_pole)
- {
- return (unsigned long)jmeno_pole[0];
- }
- #endif //Konec USE_INLINE
- #endif //Konec IJC_LIBRARY_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement