package body set_of_natural_pkg is bit_mask_template : bit_mask_array := ( 16#0000_0000_0000_0001#, 16#0000_0000_0000_0002#, 16#0000_0000_0000_0004#, 16#0000_0000_0000_0008#, 16#0000_0000_0000_0010#, 16#0000_0000_0000_0020#, 16#0000_0000_0000_0040#, 16#0000_0000_0000_0080#, 16#0000_0000_0000_0100#, 16#0000_0000_0000_0200#, 16#0000_0000_0000_0400#, 16#0000_0000_0000_0800#, 16#0000_0000_0000_1000#, 16#0000_0000_0000_2000#, 16#0000_0000_0000_4000#, 16#0000_0000_0000_8000#, 16#0000_0000_0001_0000#, 16#0000_0000_0002_0000#, 16#0000_0000_0004_0000#, 16#0000_0000_0008_0000#, 16#0000_0000_0010_0000#, 16#0000_0000_0020_0000#, 16#0000_0000_0040_0000#, 16#0000_0000_0080_0000#, 16#0000_0000_0100_0000#, 16#0000_0000_0200_0000#, 16#0000_0000_0400_0000#, 16#0000_0000_0800_0000#, 16#0000_0000_1000_0000#, 16#0000_0000_2000_0000#, 16#0000_0000_4000_0000#, 16#0000_0000_8000_0000#, 16#0000_0001_0000_0000#, 16#0000_0002_0000_0000#, 16#0000_0004_0000_0000#, 16#0000_0008_0000_0000#, 16#0000_0010_0000_0000#, 16#0000_0020_0000_0000#, 16#0000_0040_0000_0000#, 16#0000_0080_0000_0000#, 16#0000_0100_0000_0000#, 16#0000_0200_0000_0000#, 16#0000_0400_0000_0000#, 16#0000_0800_0000_0000#, 16#0000_1000_0000_0000#, 16#0000_2000_0000_0000#, 16#0000_4000_0000_0000#, 16#0000_8000_0000_0000#, 16#0001_0000_0000_0000#, 16#0002_0000_0000_0000#, 16#0004_0000_0000_0000#, 16#0008_0000_0000_0000#, 16#0010_0000_0000_0000#, 16#0020_0000_0000_0000#, 16#0040_0000_0000_0000#, 16#0080_0000_0000_0000#, 16#0100_0000_0000_0000#, 16#0200_0000_0000_0000#, 16#0400_0000_0000_0000#, 16#0800_0000_0000_0000#, 16#1000_0000_0000_0000#, 16#2000_0000_0000_0000#, 16#4000_0000_0000_0000#, 16#8000_0000_0000_0000# ); type BS_Iterator is new BS_Iterator_Interface.Reversible_Iterator with record BS_Set_Ref : BS_Access; Value : element_value_ext; end record; overriding function First (Object : BS_Iterator) return BS_Cursor; overriding function Next (Object : BS_Iterator; Position : BS_Cursor) return BS_Cursor; overriding function Last (Object : BS_Iterator) return BS_Cursor; overriding function Previous (Object : BS_Iterator; Position : BS_Cursor) return BS_Cursor; procedure Initialize (set_object : in out BS_Set) is begin null; end Initialize; procedure Adjust (set_object : in out BS_Set) is pragma Suppress(All_Checks); new_bit_set : bit_set_access; bitset_index : Integer; bitset_exist : Boolean; begin if not IsEmpty(set_object) then for J in bit_set'Range loop if 0 /= set_object.not_empty_bitset(J) then if 16#ffff_ffff_ffff_ffff# /= set_object.full_bitsets(J) then for K in bit_mask_array'Range loop bitset_exist := (0 = (set_object.full_bitsets(J) and bit_mask_template(K))) and then (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); if bitset_exist then bitset_index := 64*J + K; new_bit_set := new bit_set; new_bit_set.all := set_object.bit_sets(bitset_index).all; set_object.bit_sets(bitset_index) := new_bit_set; end if; end loop; end if; end if; end loop; end if; end Adjust; procedure Finalize (set_object : in out BS_Set) is begin if not IsEmpty(set_object) then Clear(set_object); end if; end Finalize; function get_power(set_object : BS_set) return Natural is power : Natural := 0; bit_array_ptr : bit_set_access; begin for I in bit_set'Range loop for J in bit_mask_array'Range loop if (set_object.full_bitsets(I) and bit_mask_template(J)) /= 0 then power := @ + 262144; end if; end loop; end loop; for I in bit_set_array'Range loop bit_array_ptr := set_object.bit_sets(I); if bit_array_ptr /= null then for J in bit_set'Range loop for K in bit_mask_array'Range loop if (bit_array_ptr.all(J) and bit_mask_template(K)) /= 0 then power := @ + 1; end if; end loop; end loop; end if; end loop; return power; end get_power; procedure Append ( set_object : in out BS_Set; element : in element_value_ext; element_pos : out element_value_ext ) is pragma Suppress(All_Checks); bitset_pos, bitset_array_pos, bitwize_pos, bitset_pos_l2, bitwize_pos_l2 : Integer; element_val : element_value; element_u64 : Unsigned_64; b_bitset_full, b_bitset_exist : Boolean; begin if element = -1 then if set_object.max_element = -1 then set_object.min_element := 0; set_object.max_element := 0; element_pos := 0; set_object.bit_sets(0) := new bit_set; set_object.bit_sets(0).all := (others => 0); set_object.not_empty_bitset(0) := bit_mask_template(0); set_object.bit_sets(0).all(0) := bit_mask_template(0); else set_object.max_element := set_object.max_element + 1; element_pos := set_object.max_element; element_val := abs(element_pos); element_u64 := Unsigned_64(element_val); bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); if null = set_object.bit_sets(bitset_array_pos) then set_object.bit_sets(bitset_array_pos) := new bit_set; set_object.bit_sets(bitset_array_pos).all := (others => 0); set_object.bit_sets(bitset_array_pos).all(bitset_pos) := bit_mask_template(bitwize_pos); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); set_object.not_empty_bitset(bitset_pos_l2) := set_object.not_empty_bitset(bitset_pos_l2) or bit_mask_template(bitwize_pos_l2); else set_object.bit_sets(bitset_array_pos).all(bitset_pos) := set_object.bit_sets(bitset_array_pos).all(bitset_pos) or bit_mask_template(bitwize_pos); b_bitset_full := True; for J in bit_set'Range loop if set_object.bit_sets(bitset_array_pos).all(J) /= 16#ffff_ffff_ffff_ffff# then b_bitset_full := False; exit; end if; end loop; if b_bitset_full then Free(set_object.bit_sets(bitset_array_pos)); set_object.bit_sets(bitset_array_pos) := null; bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); set_object.full_bitsets(bitset_pos_l2) := set_object.full_bitsets(bitset_pos_l2) or bit_mask_template(bitwize_pos_l2); end if; end if; end if; else element_pos := element; element_val := abs(element); element_u64 := Unsigned_64(element_val); bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); b_bitset_exist := (0 /= (set_object.full_bitsets(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if b_bitset_exist then return; end if; if null = set_object.bit_sets(bitset_array_pos) then set_object.bit_sets(bitset_array_pos) := new bit_set; set_object.bit_sets(bitset_array_pos).all := (others => 0); set_object.bit_sets(bitset_array_pos).all(bitset_pos) := bit_mask_template(bitwize_pos); set_object.not_empty_bitset(bitset_pos_l2) := set_object.not_empty_bitset(bitset_pos_l2) or bit_mask_template(bitwize_pos_l2); if element > set_object.max_element Then set_object.max_element := element; end if; if set_object.min_element = -1 or else element < set_object.min_element Then set_object.min_element := element; end if; return; end if; b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(bitset_pos) and bit_mask_template(bitwize_pos))); if b_bitset_exist then return; end if; set_object.bit_sets(bitset_array_pos).all(bitset_pos) := set_object.bit_sets(bitset_array_pos).all(bitset_pos) or bit_mask_template(bitwize_pos); if element > set_object.max_element Then set_object.max_element := element; end if; if element < set_object.min_element Then set_object.min_element := element; end if; b_bitset_full := True; for J in bit_set'Range loop if set_object.bit_sets(bitset_array_pos).all(J) /= 16#ffff_ffff_ffff_ffff# then b_bitset_full := False; exit; end if; end loop; if b_bitset_full then Free(set_object.bit_sets(bitset_array_pos)); set_object.bit_sets(bitset_array_pos) := null; set_object.full_bitsets(bitset_pos_l2) := set_object.full_bitsets(bitset_pos_l2) or bit_mask_template(bitwize_pos_l2); end if; end if; end Append; function Find(set_object : BS_Set; element : element_value) return Boolean is pragma Suppress(All_Checks); bitset_pos, bitset_array_pos, bitwize_pos, bitset_pos_l2, bitwize_pos_l2 : Integer; element_u64 : Unsigned_64 := Unsigned_64(element); b_bitset_exist : Boolean; begin if IsEmpty(set_object) then return False; end if; bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); b_bitset_exist := (0 /= (set_object.full_bitsets(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if b_bitset_exist then return True; end if; b_bitset_exist := (0 /= (set_object.not_empty_bitset(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if not b_bitset_exist then return False; end if; for J in bit_set'Range loop b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(bitset_pos) and bit_mask_template(bitwize_pos))); if b_bitset_exist then return True; end if; end loop; return False; end Find; function "or" (Left, Right : BS_Set) return BS_Set is pragma Suppress(All_Checks); result_object : BS_Set := Left; bitset_array_indx : Integer; b_bit_exist : Boolean; begin if -1 = Right.max_element then return result_object; end if; for J in bit_set'Range loop if 0 /= Right.full_bitsets(J) then result_object.full_bitsets(J) := result_object.full_bitsets(J) or Right.full_bitsets(J); result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) or Right.full_bitsets(J); for K in bit_mask_array'Range loop b_bit_exist := (0 /= (Right.full_bitsets(J) and bit_mask_template(K))); if b_bit_exist then bitset_array_indx := 64*J + K; if null /= result_object.bit_sets(bitset_array_indx) then Free(result_object.bit_sets(bitset_array_indx)); result_object.bit_sets(bitset_array_indx) := null; end if; end if; end loop; end if; end loop; for J in bit_set'Range loop if 0 /= Right.not_empty_bitset(J) then for K in bit_mask_array'Range loop b_bit_exist := (0 /= (Right.not_empty_bitset(J) and bit_mask_template(K))); if b_bit_exist and (0 = (result_object.full_bitsets(J) and bit_mask_template(K))) then bitset_array_indx := 64*J + K; if null = result_object.bit_sets(bitset_array_indx) then result_object.bit_sets(bitset_array_indx) := new bit_set; result_object.bit_sets(bitset_array_indx).all := Right.bit_sets(bitset_array_indx).all; else for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := result_object.bit_sets(bitset_array_indx).all(L) or Right.bit_sets(bitset_array_indx).all(L); end loop; end if; end if; end loop; end if; end loop; minmax_recalculation(result_object); return result_object; end "or"; function "and" (Left, Right : BS_Set) return BS_Set is pragma Suppress(All_Checks); result_object : BS_Set; bitset_array_indx : Integer; b_bit_exist, b_result_emty, b_left, b_right : Boolean; begin if (-1 = Right.max_element) or else (-1 = Left.max_element) then return result_object; end if; b_result_emty := (Right.min_element > Left.max_element) or else (Left.min_element > Right.max_element); if b_result_emty then return result_object; end if; result_object := Left; for J in bit_set'Range loop if 0 /= result_object.not_empty_bitset(J) then if 0 /= Right.not_empty_bitset(J) then for K in bit_mask_array'Range loop b_left := (0 /= (result_object.not_empty_bitset(J) and bit_mask_template(K))); b_right := (0 /= (Right.not_empty_bitset(J) and bit_mask_template(K))); bitset_array_indx := 4096*(64*J + K); if b_left and then not b_right then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) and not bit_mask_template(K); b_bit_exist := (0 /= (result_object.full_bitsets(J) and bit_mask_template(K))); if b_bit_exist then result_object.full_bitsets(J) := result_object.full_bitsets(J) and not bit_mask_template(K); else Free(result_object.bit_sets(bitset_array_indx)); result_object.bit_sets(bitset_array_indx) := null; end if; elsif b_left then b_right := (0 /= (Right.full_bitsets(J) and bit_mask_template(K))); if not b_right then b_left := (0 /= (result_object.full_bitsets(J) and bit_mask_template(K))); if b_left then result_object.full_bitsets(J) := result_object.full_bitsets(J) and not bit_mask_template(K); result_object.bit_sets(bitset_array_indx) := new bit_set; result_object.bit_sets(bitset_array_indx).all := Right.bit_sets(bitset_array_indx).all; else for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := result_object.bit_sets(bitset_array_indx).all(L) and Right.bit_sets(bitset_array_indx).all(L); end loop; b_result_emty := True; for L in bit_set'Range loop if 0 /= result_object.bit_sets(bitset_array_indx).all(L) then b_result_emty := False; exit; end if; end loop; if b_result_emty then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) and not bit_mask_template(K); Free(result_object.bit_sets(bitset_array_indx)); result_object.bit_sets(bitset_array_indx) := null; end if; end if; end if; end if; end loop; else for K in bit_mask_array'Range loop result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) and not bit_mask_template(K); bitset_array_indx := 4096*(64*J + K); b_left := (0 /= (result_object.full_bitsets(J) and bit_mask_template(K))); if b_left then result_object.full_bitsets(J) := result_object.full_bitsets(J) and not bit_mask_template(K); else Free(result_object.bit_sets(bitset_array_indx)); result_object.bit_sets(bitset_array_indx) := null; end if; end loop; end if; end if; end loop; b_result_emty := True; for J in bit_set'Range loop if 0 /= result_object.not_empty_bitset(J) then b_result_emty := False; exit; end if; end loop; if b_result_emty then result_object.min_element := -1; result_object.max_element := -1; else minmax_recalculation(result_object); end if; return result_object; end "and"; function "xor" (Left, Right : BS_Set) return BS_Set is pragma Suppress(All_Checks); result_object : BS_Set; bitset_array_indx : Integer; b_left1, b_right1, b_left, b_right : Boolean; aux_bitset : bit_set := (others => 16#ffff_ffff_ffff_ffff#); begin if Left = Right then return result_object; end if; if IsEmpty(Right) then return Left; end if; if IsEmpty(Left) then return Right; end if; result_object := Left; for J in bit_set'Range loop if 0 /= result_object.not_empty_bitset(J) or else 0 /= Right.not_empty_bitset(J) then for K in bit_mask_array'Range loop bitset_array_indx := 4096*(64*J + K); b_left := (0 /= (result_object.full_bitsets(J) and bit_mask_template(K))); b_right := (0 /= (Right.full_bitsets(J) and bit_mask_template(K))); b_left1 := (0 /= (result_object.not_empty_bitset(J) and bit_mask_template(K))); b_right1 := (0 /= (Right.not_empty_bitset(J) and bit_mask_template(K))); if b_left and b_right then result_object.not_empty_bitset(j) := result_object.not_empty_bitset(j) and not bit_mask_template(K); result_object.full_bitsets(j) := result_object.full_bitsets(j) and not bit_mask_template(K); elsif b_left and b_right1 then result_object.bit_sets(bitset_array_indx) := new bit_set; result_object.bit_sets(bitset_array_indx).all := (others => 16#ffff_ffff_ffff_ffff#); for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := result_object.bit_sets(bitset_array_indx).all(L) xor Right.bit_sets(bitset_array_indx).all(L); end loop; elsif b_left1 and b_right then for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := result_object.bit_sets(bitset_array_indx).all(L) xor aux_bitset(L); end loop; elsif b_left1 and b_right1 then for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := result_object.bit_sets(bitset_array_indx).all(L) xor Right.bit_sets(bitset_array_indx).all(L); end loop; elsif not b_left1 and b_right then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) or bit_mask_template(K); result_object.full_bitsets(J) := result_object.full_bitsets(J) or bit_mask_template(K); elsif not b_left1 and b_right1 then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) or bit_mask_template(K); result_object.bit_sets(bitset_array_indx) := new bit_set; result_object.bit_sets(bitset_array_indx).all := Right.bit_sets(bitset_array_indx).all; end if; end loop; end if; end loop; minmax_recalculation(result_object); return result_object; end "xor"; function "not" (set_object : BS_Set) return BS_Set is pragma Suppress(All_Checks); result_object : BS_Set; bitset_array_indx : Integer; b_fullset, b_bitset : Boolean; begin if IsEmpty(set_object) then result_object.min_element := element_value'First; result_object.max_element := element_value'Last; result_object.not_empty_bitset := (others => 16#ffff_ffff_ffff_ffff#); result_object.full_bitsets := (others => 16#ffff_ffff_ffff_ffff#); return result_object; end if; if IsFullFilled(set_object) then return result_object; end if; for J in bit_set'Range loop if 16#ffff_ffff_ffff_ffff# = result_object.full_bitsets(J) then result_object.not_empty_bitset(J) := 0; result_object.full_bitsets(J) := 0; elsif 0 /= result_object.not_empty_bitset(J) then for K in bit_mask_array'Range loop bitset_array_indx := 4096*(J*64 + K); b_bitset := (0 /= (result_object.not_empty_bitset(J) and bit_mask_template(K))); b_fullset := (0 /= (result_object.full_bitsets(J) and bit_mask_template(K))); if b_fullset then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) and not bit_mask_template(K); result_object.full_bitsets(J) := result_object.not_empty_bitset(J) and not bit_mask_template(K); elsif not b_bitset then result_object.not_empty_bitset(J) := result_object.not_empty_bitset(J) or bit_mask_template(K); result_object.full_bitsets(J) := result_object.not_empty_bitset(J) or bit_mask_template(K); else for L in bit_set'Range loop result_object.bit_sets(bitset_array_indx).all(L) := not result_object.bit_sets(bitset_array_indx).all(L); end loop; end if; end loop; else result_object.not_empty_bitset(J) := 16#ffff_ffff_ffff_ffff#; result_object.full_bitsets(J) := 16#ffff_ffff_ffff_ffff#; end if; end loop; result_object := set_object; minmax_recalculation(result_object); return result_object; end "not"; function "-" (Left, Right : BS_Set) return BS_Set is result_object : BS_Set; begin result_object := Left and Right; result_object := Left xor result_object; return result_object; end "-"; function ">=" (Left, Right : BS_Set) return Boolean is begin return IsEmpty(Right - Left); end ">="; function ">" (Left, Right : BS_Set) return Boolean is begin return (Left >= Right) and then (Left /= Right); end ">"; function IsFullFilled(set_object : BS_Set) return Boolean is pragma Suppress(All_Checks); begin if set_object.min_element /= element_value'First then return False; end if; if set_object.max_element /= element_value'Last then return False; end if; for J in bit_set'Range loop if set_object.full_bitsets(J) /= 16#ffff_ffff_ffff_ffff# then return False; end if; end loop; return True; end IsFullFilled; procedure minmax_recalculation( set_object : in out BS_Set) is pragma Suppress(All_Checks); b_bit_exist : Boolean; begin J_loop: for J in bit_set'Range loop if 0 /= set_object.not_empty_bitset(J) then K_loop: for K in bit_mask_array'Range loop b_bit_exist := (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); if b_bit_exist then if 0 /= (set_object.full_bitsets(J) and bit_mask_template(K)) then set_object.min_element := 4096*(64*J + K); exit J_loop; end if; end if; L_loop: for L in bit_set'Range loop M_loop: for M in bit_mask_array'Range loop b_bit_exist := (0 /= (set_object.bit_sets(0).all(L) and bit_mask_template(M))); if b_bit_exist then set_object.min_element := 4096*(64*J + K) + 64*L + M; exit J_loop; end if; end loop M_loop; end loop L_loop; end loop K_loop; end if; end loop J_loop; J_loop1: for J in reverse bit_set'Range loop if 0 /= set_object.not_empty_bitset(J) then K_loop1: for K in reverse bit_mask_array'Range loop b_bit_exist := (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); if b_bit_exist then if 0 /= (set_object.full_bitsets(J) and bit_mask_template(K)) then set_object.max_element := 4096*(64*J + K) + 4095; exit J_loop1; end if; end if; L_loop1: for L in reverse bit_set'Range loop M_loop1: for M in reverse bit_mask_array'Range loop b_bit_exist := (0 /= (set_object.bit_sets(0).all(L) and bit_mask_template(M))); if b_bit_exist then set_object.max_element := 4096*(64*J + K) + 64*L + M; exit J_loop1; end if; end loop M_loop1; end loop L_loop1; end loop K_loop1; end if; end loop J_loop1; end minmax_recalculation; procedure Remove ( set_object : in out BS_Set; element : in element_value ) is pragma Suppress(All_Checks); bitset_pos, bitset_array_pos, bitwize_pos, bitset_pos_l2, bitwize_pos_l2 : Integer; element_u64 : Unsigned_64 := Unsigned_64(element); b_bitset_full, b_bit_exist, b_empty : Boolean; begin if -1 = set_object.max_element then return; end if; bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); b_bitset_full := (0 /= (set_object.full_bitsets(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if b_bitset_full then set_object.full_bitsets(bitset_pos_l2) := set_object.full_bitsets(bitset_pos_l2) and not bit_mask_template(bitwize_pos_l2); set_object.bit_sets(bitset_array_pos) := new bit_set; set_object.bit_sets(bitset_array_pos).all := (others => 16#ffff_ffff_ffff_ffff#); set_object.bit_sets(bitset_array_pos).all(bitset_pos) := set_object.bit_sets(bitset_array_pos).all(bitset_pos) and not bit_mask_template(bitwize_pos); else b_bit_exist := ((null /= set_object.bit_sets(bitset_array_pos)) and then (0 /= (set_object.bit_sets(bitset_array_pos).all(bitset_pos) and bit_mask_template(bitwize_pos)))); if not b_bit_exist then return; end if; set_object.bit_sets(bitset_array_pos).all(bitset_pos) := set_object.bit_sets(bitset_array_pos).all(bitset_pos) and not bit_mask_template(bitwize_pos); b_empty := True; for J in bit_set'Range loop if 0 /= set_object.bit_sets(bitset_array_pos).all(J) then b_empty := False; exit; end if; end loop; if b_empty then Free(set_object.bit_sets(bitset_array_pos)); set_object.bit_sets(bitset_array_pos) := null; set_object.not_empty_bitset(bitset_pos_l2) := set_object.not_empty_bitset(bitset_pos_l2) and not bit_mask_template(bitwize_pos_l2); end if; end if; if (element = set_object.min_element) and then (element = set_object.max_element) then set_object.min_element := -1; set_object.max_element := -1; elsif (element = set_object.min_element) or else (element = set_object.max_element) then minmax_recalculation(set_object); end if; end Remove; function "=" (Left, Right : BS_Set) return Boolean is pragma Suppress(All_Checks); bitset_array_indx : Integer; b_value : Boolean; begin if Left.min_element = -1 and Right.min_element = -1 then return True; end if; if Left.min_element /= Right.min_element then return False; end if; if Left.max_element /= Right.max_element then return False; end if; for J in bit_set'Range loop if Left.not_empty_bitset(J) /= Right.not_empty_bitset(J) then return False; end if; if Left.full_bitsets(J) /= Right.full_bitsets(j) then return False; end if; if 0 /= Left.not_empty_bitset(J) then for K in bit_mask_array'Range loop bitset_array_indx := 4096*(64*J + K); b_value := (null /= Left.bit_sets(bitset_array_indx) and null = Right.bit_sets(bitset_array_indx)) or else (null = Left.bit_sets(bitset_array_indx) and null /= Right.bit_sets(bitset_array_indx)); if b_value then return False; end if; if null /= Left.bit_sets(bitset_array_indx) then for L in bit_set'Range loop if Left.bit_sets(bitset_array_indx).all(L) /= Right.bit_sets(bitset_array_indx).all(L) then return False; end if; end loop; end if; end loop; end if; end loop; return True; end "="; function IsEmpty(set_object : BS_Set) return Boolean is begin return -1 = set_object.min_element; end IsEmpty; function GetFirst(set_object : BS_Set) return element_value_ext is begin return set_object.min_element; end GetFirst; function GetNext(set_object : BS_Set; element : element_value_ext) return element_value_ext is pragma Suppress(All_Checks); bitset_pos, bitset_array_pos, bitwize_pos, bitset_pos_l2, bitwize_pos_l2 : Integer; element_val : element_value; element_u64 : Unsigned_64; b_bitset_exist, b_full_exist : Boolean; begin if -1 = element then return -1; end if; if element >= set_object.max_element then return -1; end if; element_val := abs(element) + 1; element_u64 := Unsigned_64(element_val); bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); b_bitset_exist := (0 /= (set_object.not_empty_bitset(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); b_full_exist := (0 /= (set_object.full_bitsets(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if b_full_exist then return element_val; end if; if b_bitset_exist then for J in bitset_pos .. bit_set'Last loop for K in bitwize_pos .. bit_mask_array'Last loop b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(J) and bit_mask_template(K))); if b_bitset_exist then return 4096*(64*bitset_pos_l2 + bitwize_pos_l2) + 64*J + K; end if; end loop; bitwize_pos := 0; end loop; end if; bitwize_pos_l2 := bitwize_pos_l2 + 1; if 64 = bitwize_pos_l2 then bitwize_pos_l2 := 0; bitset_pos_l2 := bitset_pos_l2 + 1; if 16 = bitset_pos_l2 then return -1; end if; end if; for J in bitset_pos_l2 .. bit_set'Last loop for K in bitwize_pos_l2 .. bit_mask_array'Last loop b_bitset_exist := (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); b_full_exist := (0 /= (set_object.full_bitsets(J) and bit_mask_template(K))); bitset_array_pos := 64*J + K; if b_full_exist then return 4096*bitset_array_pos; end if; if b_bitset_exist then for L in bit_set'Range loop for M in bit_mask_array'Range loop b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(L) and bit_mask_template(M))); if b_bitset_exist then return 4096*bitset_array_pos + 64*L + M; end if; end loop; end loop; end if; end loop; bitwize_pos_l2 := 0; end loop; return -1; end GetNext; function GetLast(set_object : BS_Set) return element_value_ext is begin return set_object.max_element; end GetLast; function GetPrev(set_object : BS_Set; element : element_value_ext) return element_value_ext is pragma Suppress(All_Checks); bitset_pos, bitset_array_pos, bitwize_pos, bitset_pos_l2, bitwize_pos_l2 : Integer; element_val : element_value; element_u64 : Unsigned_64; b_bitset_exist, b_full_exist : Boolean; begin if -1 = element then return -1; end if; if element <= set_object.min_element then return -1; end if; element_val := abs(element) - 1; element_u64 := Unsigned_64(element_val); bitset_array_pos := Integer(Shift_Right(element_u64, 10)); bitset_pos := Integer(Shift_Right(element_u64, 6) and 15); bitwize_pos := Integer(element_u64 and 63); bitset_pos_l2 := Integer(Shift_Right(Unsigned_64(bitset_array_pos), 6)); bitwize_pos_l2 := Integer(Unsigned_64(bitset_array_pos) and 63); b_bitset_exist := (0 /= (set_object.not_empty_bitset(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); b_full_exist := (0 /= (set_object.full_bitsets(bitset_pos_l2) and bit_mask_template(bitwize_pos_l2))); if b_full_exist then return element_val; end if; if b_bitset_exist then for J in reverse 0 .. bitset_pos loop for K in reverse 0 .. bitwize_pos loop b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(J) and bit_mask_template(K))); if b_bitset_exist then return 4096*(64*bitset_pos_l2 + bitwize_pos_l2) + 64*J + K; end if; end loop; bitwize_pos := bit_mask_array'Last; end loop; end if; bitwize_pos_l2 := bitwize_pos_l2 - 1; if -1 = bitwize_pos_l2 then bitwize_pos_l2 := bit_mask_array'Last; bitset_pos_l2 := bitset_pos_l2 - 1; if -1 = bitset_pos_l2 then return -1; end if; end if; for J in reverse 0 .. bitset_pos_l2 loop for K in reverse 0 .. bitwize_pos_l2 loop b_bitset_exist := (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); b_full_exist := (0 /= (set_object.full_bitsets(J) and bit_mask_template(K))); bitset_array_pos := 64*J + K; if b_full_exist then return 4096*bitset_array_pos + 4095; end if; if b_bitset_exist then for L in reverse bit_set'Range loop for M in reverse bit_mask_array'Range loop b_bitset_exist := (0 /= (set_object.bit_sets(bitset_array_pos).all(L) and bit_mask_template(M))); if b_bitset_exist then return 4096*bitset_array_pos + 64*L + M; end if; end loop; end loop; end if; end loop; bitwize_pos_l2 := bit_mask_array'Last; end loop; return -1; end GetPrev; procedure Clear( set_object : in out BS_Set) is pragma Suppress(All_Checks); b_bitset_exist, b_full_exist : Boolean; bitset_index : Integer; begin set_object.min_element := -1; set_object.max_element := -1; for J in bit_set'Range loop if 0 /= set_object.not_empty_bitset(J) then for K in bit_mask_array'Range loop b_bitset_exist := (0 /= (set_object.not_empty_bitset(J) and bit_mask_template(K))); b_full_exist := (0 /= (set_object.full_bitsets(J) and bit_mask_template(K))); if b_bitset_exist and then not b_full_exist then bitset_index := 64*J + K; Free(set_object.bit_sets(bitset_index)); set_object.bit_sets(bitset_index) := null; end if; end loop; set_object.not_empty_bitset(J) := 0; set_object.full_bitsets(J) := 0; end if; end loop; end Clear; function BS_Has_Element (Position : BS_Cursor) return Boolean is begin if Position.Value = no_element_value then return False; end if; return True; end BS_Has_Element; function BS_Element(Set : aliased BS_Set; Position : BS_Cursor) return element_value_ext is begin return Position.Value; end BS_Element; function To_Cursor (Set : aliased BS_Set; Value : element_value_ext) return BS_Cursor is S : constant BS_Access := Set'Unrestricted_Access; begin if Value = no_element_value then return no_element; end if; if Find(Set, Value) then return BS_Cursor'(S, Value); end if; return no_element; end To_Cursor; function BS_Iterate(Set : BS_Set) return BS_Iterator_Interface.Reversible_Iterator'Class is S : constant BS_Access := Set'Unrestricted_Access; begin return BS_Iterator'(S, no_element_value); end BS_Iterate; function BS_Iterate(Set : BS_Set; Start : BS_Cursor) return BS_Iterator_Interface.Reversible_Iterator'Class is S : constant BS_Access := Set'Unrestricted_Access; V : element_value_ext := Start.Value; begin if V = no_element_value then return BS_Iterator'(S, no_element_value); end if; if Find(Set, V) then return BS_Iterator'(S, V); end if; return BS_Iterator'(S, no_element_value); end BS_Iterate; function First (Object : BS_Iterator) return BS_Cursor is RS : BS_Access := Object.BS_Set_Ref; V : element_value_ext := Object.Value; RV : element_value_ext; begin if V = no_element_value then RV := GetFirst(RS.all); if RV = no_element_value then return BS_Cursor'(RS, RV); end if; return no_element; end if; return BS_Cursor'(RS, V); end First; function Last (Object : BS_Iterator) return BS_Cursor is RS : BS_Access := Object.BS_Set_Ref; V : element_value_ext := Object.Value; RV : element_value_ext; begin if V = no_element_value then RV := GetLast(RS.all); if RV = no_element_value then return BS_Cursor'(RS, RV); end if; return no_element; end if; return BS_Cursor'(RS, V); end Last; function BS_Find(Set : BS_Set; cs_element : element_value) return BS_Cursor is S : constant BS_Access := Set'Unrestricted_Access; begin if Find(Set, cs_element) then return BS_Cursor'(S, cs_element); end if; return no_element; end BS_Find; function Next (Object : BS_Iterator; Position : BS_Cursor) return BS_Cursor is RS : BS_Access := Object.BS_Set_Ref; V : element_value_ext := Position.Value; RV : element_value_ext; begin if V = no_element_value then return no_element; end if; pragma Assert(RS = Position.BS_Set_Ref, "Object.BS_Set_Ref /= Position.BS_Set_Ref"); RV := GetNext(RS.all, V); if RV = no_element_value then return no_element; end if; return BS_Cursor'(RS, RV); end Next; function Previous (Object : BS_Iterator; Position : BS_Cursor) return BS_Cursor is RS : BS_Access := Object.BS_Set_Ref; V : element_value_ext := Position.Value; RV : element_value_ext; begin if V = no_element_value then return no_element; end if; pragma Assert(RS = Position.BS_Set_Ref, "Object.BS_Set_Ref /= Position.BS_Set_Ref"); RV := GetPrev(RS.all, V); if RV = no_element_value then return no_element; end if; return BS_Cursor'(RS, RV); end Previous; procedure Deallocate(ptr : in out BS_Access) is begin Free(ptr); end Deallocate; begin null; end set_of_natural_pkg;