OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [a-cforma.adb] - Blame information for rev 749

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT LIBRARY COMPONENTS                          --
4
--                                                                          --
5
--   A D A . C O N T A I N E R S . F O R M A L _ O R D E R E D _ M A P S    --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 2010-2011, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
------------------------------------------------------------------------------
27
 
28
with Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations;
29
pragma Elaborate_All
30
  (Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations);
31
 
32
with Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys;
33
pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys);
34
 
35
with System; use type System.Address;
36
 
37
package body Ada.Containers.Formal_Ordered_Maps is
38
 
39
   -----------------------------
40
   -- Node Access Subprograms --
41
   -----------------------------
42
 
43
   --  These subprograms provide a functional interface to access fields
44
   --  of a node, and a procedural interface for modifying these values.
45
 
46
   function Color
47
     (Node : Node_Type) return Ada.Containers.Red_Black_Trees.Color_Type;
48
   pragma Inline (Color);
49
 
50
   function Left_Son (Node : Node_Type) return Count_Type;
51
   pragma Inline (Left);
52
 
53
   function Parent (Node : Node_Type) return Count_Type;
54
   pragma Inline (Parent);
55
 
56
   function Right_Son (Node : Node_Type) return Count_Type;
57
   pragma Inline (Right);
58
 
59
   procedure Set_Color
60
     (Node  : in out Node_Type;
61
      Color : Ada.Containers.Red_Black_Trees.Color_Type);
62
   pragma Inline (Set_Color);
63
 
64
   procedure Set_Left (Node : in out Node_Type; Left : Count_Type);
65
   pragma Inline (Set_Left);
66
 
67
   procedure Set_Right (Node : in out Node_Type; Right : Count_Type);
68
   pragma Inline (Set_Right);
69
 
70
   procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type);
71
   pragma Inline (Set_Parent);
72
 
73
   -----------------------
74
   -- Local Subprograms --
75
   -----------------------
76
 
77
   --  All need comments ???
78
 
79
   generic
80
      with procedure Set_Element (Node : in out Node_Type);
81
   procedure Generic_Allocate
82
     (Tree : in out Tree_Types.Tree_Type'Class;
83
      Node : out Count_Type);
84
 
85
   procedure Free (Tree : in out Map; X : Count_Type);
86
 
87
   function Is_Greater_Key_Node
88
     (Left  : Key_Type;
89
      Right : Node_Type) return Boolean;
90
   pragma Inline (Is_Greater_Key_Node);
91
 
92
   function Is_Less_Key_Node
93
     (Left  : Key_Type;
94
      Right : Node_Type) return Boolean;
95
   pragma Inline (Is_Less_Key_Node);
96
 
97
   --------------------------
98
   -- Local Instantiations --
99
   --------------------------
100
 
101
   package Tree_Operations is
102
     new Red_Black_Trees.Generic_Bounded_Operations
103
       (Tree_Types => Tree_Types,
104
        Left       => Left_Son,
105
        Right      => Right_Son);
106
 
107
   use Tree_Operations;
108
 
109
   package Key_Ops is
110
     new Red_Black_Trees.Generic_Bounded_Keys
111
       (Tree_Operations     => Tree_Operations,
112
        Key_Type            => Key_Type,
113
        Is_Less_Key_Node    => Is_Less_Key_Node,
114
        Is_Greater_Key_Node => Is_Greater_Key_Node);
115
 
116
   ---------
117
   -- "=" --
118
   ---------
119
 
120
   function "=" (Left, Right : Map) return Boolean is
121
      Lst   : Count_Type;
122
      Node  : Count_Type;
123
      ENode : Count_Type;
124
 
125
   begin
126
      if Length (Left) /= Length (Right) then
127
         return False;
128
      end if;
129
 
130
      if Is_Empty (Left) then
131
         return True;
132
      end if;
133
 
134
      Lst := Next (Left, Last (Left).Node);
135
 
136
      Node := First (Left).Node;
137
      while Node /= Lst loop
138
         ENode := Find (Right, Left.Nodes (Node).Key).Node;
139
 
140
         if ENode = 0 or else
141
           Left.Nodes (Node).Element /= Right.Nodes (ENode).Element
142
         then
143
            return False;
144
         end if;
145
 
146
         Node := Next (Left, Node);
147
      end loop;
148
 
149
      return True;
150
   end "=";
151
 
152
   ------------
153
   -- Assign --
154
   ------------
155
 
156
   procedure Assign (Target : in out Map; Source : Map) is
157
      procedure Append_Element (Source_Node : Count_Type);
158
 
159
      procedure Append_Elements is
160
         new Tree_Operations.Generic_Iteration (Append_Element);
161
 
162
      --------------------
163
      -- Append_Element --
164
      --------------------
165
 
166
      procedure Append_Element (Source_Node : Count_Type) is
167
         SN : Node_Type renames Source.Nodes (Source_Node);
168
 
169
         procedure Set_Element (Node : in out Node_Type);
170
         pragma Inline (Set_Element);
171
 
172
         function New_Node return Count_Type;
173
         pragma Inline (New_Node);
174
 
175
         procedure Insert_Post is new Key_Ops.Generic_Insert_Post (New_Node);
