summaryrefslogtreecommitdiff
path: root/misc/count_tables.ads
blob: 9f3055cde0abeb9d2040f3b372b7a18e2ab14b73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124


with
    Ada.Iterator_Interfaces;

private with
    Ada.Containers.Indefinite_Ordered_Maps,
    Ada.Containers.Vectors,
    Ada.Finalization;

generic
    type Key_Type (<>) is private;
    with function "<" (Left, Right : Key_Type) return Boolean is <>;
package Count_Tables is

    --  This package imitates the basics of
    --  the Nim CountTable table variant.

    --  Functionality is incomplete and likely inefficient,
    --  as this was only put together for demonstrative purposes.

    type Map is tagged private
    with Variable_Indexing => Reference,
         Default_Iterator  => Iterate,
         Iterator_Element  => Natural;

    type Cursor is private;

    Empty_Map  : constant Map;
    No_Element : constant Cursor;

    function Has_Element
           (Position : Cursor)
        return Boolean;

    function Key
           (Position : Cursor)
        return Key_Type;

    function Element
           (Position : Cursor)
        return Natural;

    package Map_Iterator_Interfaces is new
        Ada.Iterator_Interfaces (Cursor, Has_Element);

    type Reference_Type (Element : not null access Natural) is private
    with Implicit_Dereference => Element;

    function Reference
           (Container : aliased in out Map;
            Position  :                Cursor)
        return Reference_Type;

    procedure Increment
           (Container : in out Map;
            Key       : in     Key_Type;
            Value     : in     Natural := 1);

    procedure Sort
           (Container : in out Map);

    function Iterate
           (Container : in Map)
        return Map_Iterator_Interfaces.Reversible_Iterator'Class;

private

    type Map_Access is access all Map;

    type Cursor is record
        My_Map : Map_Access;
        Index  : Positive;
    end record;

    package Internal_Maps is new Ada.Containers.Indefinite_Ordered_Maps (Key_Type, Natural);
    package Cursor_Vectors is new Ada.Containers.Vectors (Positive, Internal_Maps.Cursor, Internal_Maps."=");

    type Map is tagged record
        My_Map : Internal_Maps.Map;
        My_Vec : Cursor_Vectors.Vector;
    end record;

    Empty_Map  : constant Map :=
       (My_Map => Internal_Maps.Empty_Map,
        My_Vec => Cursor_Vectors.Empty_Vector);
    No_Element : constant Cursor :=
       (My_Map => null,
        Index  => 1);

    function Less
           (Left, Right : in Internal_Maps.Cursor)
        return Boolean;

    package Cursor_Sorting is new Cursor_Vectors.Generic_Sorting (Less);

    type Reference_Type (Element : not null access Natural) is null record;

    type Iterator is new Ada.Finalization.Limited_Controlled and
        Map_Iterator_Interfaces.Reversible_Iterator with
    record
        Container : Map_Access;
    end record;

    overriding function First
           (Object : in Iterator)
        return Cursor;

    overriding function Last
           (Object : in Iterator)
        return Cursor;

    overriding function Next
           (Object   : in Iterator;
            Position : in Cursor)
        return Cursor;

    overriding function Previous
           (Object   : in Iterator;
            Position : in Cursor)
        return Cursor;

end Count_Tables;