‟overcq”

Z bloga o OUX/C+

Menedżer tablic — “mem-tab.cx”

Jest to drugi po menedżerze bloków pamięci dostępny standardowo menedżer pamięci, jednak innego rodzaju. Przydziela on obiekt tablicy “E_mem_Q_tab”, który przechowuje nieliniowo w pamięci listę bloków, np. struktur języka C. Każdy z tych bloków ma identyfikator przechowywany w zmiennej typu I. Można tworzyć w tablicy nowe bloki, wyrzucać istniejace oraz wyliczać wszystkie w pętli.

Tablice zarządzane przez tego menedżera służą do przechowywania kolekcji obiektów wydawanych w czasie wykonywania się programu z innych menedżerów po identyfikatorze.

Obiekty tablicy tworzy się i wyrzuca następującymi procedurami:

struct E_mem_Q_tab_Z *
E_mem_Q_tab_M(
  N u
, I n
);
void
E_mem_Q_tab_W( struct E_mem_Q_tab_Z *tab
);

Procedura tworzenia obiektu bierze parametry: rozmiar obiektu tablicy oraz początkową liczbę obiektów. W przypadku niepowodzenia wraca ona z wartością 0, a w przeciwnym przypadku podaje adres obiektu tablicy.

Procedurami narzędziowymi można sprawdzić

Natomiast nowe elementy w tablicy można tworzyć procedurami:

I
E_mem_Q_tab_I_add( struct E_mem_Q_tab_Z *tab
);
I
E_mem_Q_tab_I_add_i( struct E_mem_Q_tab_Z *tab
, I id
);

Przy czym druga procedura dodaje element z podanym identyfikatorem, więc musi on być nie używany przed jej wywołaniem.

Elementy tablicy można wyrzucić procedurą:

N
E_mem_Q_tab_I_rem( struct E_mem_Q_tab_Z *tab
, I id
);

Iteratory

Menedżer tablic obsługuje też obiekty iteratorów dwóch rodzajów:

Statyczne

Pierwsze mają zastosowanie wtedy, gdy pomiędzy wyliczeniami takiego iteratora nie następuje przełączenie zadania, a drugie – wtedy, gdy takie przełączenie może nastąpić (oczywiście przy użyciu instrukcji przełączenia zadania).

Do wyliczania w pętli iteratorów statycznych istnieją instrukcje wbudowane “for_each”:

for_each( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
for_each_( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}

Druga z nich korzysta z już zdefiniowanej zmiennej identyfikatora.

Natomiast do wyliczania obiektu z pominięciem elementu o podanym identyfikatorze:

for_each_out( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
for_each_out_( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}

W przypadku obiektu tablicy opisywanego w tym wpisie instrukcje wyliczania w pętli iteratora statycznego mają następującą przykładową postać:

for_each( id, tab, E_mem_Q_tab ){}
for_each_out( out, id, tab, E_mem_Q_tab ){}

Są również procedury wyliczania iteratora od końca do początku:

for_each( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
for_each_( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
for_each_rev_out( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
for_each_rev_out_( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
Obiektowe

Natomiast iteratory obiektowe wymagają utworzenia obiektu iteratora i jego wyrzucenia po użyciu procedurami:

I
E_mem_Q_tab_Q_iter_M( struct E_mem_Q_tab_Z *tab
, I out_id
);
void
E_mem_Q_tab_Q_iter_W( struct E_mem_Q_tab_Z *tab
, I iterator_id
);

Procedura tworząca iterator bierze jako parametr identyfikator pomijanego elementu i wraca z identyfikatorem iteratora obiektowego albo wartością ~0 w przypadku niepowodzenia.

W każdym przypadku jako pomijany element można podać wartość ~0, kiedy to żaden element nie zostanie pominięty.

Kolejne elementy tablicy wylicza się procedurą:

I
E_mem_Q_tab_Q_iter_R_next( struct E_mem_Q_tab_Z *tab
, I iterator_id
, I id
);

Koniec wyliczania jest sygnalizowany wartością ~0 zwróconą jako identyfikator kolejnego elementu.

Na przykład:

I iter_id = E_mem_Q_tab_Q_iter_M( tab, ~0 );
I id = ~0;
while( !~( id = E_mem_Q_tab_Q_iter_R_next( iter_id, id ))
{    I_B()
        break;
}
E_mem_Q_tab_Q_iter_W( tab, iter_id );