176
 
177
         procedure Unconditional_Insert_Sans_Hint is
178
           new Key_Ops.Generic_Unconditional_Insert (Insert_Post);
179
 
180
         procedure Unconditional_Insert_Avec_Hint is
181
           new Key_Ops.Generic_Unconditional_Insert_With_Hint
182
             (Insert_Post,
183
              Unconditional_Insert_Sans_Hint);
184
 
185
         procedure Allocate is new Generic_Allocate (Set_Element);
186
 
187
         --------------
188
         -- New_Node --
189
         --------------
190
 
191
         function New_Node return Count_Type is
192
            Result : Count_Type;
193
         begin
194
            Allocate (Target, Result);
195
            return Result;
196
         end New_Node;
197
 
198
         -----------------
199
         -- Set_Element --
200
         -----------------
201
 
202
         procedure Set_Element (Node : in out Node_Type) is
203
         begin
204
            Node.Key := SN.Key;
205
            Node.Element := SN.Element;
206
         end Set_Element;
207
 
208
         Target_Node : Count_Type;
209
 
210
      --  Start of processing for Append_Element
211
 
212
      begin
213
         Unconditional_Insert_Avec_Hint
214
           (Tree  => Target,
215
            Hint  => 0,
216
            Key   => SN.Key,
217
            Node  => Target_Node);
218
      end Append_Element;
219
 
220
   --  Start of processing for Assign
221
 
222
   begin
223
      if Target'Address = Source'Address then
224
         return;
225
      end if;
226
 
227
      if Target.Capacity < Length (Source) then
228
         raise Storage_Error with "not enough capacity";  -- SE or CE? ???
229
      end if;
230
 
231
      Tree_Operations.Clear_Tree (Target);
232
      Append_Elements (Source);
233
   end Assign;
234
 
235
   -------------
236
   -- Ceiling --
237
   -------------
238
 
239
   function Ceiling (Container : Map; Key : Key_Type) return Cursor is
240
      Node : constant Count_Type := Key_Ops.Ceiling (Container, Key);
241
 
242
   begin
243
      if Node = 0 then
244
         return No_Element;
245
      end if;
246
 
247
      return (Node => Node);
248
   end Ceiling;
249
 
250
   -----------
251
   -- Clear --
252
   -----------
253
 
254
   procedure Clear (Container : in out Map) is
255
   begin
256
      Tree_Operations.Clear_Tree (Container);
257
   end Clear;
258
 
259
   -----------
260
   -- Color --
261
   -----------
262
 
263
   function Color (Node : Node_Type) return Color_Type is
264
   begin
265
      return Node.Color;
266
   end Color;
267
 
268
   --------------
269
   -- Contains --
270
   --------------
271
 
272
   function Contains (Container : Map; Key : Key_Type) return Boolean is
273
   begin
274
      return Find (Container, Key) /= No_Element;
275
   end Contains;
276
 
277
   ----------
278
   -- Copy --
279
   ----------
280
 
281
   function Copy (Source : Map; Capacity : Count_Type := 0) return Map is
282
      Node : Count_Type := 1;
283
      N    : Count_Type;
284
 
285
   begin
