1-- Copyright 1994 Grady Booch 2-- Copyright 1998-2014 Simon Wright <simon@pushface.org> 3 4-- This package is free software; you can redistribute it and/or 5-- modify it under terms of the GNU General Public License as 6-- published by the Free Software Foundation; either version 2, or 7-- (at your option) any later version. This package is distributed in 8-- the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9-- even the implied warranty of MERCHANTABILITY or FITNESS FOR A 10-- PARTICULAR PURPOSE. See the GNU General Public License for more 11-- details. You should have received a copy of the GNU General Public 12-- License distributed with this package; see file COPYING. If not, 13-- write to the Free Software Foundation, 59 Temple Place - Suite 14-- 330, Boston, MA 02111-1307, USA. 15 16-- As a special exception, if other files instantiate generics from 17-- this unit, or you link this unit with other files to produce an 18-- executable, this unit does not by itself cause the resulting 19-- executable to be covered by the GNU General Public License. This 20-- exception does not however invalidate any other reasons why the 21-- executable file might be covered by the GNU Public License. 22 23generic 24 type Key is private; 25 with function "=" (L, R : Key) return Boolean is <>; 26package BC.Containers.Maps is 27 28 pragma Preelaborate; 29 30 -- A map denotes a collection forming a dictionary of domain/range 31 -- pairs. 32 33 -- The parameter Key denotes the universe from which the map draws 34 -- its domain; the parameter Item denotes the universe from which 35 -- the map draws its range. The parameters Key and Item typically 36 -- represent different types, although they may may represent the 37 -- same type. Either may be a primitive type or user-defined. 38 39 type Abstract_Map is abstract new Container with private; 40 41 function Are_Equal (L, R : Abstract_Map'Class) return Boolean; 42 -- Return True if and only if both maps have the same extent and 43 -- the same key/item pairs; return False otherwise. 44 -- Can't call this "=" because of the standard one for Map. 45 46 procedure Clear (M : in out Abstract_Map) 47 is abstract; 48 -- Empty the map of all key/item pairs. 49 50 procedure Bind (M : in out Abstract_Map; K : Key; I : Item) 51 is abstract; 52 -- If the key already exists in the map, raise BC.Duplicate. 53 -- Otherwise, add the key/item pair to the map. 54 55 procedure Rebind (M : in out Abstract_Map; K : Key; I : Item) 56 is abstract; 57 -- If the key does not exist in the map, raise BC.Not_Found. 58 -- Otherwise, change the key's binding to the given value. 59 60 procedure Unbind (M : in out Abstract_Map; K : Key) 61 is abstract; 62 -- If the key does not exist in the map, raise BC.Not_Found. 63 -- Otherwise, remove the key/item binding. 64 65 function Available (M : Abstract_Map) return Natural; 66 -- Return the number of unused slots in the map. 67 68 function Extent (M : Abstract_Map) return Natural 69 is abstract; 70 -- Return the number of key/item bindings in the map. 71 72 function Is_Empty (M : Abstract_Map) return Boolean 73 is abstract; 74 -- Return True if and only if there are no key/item bindings in 75 -- the map; otherwise, return False. 76 77 function Is_Bound (M : Abstract_Map; K : Key) return Boolean 78 is abstract; 79 -- Return True if and only if there is a binding for the given key 80 -- in the map; otherwise, return False. 81 82 function Item_Of (M : Abstract_Map; K : Key) return Item 83 is abstract; 84 -- If the key does not exist in the map, raises BC.Not_Found. 85 -- Otherwise, returns a copy of the item bound to the given key. 86 87 -- Additional Iterator support 88 89 type Map_Iterator is abstract new Iterator with private; 90 91 function Current_Key (It : Map_Iterator) return Key is abstract; 92 -- Returns a copy of the current Key. 93 94 generic 95 with procedure Apply (K : Key; I : Item; OK : out Boolean); 96 procedure Visit (Using : in out Map_Iterator'Class); 97 -- Call Apply with a copy of each Key/Item pair in the Container 98 -- to which the iterator Using is bound. The iteration will 99 -- terminate early if Apply sets OK to False. 100 101 generic 102 with procedure Apply (K : Key; I : in out Item; OK : out Boolean); 103 procedure Modify (Using : in out Map_Iterator'Class); 104 -- Call Apply for each Key/Item pair in the Container to which the 105 -- iterator Using is bound. The Item is a copy, the Item is the 106 -- actual content. The iteration will terminate early if Apply 107 -- sets OK to False. 108 109private 110 111 -- Suppress "unreferenced" warnings here (GNAT 5.02). Can't use 112 -- pragma Unreferenced, because then we get warnings in child 113 -- packages. 114 pragma Warnings (Off, "="); 115 116 type Abstract_Map is abstract new Container with null record; 117 118 type Key_Ptr is access all Key; 119 for Key_Ptr'Storage_Size use 0; 120 121 -- The new subprograms for Map iteration (which allow access to 122 -- the Key as well as the Item) require the inherited 123 -- For_The_Container to in fact be in Map'Class. This must be the 124 -- case since the only way of getting a Map_Iterator is by using 125 -- one of the concrete forms' New_Iterator using eg 126 -- 127 -- Iter : Map_Iterator'Class := Map_Iterator'Class (New_Iterator (M)); 128 -- 129 -- which fails at compilation time if M isn't actually a Map. 130 type Map_Iterator is abstract new Iterator with record 131 Bucket_Index : Natural := 0; 132 Index : Natural := 0; 133 end record; 134 135end BC.Containers.Maps; 136