(* Copyright 2016, 2023 Anton Krotov This file is part of fb2read. fb2read is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. fb2read is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with fb2read. If not, see . *) MODULE Vector; IMPORT SYSTEM, K := KOSAPI; CONST ptr_size = 4; TYPE DESC_VECTOR = RECORD data : INTEGER; count* : INTEGER; size : INTEGER END; VECTOR* = POINTER TO DESC_VECTOR; ANYREC* = RECORD END; ANYPTR* = POINTER TO ANYREC; DESTRUCTOR* = PROCEDURE (VAR ptr: ANYPTR); PROCEDURE push* (vector: VECTOR; value: ANYPTR); BEGIN IF vector.count = vector.size THEN vector.data := K.realloc(vector.data, (vector.size + 1024) * ptr_size); vector.size := vector.size + 1024 END; SYSTEM.PUT(vector.data + vector.count * ptr_size, value); INC(vector.count) END push; PROCEDURE get* (vector: VECTOR; idx: INTEGER): ANYPTR; VAR res: ANYPTR; BEGIN ASSERT( (0 <= idx) & (idx < vector.count) ); SYSTEM.GET(vector.data + idx * ptr_size, res) RETURN res END get; PROCEDURE put* (vector: VECTOR; idx: INTEGER; value: ANYPTR); BEGIN ASSERT( (0 <= idx) & (idx < vector.count) ); SYSTEM.PUT(vector.data + idx * ptr_size, value) END put; PROCEDURE create* (size: INTEGER): VECTOR; VAR vector: VECTOR; BEGIN NEW(vector); vector.data := K.malloc(ptr_size * size); vector.size := size; vector.count := 0 RETURN vector END create; PROCEDURE def_destructor (VAR any: ANYPTR); BEGIN DISPOSE(any) END def_destructor; PROCEDURE destroy* (VAR vector: VECTOR; destructor: DESTRUCTOR); VAR i: INTEGER; any: ANYPTR; BEGIN IF destructor = NIL THEN destructor := def_destructor END; FOR i := 0 TO vector.count - 1 DO any := get(vector, i); destructor(any) END; vector.data := K.free(vector.data); DISPOSE(vector) END destroy; END Vector.