286
      return Target : Map (Count_Type'Max (Source.Capacity, Capacity)) do
287
         if Length (Source) > 0 then
288
            Target.Length := Source.Length;
289
            Target.Root := Source.Root;
290
            Target.First := Source.First;
291
            Target.Last := Source.Last;
292
            Target.Free := Source.Free;
293
 
294
            while Node <= Source.Capacity loop
295
               Target.Nodes (Node).Element :=
296
                 Source.Nodes (Node).Element;
297
               Target.Nodes (Node).Key :=
298
                 Source.Nodes (Node).Key;
299
               Target.Nodes (Node).Parent :=
300
                 Source.Nodes (Node).Parent;
301
               Target.Nodes (Node).Left :=
302
                 Source.Nodes (Node).Left;
303
               Target.Nodes (Node).Right :=
304
                 Source.Nodes (Node).Right;
305
               Target.Nodes (Node).Color :=
306
                 Source.Nodes (Node).Color;
307
               Target.Nodes (Node).Has_Element :=
308
                 Source.Nodes (Node).Has_Element;
309
               Node := Node + 1;
310
            end loop;
311
 
312
            while Node <= Target.Capacity loop
313
               N := Node;
314
               Formal_Ordered_Maps.Free (Tree => Target, X => N);
315
               Node := Node + 1;
316
            end loop;
317
         end if;
318
      end return;
319
   end Copy;
320
 
321
   ------------
322
   -- Delete --
323
   ------------
324
 
325
   procedure Delete (Container : in out Map; Position : in out Cursor) is
326
   begin
327
      if not Has_Element (Container, Position) then
328
         raise Constraint_Error with
329
           "Position cursor of Delete has no element";
330
      end if;
331
 
332
      pragma Assert (Vet (Container, Position.Node),
333
                     "Position cursor of Delete is bad");
334
 
335
      Tree_Operations.Delete_Node_Sans_Free (Container,
336
                                             Position.Node);
337
      Formal_Ordered_Maps.Free (Container, Position.Node);
338
   end Delete;
339
 
340
   procedure Delete (Container : in out Map; Key : Key_Type) is
341
      X : constant Node_Access := Key_Ops.Find (Container, Key);
342
 
343
   begin
344
      if X = 0 then
345
         raise Constraint_Error with "key not in map";
346
      end if;
347
 
348
      Tree_Operations.Delete_Node_Sans_Free (Container, X);
349
      Formal_Ordered_Maps.Free (Container, X);
350
   end Delete;
351
 
352
   ------------------
353
   -- Delete_First --
354
   ------------------
355
 
356
   procedure Delete_First (Container : in out Map) is
357
      X : constant Node_Access := First (Container).Node;
358
   begin
359
      if X /= 0 then
360
         Tree_Operations.Delete_Node_Sans_Free (Container, X);
361
         Formal_Ordered_Maps.Free (Container, X);
362
      end if;
363
   end Delete_First;
364
 
365
   -----------------
366
   -- Delete_Last --
367
   -----------------
368
 
369
   procedure Delete_Last (Container : in out Map) is
370
      X : constant Node_Access := Last (Container).Node;
371
   begin
372
      if X /= 0 then
373
         Tree_Operations.Delete_Node_Sans_Free (Container, X);
374
         Formal_Ordered_Maps.Free (Container, X);
375
      end if;
376
   end Delete_Last;
377
 
378
   -------------
379
   -- Element --
380
   -------------
381
 
382
   function Element (Container : Map; Position : Cursor) return Element_Type is
383
   begin
384
      if not Has_Element (Container, Position) then
385
         raise Constraint_Error with
386
           "Position cursor of function Element has no element";
387
      end if;
388
 
389
      pragma Assert (Vet (Container, Position.Node),
390
                     "Position cursor of function Element is bad");
391
 
392
      return Container.Nodes (Position.Node).Element;
393
 
394
   end Element;
395
 
396
   function Element (Container : Map; Key : Key_Type) return Element_Type is
397
      Node : constant Node_Access := Find (Container, Key).Node;
398
 
399
   begin
400
      if Node = 0 then
401
         raise Constraint_Error with "key not in map";
402
      end if;
403
 
404
      return Container.Nodes (Node).Element;
405
   end Element;
406
 
407
   ---------------------
408
   -- Equivalent_Keys --
409
   ---------------------
410
 
411
   function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
412
   begin
413
      if Left < Right
414
        or else Right < Left
415
      then
416
         return False;
417
      else
418
         return True;
419
      end if;
420
   end Equivalent_Keys;
421
 
422
   -------------
423
   -- Exclude --
424
   -------------
425
 
426
   procedure Exclude (Container : in out Map; Key : Key_Type) is
427
      X : constant Node_Access := Key_Ops.Find (Container, Key);
428
   begin
429
      if X /= 0 then
430
         Tree_Operations.Delete_Node_Sans_Free (Container, X);
431
         Formal_Ordered_Maps.Free (Container, X);
432
      end if;
433
   end Exclude;
434
 
435
   ----------
436
   -- Find --
437
   ----------
438
 
439
   function Find (Container : Map; Key : Key_Type) return Cursor is
440
      Node : constant Count_Type := Key_Ops.Find (Container, Key);
441
 
442
   begin
443
      if Node = 0 then
444
         return No_Element;
445
      end if;
446
 
447
      return (Node => Node);
448
   end Find;
449
 
450
   -----------
451
   -- First --
452
   -----------
453
 
454
   function First (Container : Map) return Cursor is
455
   begin
456
      if Length (Container) = 0 then
457
         return No_Element;
458
      end if;
459
 
460
      return (Node => Container.First);
461
   end First;
462
 
463
   -------------------
464
   -- First_Element --
465
   -------------------
466
 
467
   function First_Element (Container : Map) return Element_Type is
468
   begin
469
      if Is_Empty (Container) then
470
         raise Constraint_Error with "map is empty";
471
      end if;
472
 
473
      return Container.Nodes (First (Container).Node).Element;
474
   end First_Element;
475
 
476
   ---------------
477
   -- First_Key --
478
   ---------------
479
 
480
   function First_Key (Container : Map) return Key_Type is
481
   begin
482
      if Is_Empty (Container) then
483
         raise Constraint_Error with "map is empty";
484
      end if;
485
 
486
      return Container.Nodes (First (Container).Node).Key;
487
   end First_Key;
488
 
489
   -----------
490
   -- Floor --
491
   -----------
492
 
493
   function Floor (Container : Map; Key : Key_Type) return Cursor is
494
      Node : constant Count_Type := Key_Ops.Floor (Container, Key);
495
 
496
   begin
497
      if Node = 0 then
498
         return No_Element;
499
      end if;
500
 
501
      return (Node => Node);
502
   end Floor;
503
 
504
   ----------
505
   -- Free --
506
   ----------
507
 
508
   procedure Free
509
     (Tree : in out Map;
510
      X  : Count_Type)
511
   is
512
   begin
513
      Tree.Nodes (X).Has_Element := False;
514
      Tree_Operations.Free (Tree, X);
515
   end Free;
516
 
517
   ----------------------
518
   -- Generic_Allocate --
519
   ----------------------
520
 
521
   procedure Generic_Allocate
522
     (Tree : in out Tree_Types.Tree_Type'Class;
523
      Node : out Count_Type)
524
   is
525
      procedure Allocate is
526
        new Tree_Operations.Generic_Allocate (Set_Element);
527
   begin
528
      Allocate (Tree, Node);
529
      Tree.Nodes (Node).Has_Element := True;
530
   end Generic_Allocate;
531
 
532
   -----------------
533
   -- Has_Element --
534
   -----------------
535
 
536
   function Has_Element (Container : Map; Position : Cursor) return Boolean is
537
   begin
538
      if Position.Node = 0 then
539
         return False;
540
      end if;
541
 
542
      return Container.Nodes (Position.Node).Has_Element;
543
   end Has_Element;
544
 
545
   -------------
546
   -- Include --
547
   -------------
548
 
549
   procedure Include
550
     (Container : in out Map;
551
      Key       : Key_Type;
552
      New_Item  : Element_Type)
553
   is
554
      Position : Cursor;
555
      Inserted : Boolean;
556
 
557
   begin
558
      Insert (Container, Key, New_Item, Position, Inserted);
559
 
560
      if not Inserted then
561
         if Container.Lock > 0 then
562
            raise Program_Error with
563
              "attempt to tamper with cursors (map is locked)";
564
         end if;
565
 
566
         declare
567
            N : Node_Type renames Container.Nodes (Position.Node);
568
         begin
569
            N.Key := Key;
570
            N.Element := New_Item;
571
         end;
572
      end if;
573
   end Include;
574
 
575
   procedure Insert
576
     (Container : in out Map;
577
      Key       : Key_Type;
578
      New_Item  : Element_Type;
579
      Position  : out Cursor;
580
      Inserted  : out Boolean)
581
   is
582
      function New_Node return Node_Access;
583
      --  Comment ???
584
 
585
      procedure Insert_Post is
586
        new Key_Ops.Generic_Insert_Post (New_Node);
587
 
588
      procedure Insert_Sans_Hint is
589
        new Key_Ops.Generic_Conditional_Insert (Insert_Post);
590
 
591
      --------------
592
      -- New_Node --
593
      --------------
594
 
595
      function New_Node return Node_Access is
596
         procedure Initialize (Node : in out Node_Type);
597
         procedure Allocate_Node is new Generic_Allocate (Initialize);
598
 
599
         procedure Initialize (Node : in out Node_Type) is
600
         begin
601
            Node.Key := Key;
602
            Node.Element := New_Item;
603
         end Initialize;
604
 
605
         X : Node_Access;
606
 
607
      begin
608
         Allocate_Node (Container, X);
609
         return X;
610
      end New_Node;
611
 
612
   --  Start of processing for Insert
613
 
614
   begin
615
      Insert_Sans_Hint
616
        (Container,
617
         Key,
618
         Position.Node,
619
         Inserted);
620
   end Insert;
621
 
622
   procedure Insert
623
     (Container : in out Map;
624
      Key       : Key_Type;
625
      New_Item  : Element_Type)
626
   is
627
      Position : Cursor;
628
      Inserted : Boolean;
629
 
630
   begin
631
      Insert (Container, Key, New_Item, Position, Inserted);
632
 
633
      if not Inserted then
634
         raise Constraint_Error with "key already in map";
635
      end if;
636
   end Insert;
637
 
638
   ------------
639
   -- Insert --
640
   ------------
641
 
642
   procedure Insert
643
     (Container : in out Map;
644
      Key       : Key_Type;
645
      Position  : out Cursor;
646
      Inserted  : out Boolean)
647
   is
648
      function New_Node return Node_Access;
649
 
650
      procedure Insert_Post is
651
        new Key_Ops.Generic_Insert_Post (New_Node);
652
 
653
      procedure Insert_Sans_Hint is
654
        new Key_Ops.Generic_Conditional_Insert (Insert_Post);
655
 
656
      --------------
657
      -- New_Node --
658
      --------------
659
 
660
      function New_Node return Node_Access is
661
         procedure Initialize (Node : in out Node_Type);
662
         procedure Allocate_Node is new Generic_Allocate (Initialize);
663
 
664
         ----------------
665
         -- Initialize --
666
         ----------------
667
 
668
         procedure Initialize (Node : in out Node_Type) is
669
         begin
670
            Node.Key := Key;
671
         end Initialize;
672
 
673
         X : Node_Access;
674
 
675
      --  Start of processing for New_Node
676
 
677
      begin
678
         Allocate_Node (Container, X);
679
         return X;
680
      end New_Node;
681
 
682
   --  Start of processing for Insert
683
 
684
   begin
685
      Insert_Sans_Hint (Container, Key, Position.Node, Inserted);
686
   end Insert;
687
 
688
   --------------
689
   -- Is_Empty --
690
   --------------
691
 
692
   function Is_Empty (Container : Map) return Boolean is
693
   begin
694
      return Length (Container) = 0;
695
   end Is_Empty;
696
 
697
   -------------------------
698
   -- Is_Greater_Key_Node --
699
   -------------------------
700
 
701
   function Is_Greater_Key_Node
702
     (Left  : Key_Type;
703
      Right : Node_Type) return Boolean
704
   is
705
   begin
706
      --  k > node same as node < k
707
 
708
      return Right.Key < Left;
709
   end Is_Greater_Key_Node;
710
 
711
   ----------------------
712
   -- Is_Less_Key_Node --
713
   ----------------------
714
 
715
   function Is_Less_Key_Node
716
     (Left  : Key_Type;
717
      Right : Node_Type) return Boolean
718
   is
719
   begin
720
      return Left < Right.Key;
721
   end Is_Less_Key_Node;
722
 
723
   -------------
724
   -- Iterate --
725
   -------------
726
 
727
   procedure Iterate
728
     (Container : Map;
729
      Process   :
730
        not null access procedure (Container : Map; Position : Cursor))
731
   is
732
      procedure Process_Node (Node : Node_Access);
733
      pragma Inline (Process_Node);
734
 
735
      procedure Local_Iterate is
736
        new Tree_Operations.Generic_Iteration (Process_Node);
737
 
738
      ------------------
739
      -- Process_Node --
740
      ------------------
741
 
742
      procedure Process_Node (Node : Node_Access) is
743
      begin
744
         Process (Container, (Node => Node));
745
      end Process_Node;
746
 
747
      B : Natural renames Container'Unrestricted_Access.Busy;
748
 
749
      --  Start of processing for Iterate
750
 
751
   begin
752
      B := B + 1;
753
 
754
      begin
755
         Local_Iterate (Container);
756
      exception
757
         when others =>
758
            B := B - 1;
759
            raise;
760
      end;
761
 
762
      B := B - 1;
763
   end Iterate;
764
 
765
   ---------
766
   -- Key --
767
   ---------
768
 
769
   function Key (Container : Map; Position : Cursor) return Key_Type is
770
   begin
771
      if not Has_Element (Container, Position) then
772
         raise Constraint_Error with
773
           "Position cursor of function Key has no element";
774
      end if;
775
 
776
      pragma Assert (Vet (Container, Position.Node),
777
                     "Position cursor of function Key is bad");
778
 
779
      return Container.Nodes (Position.Node).Key;
780
   end Key;
781
 
782
   ----------
783
   -- Last --
784
   ----------
785
 
786
   function Last (Container : Map) return Cursor is
787
   begin
788
      if Length (Container) = 0 then
789
         return No_Element;
790
      end if;
791
 
792
      return (Node => Container.Last);
793
   end Last;
794
 
795
   ------------------
796
   -- Last_Element --
797
   ------------------
798
 
799
   function Last_Element (Container : Map) return Element_Type is
800
   begin
801
      if Is_Empty (Container) then
802
         raise Constraint_Error with "map is empty";
803
      end if;
804
 
805
      return Container.Nodes (Last (Container).Node).Element;
806
   end Last_Element;
807
 
808
   --------------
809
   -- Last_Key --
810
   --------------
811
 
812
   function Last_Key (Container : Map) return Key_Type is
813
   begin
814
      if Is_Empty (Container) then
815
         raise Constraint_Error with "map is empty";
816
      end if;
817
 
818
      return Container.Nodes (Last (Container).Node).Key;
819
   end Last_Key;
820
 
821
   ----------
822
   -- Left --
823
   ----------
824
 
825
   function Left (Container : Map; Position : Cursor) return Map is
826
      Curs : Cursor := Position;
827
      C    : Map (Container.Capacity) := Copy (Container, Container.Capacity);
828
      Node : Count_Type;
829
 
830
   begin
831
      if Curs = No_Element then
832
         return C;
833
      end if;
834
 
835
      if not Has_Element (Container, Curs) then
836
         raise Constraint_Error;
837
      end if;
838
 
839
      while Curs.Node /= 0 loop
840
         Node := Curs.Node;
841
         Delete (C, Curs);
842
         Curs := Next (Container, (Node => Node));
843
      end loop;
844
 
845
      return C;
846
   end Left;
847
 
848
   --------------
849
   -- Left_Son --
850
   --------------
851
 
852
   function Left_Son (Node : Node_Type) return Count_Type is
853
   begin
854
      return Node.Left;
855
   end Left_Son;
856
 
857
   ------------
858
   -- Length --
859
   ------------
860
 
861
   function Length (Container : Map) return Count_Type is
862
   begin
863
      return Container.Length;
864
   end Length;
865
 
866
   ----------
867
   -- Move --
868
   ----------
869
 
870
   procedure Move (Target : in out Map; Source : in out Map) is
871
      NN : Tree_Types.Nodes_Type renames Source.Nodes;
872
      X  : Node_Access;
873
 
874
   begin
875
      if Target'Address = Source'Address then
876
         return;
877
      end if;
878
 
879
      if Target.Capacity < Length (Source) then
880
         raise Constraint_Error with  -- ???
881
           "Source length exceeds Target capacity";
882
      end if;
883
 
884
      if Source.Busy > 0 then
885
         raise Program_Error with
886
           "attempt to tamper with cursors of Source (list is busy)";
887
      end if;
888
 
889
      Clear (Target);
890
 
891
      loop
892
         X := First (Source).Node;
893
         exit when X = 0;
894
 
895
         --  Here we insert a copy of the source element into the target, and
896
         --  then delete the element from the source. Another possibility is
897
         --  that delete it first (and hang onto its index), then insert it.
898
         --  ???
899
 
900
         Insert (Target, NN (X).Key, NN (X).Element);  -- optimize???
901
 
902
         Tree_Operations.Delete_Node_Sans_Free (Source, X);
903
         Formal_Ordered_Maps.Free (Source, X);
904
      end loop;
905
   end Move;
906
 
907
   ----------
908
   -- Next --
909
   ----------
910
 
911
   procedure Next (Container : Map; Position : in out Cursor) is
912
   begin
913
      Position := Next (Container, Position);
914
   end Next;
915
 
916
   function Next (Container : Map; Position : Cursor) return Cursor is
917
   begin
918
      if Position = No_Element then
919
         return No_Element;
920
      end if;
921
 
922
      if not Has_Element (Container, Position) then
923
         raise Constraint_Error;
924
      end if;
925
 
926
      pragma Assert (Vet (Container, Position.Node),
927
                     "bad cursor in Next");
928
 
929
      return (Node => Tree_Operations.Next (Container, Position.Node));
930
   end Next;
931
 
932
   -------------
933
   -- Overlap --
934
   -------------
935
 
936
   function Overlap (Left, Right : Map) return Boolean is
937
   begin
938
      if Length (Left) = 0 or Length (Right) = 0 then
939
         return False;
940
      end if;
941
 
942
      declare
943
         L_Node : Count_Type          := First (Left).Node;
944
         R_Node : Count_Type          := First (Right).Node;
945
         L_Last : constant Count_Type := Next (Left, Last (Left).Node);
946
         R_Last : constant Count_Type := Next (Right, Last (Right).Node);
947
 
948
      begin
949
         if Left'Address = Right'Address then
950
            return True;
951
         end if;
952
 
953
         loop
954
            if L_Node = L_Last
955
              or else R_Node = R_Last
956
            then
957
               return False;
958
            end if;
959
 
960
            if Left.Nodes (L_Node).Key < Right.Nodes (R_Node).Key then
961
               L_Node := Next (Left, L_Node);
962
 
963
            elsif Right.Nodes (R_Node).Key < Left.Nodes (L_Node).Key then
964
               R_Node := Next (Right, R_Node);
965
 
966
            else
967
               return True;
968
            end if;
969
         end loop;
970
      end;
971
   end Overlap;
972
 
973
   ------------
974
   -- Parent --
975
   ------------
976
 
977
   function Parent (Node : Node_Type) return Count_Type is
978
   begin
979
      return Node.Parent;
980
   end Parent;
981
 
982
   --------------
983
   -- Previous --
984
   --------------
985
 
986
   procedure Previous (Container : Map; Position : in out Cursor) is
987
   begin
988
      Position := Previous (Container, Position);
989
   end Previous;
990
 
991
   function Previous (Container : Map; Position : Cursor) return Cursor is
992
   begin
993
      if Position = No_Element then
994
         return No_Element;
995
      end if;
996
 
997
      if not Has_Element (Container, Position) then
998
         raise Constraint_Error;
999
      end if;
1000
 
1001
      pragma Assert (Vet (Container, Position.Node),
1002
                     "bad cursor in Previous");
1003
 
1004
      declare
1005
         Node : constant Count_Type :=
1006
                  Tree_Operations.Previous (Container, Position.Node);
1007
 
1008
      begin
1009
         if Node = 0 then
1010
            return No_Element;
1011
         end if;
1012
 
1013
         return (Node => Node);
1014
      end;
1015
   end Previous;
1016
 
1017
   -------------------
1018
   -- Query_Element --
1019
   -------------------
1020
 
1021
   procedure Query_Element
1022
     (Container : in out Map;
1023
      Position  : Cursor;
1024
      Process   : not null access procedure (Key     : Key_Type;
1025
                                             Element : Element_Type))
1026
   is
1027
   begin
1028
      if not Has_Element (Container, Position) then
1029
         raise Constraint_Error with
1030
           "Position cursor of Query_Element has no element";
1031
      end if;
1032
 
1033
      pragma Assert (Vet (Container, Position.Node),
1034
                     "Position cursor of Query_Element is bad");
1035
 
1036
      declare
1037
         B : Natural renames Container.Busy;
1038
         L : Natural renames Container.Lock;
1039
 
1040
      begin
1041
         B := B + 1;
1042
         L := L + 1;
1043
 
1044
         declare
1045
            N  : Node_Type renames Container.Nodes (Position.Node);
1046
            K  : Key_Type renames N.Key;
1047
            E  : Element_Type renames N.Element;
1048
 
1049
         begin
1050
            Process (K, E);
1051
         exception
1052
            when others =>
1053
               L := L - 1;
1054
               B := B - 1;
1055
               raise;
1056
         end;
1057
 
1058
         L := L - 1;
1059
         B := B - 1;
1060
      end;
1061
   end Query_Element;
1062
 
1063
   ----------
1064
   -- Read --
1065
   ----------
1066
 
1067
   procedure Read
1068
     (Stream    : not null access Root_Stream_Type'Class;
1069
      Container : out Map)
1070
   is
1071
      procedure Read_Element (Node : in out Node_Type);
1072
      pragma Inline (Read_Element);
1073
 
1074
      procedure Allocate is
1075
         new Generic_Allocate (Read_Element);
1076
 
1077
      procedure Read_Elements is
1078
         new Tree_Operations.Generic_Read (Allocate);
1079
 
1080
      ------------------
1081
      -- Read_Element --
1082
      ------------------
1083
 
1084
      procedure Read_Element (Node : in out Node_Type) is
1085
      begin
1086
         Key_Type'Read (Stream, Node.Key);
1087
         Element_Type'Read (Stream, Node.Element);
1088
      end Read_Element;
1089
 
1090
   --  Start of processing for Read
1091
 
1092
   begin
1093
      Read_Elements (Stream, Container);
1094
   end Read;
1095
 
1096
   procedure Read
1097
     (Stream : not null access Root_Stream_Type'Class;
1098
      Item   : out Cursor)
1099
   is
1100
   begin
1101
      raise Program_Error with "attempt to stream map cursor";
1102
   end Read;
1103
 
1104
   -------------
1105
   -- Replace --
1106
   -------------
1107
 
1108
   procedure Replace
1109
     (Container : in out Map;
1110
      Key       : Key_Type;
1111
      New_Item  : Element_Type)
1112
   is
1113
   begin
1114
      declare
1115
         Node : constant Node_Access := Key_Ops.Find (Container, Key);
1116
 
1117
      begin
1118
         if Node = 0 then
1119
            raise Constraint_Error with "key not in map";
1120
         end if;
1121
 
1122
         if Container.Lock > 0 then
1123
            raise Program_Error with
1124
              "attempt to tamper with cursors (map is locked)";
1125
         end if;
1126
 
1127
         declare
1128
            N : Node_Type renames Container.Nodes (Node);
1129
         begin
1130
            N.Key := Key;
1131
            N.Element := New_Item;
1132
         end;
1133
      end;
1134
   end Replace;
1135
 
1136
   ---------------------
1137
   -- Replace_Element --
1138
   ---------------------
1139
 
1140
   procedure Replace_Element
1141
     (Container : in out Map;
1142
      Position  : Cursor;
1143
      New_Item  : Element_Type)
1144
   is
1145
   begin
1146
      if not Has_Element (Container, Position) then
1147
         raise Constraint_Error with
1148
           "Position cursor of Replace_Element has no element";
1149
      end if;
1150
 
1151
      if Container.Lock > 0 then
1152
         raise Program_Error with
1153
           "attempt to tamper with cursors (map is locked)";
1154
      end if;
1155
 
1156
      pragma Assert (Vet (Container, Position.Node),
1157
                     "Position cursor of Replace_Element is bad");
1158
 
1159
      Container.Nodes (Position.Node).Element := New_Item;
1160
   end Replace_Element;
1161
 
1162
   ---------------------
1163
   -- Reverse_Iterate --
1164
   ---------------------
1165
 
1166
   procedure Reverse_Iterate
1167
     (Container : Map;
1168
      Process   : not null access procedure (Container : Map;
1169
                                             Position : Cursor))
1170
   is
1171
      procedure Process_Node (Node : Node_Access);
1172
      pragma Inline (Process_Node);
1173
 
1174
      procedure Local_Reverse_Iterate is
1175
        new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1176
 
1177
      ------------------
1178
      -- Process_Node --
1179
      ------------------
1180
 
1181
      procedure Process_Node (Node : Node_Access) is
1182
      begin
1183
         Process (Container, (Node => Node));
1184
      end Process_Node;
1185
 
1186
      B : Natural renames Container'Unrestricted_Access.Busy;
1187
 
1188
   --  Start of processing for Reverse_Iterate
1189
 
1190
   begin
1191
      B := B + 1;
1192
 
1193
      begin
1194
         Local_Reverse_Iterate (Container);
1195
      exception
1196
         when others =>
1197
            B := B - 1;
1198
            raise;
1199
      end;
1200
 
1201
      B := B - 1;
1202
   end Reverse_Iterate;
1203
 
1204
   -----------
1205
   -- Right --
1206
   -----------
1207
 
1208
   function Right (Container : Map; Position : Cursor) return Map is
1209
      Curs : Cursor := First (Container);
1210
      C    : Map (Container.Capacity) := Copy (Container, Container.Capacity);
1211
      Node : Count_Type;
1212
 
1213
   begin
1214
      if Curs = No_Element then
1215
         Clear (C);
1216
         return C;
1217
 
1218
      end if;
1219
      if Position /= No_Element and not Has_Element (Container, Position) then
1220
         raise Constraint_Error;
1221
      end if;
1222
 
1223
      while Curs.Node /= Position.Node loop
1224
         Node := Curs.Node;
1225
         Delete (C, Curs);
1226
         Curs := Next (Container, (Node => Node));
1227
      end loop;
1228
 
1229
      return C;
1230
   end Right;
1231
 
1232
   ---------------
1233
   -- Right_Son --
1234
   ---------------
1235
 
1236
   function Right_Son (Node : Node_Type) return Count_Type is
1237
   begin
1238
      return Node.Right;
1239
   end Right_Son;
1240
 
1241
   ---------------
1242
   -- Set_Color --
1243
   ---------------
1244
 
1245
   procedure Set_Color (Node  : in out Node_Type; Color : Color_Type) is
1246
   begin
1247
      Node.Color := Color;
1248
   end Set_Color;
1249
 
1250
   --------------
1251
   -- Set_Left --
1252
   --------------
1253
 
1254
   procedure Set_Left (Node : in out Node_Type; Left : Count_Type) is
1255
   begin
1256
      Node.Left := Left;
1257
   end Set_Left;
1258
 
1259
   ----------------
1260
   -- Set_Parent --
1261
   ----------------
1262
 
1263
   procedure Set_Parent (Node : in out Node_Type; Parent : Count_Type) is
1264
   begin
1265
      Node.Parent := Parent;
1266
   end Set_Parent;
1267
 
1268
   ---------------
1269
   -- Set_Right --
1270
   ---------------
1271
 
1272
   procedure Set_Right (Node : in out Node_Type; Right : Count_Type) is
1273
   begin
1274
      Node.Right := Right;
1275
   end Set_Right;
1276
 
1277
   ------------------
1278
   -- Strict_Equal --
1279
   ------------------
1280
 
1281
   function Strict_Equal (Left, Right : Map) return Boolean is
1282
      LNode : Count_Type := First (Left).Node;
1283
      RNode : Count_Type := First (Right).Node;
1284
 
1285
   begin
1286
      if Length (Left) /= Length (Right) then
1287
         return False;
1288
      end if;
1289
 
1290
      while LNode = RNode loop
1291
         if LNode = 0 then
1292
            return True;
1293
         end if;
1294
 
1295
         if Left.Nodes (LNode).Element /= Right.Nodes (RNode).Element
1296
           or else Left.Nodes (LNode).Key /= Right.Nodes (RNode).Key
1297
         then
1298
            exit;
1299
         end if;
1300
 
1301
         LNode := Next (Left, LNode);
1302
         RNode := Next (Right, RNode);
1303
      end loop;
1304
 
1305
      return False;
1306
   end Strict_Equal;
1307
 
1308
   --------------------
1309
   -- Update_Element --
1310
   --------------------
1311
 
1312
   procedure Update_Element
1313
     (Container : in out Map;
1314
      Position  : Cursor;
1315
      Process   : not null access procedure (Key     : Key_Type;
1316
                                             Element : in out Element_Type))
1317
   is
1318
   begin
1319
      if not Has_Element (Container, Position) then
1320
         raise Constraint_Error with
1321
           "Position cursor of Update_Element has no element";
1322
      end if;
1323
 
1324
      pragma Assert (Vet (Container, Position.Node),
1325
                     "Position cursor of Update_Element is bad");
1326
 
1327
      declare
1328
         B : Natural renames Container.Busy;
1329
         L : Natural renames Container.Lock;
1330
 
1331
      begin
1332
         B := B + 1;
1333
         L := L + 1;
1334
 
1335
         declare
1336
            N : Node_Type renames Container.Nodes (Position.Node);
1337
            K : Key_Type renames N.Key;
1338
            E : Element_Type renames N.Element;
1339
 
1340
         begin
1341
            Process (K, E);
1342
         exception
1343
            when others =>
1344
               L := L - 1;
1345
               B := B - 1;
1346
               raise;
1347
         end;
1348
 
1349
         L := L - 1;
1350
         B := B - 1;
1351
      end;
1352
   end Update_Element;
1353
 
1354
   -----------
1355
   -- Write --
1356
   -----------
1357
 
1358
   procedure Write
1359
     (Stream    : not null access Root_Stream_Type'Class;
1360
      Container : Map)
1361
   is
1362
      procedure Write_Node
1363
        (Stream : not null access Root_Stream_Type'Class;
1364
         Node   : Node_Type);
1365
      pragma Inline (Write_Node);
1366
 
1367
      procedure Write_Nodes is
1368
         new Tree_Operations.Generic_Write (Write_Node);
1369
 
1370
      ----------------
1371
      -- Write_Node --
1372
      ----------------
1373
 
1374
      procedure Write_Node
1375
        (Stream : not null access Root_Stream_Type'Class;
1376
         Node   : Node_Type)
1377
      is
1378
      begin
1379
         Key_Type'Write (Stream, Node.Key);
1380
         Element_Type'Write (Stream, Node.Element);
1381
      end Write_Node;
1382
 
1383
   --  Start of processing for Write
1384
 
1385
   begin
1386
      Write_Nodes (Stream, Container);
1387
   end Write;
1388
 
1389
   procedure Write
1390
     (Stream : not null access Root_Stream_Type'Class;
1391
      Item   : Cursor)
1392
   is
1393
   begin
1394
      raise Program_Error with "attempt to stream map cursor";
1395
   end Write;
1396
 
1397
end Ada.Containers.Formal_Ordered_Maps;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.