1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
28 //////////////////////////////////////////////////////////////////////////
29 // Indexable<T> is a type of array-like objects that can grow or shrink.
30 //////////////////////////////////////////////////////////////////////////
32 #include <AD/generic/generic.h> // generic definitions
33 #include <AD/generic/tables.h> // tables of Fibonacci numbers
35 ////////////////////////////////////////////////////////////////////////
36 // Class Indexable<T> is actually implemented as a bi-level table.
37 // The first level is an index into a second level tables.
38 // The second level tables are allocated only if needed.
39 ////////////////////////////////////////////////////////////////////////
44 T
** table
; // a bi-level index.
45 int segments
; // number of segments currently allocated.
46 int limit
; // current limit
47 const int Max_segments
= 32;
51 /////////////////////////////////////////////////////////////////
52 // Constructors and destructor
53 /////////////////////////////////////////////////////////////////
55 Indexable(const Indexable
&);
56 Indexable(int n
, const T
[]);
59 /////////////////////////////////////////////////////////////////
61 /////////////////////////////////////////////////////////////////
62 Indexable
& operator = (const Indexable
&);
64 /////////////////////////////////////////////////////////////////
66 /////////////////////////////////////////////////////////////////
67 inline int size() const { return limit
; }
68 inline int length() const { return limit
; }
69 inline int capacity() const { return limit
; }
70 inline int lo() const { return 0; }
71 inline int hi() const { return limit
- 1; }
72 const T
& operator [] (int i
) const;
73 T
& operator [] (int i
);
75 /////////////////////////////////////////////////////////////////
77 /////////////////////////////////////////////////////////////////
81 /////////////////////////////////////////////////////////////////
83 // Since indexing with operator [] is not the fastest way
84 // to get to the data, we provide an iterator service to the
86 /////////////////////////////////////////////////////////////////
87 inline Ix
first() const { return Ix(1); }
88 inline Ix
last() const { return Ix(limit
+ 1); }
89 inline Ix
next(Ix i
) const { return Ix((int)i
+1); }
90 inline Ix
prev(Ix i
) const { return Ix((int)i
-1); }
91 inline const T
& operator () (Ix i
) const { return (*this)[(int)i
]; }
92 inline T
& operator () (Ix i
) { return (*this)[(int)i
]; }
95 //////////////////////////////////////////////////////////////////////////////
96 // Implementation of the template methods
97 //////////////////////////////////////////////////////////////////////////////
99 //////////////////////////////////////////////////////////////////////////////
101 //////////////////////////////////////////////////////////////////////////////
103 Indexable
<T
>::Indexable()
104 { table
= new T
* [ Max_segments
]; segments
= limit
= 0; }
106 //////////////////////////////////////////////////////////////////////////////
108 //////////////////////////////////////////////////////////////////////////////
110 Indexable
<T
>::Indexable(const Indexable
<T
>& I
)
111 { table
= new T
* [ Max_segments
]; segments
= limit
= 0;
115 //////////////////////////////////////////////////////////////////////////////
117 //////////////////////////////////////////////////////////////////////////////
119 Indexable
<T
>::Indexable(int n
, const T t
[])
120 { table
= new T
* [ Max_segments
]; segments
= limit
= 0;
122 register const T
* a
= t
;
123 for (int i
= 0; i
< segments
; i
++) {
124 register T
* b
= tables
[i
];
125 for (register int j
= fibnacci
[i
+5] - 1; j
>= 0; j
--) *b
++ = *a
++;
129 //////////////////////////////////////////////////////////////////////////////
131 //////////////////////////////////////////////////////////////////////////////
133 Indexable
<T
>::~Indexable() { clear(); delete [] table
; }
135 //////////////////////////////////////////////////////////////////////////////
137 //////////////////////////////////////////////////////////////////////////////
139 Indexable
<T
>& Indexable
<T
>::operator = (const Indexable
<T
>& t
)
142 for (int i
= 0; i
< segments
; i
++) {
143 register const T
* a
= t
.tables
[i
];
144 register T
* b
= tables
[i
];
145 for (register int j
= fibnacci
[i
+5] - 1; j
>= 0; j
--) *b
++ = *a
++;
151 //////////////////////////////////////////////////////////////////////////////
153 //////////////////////////////////////////////////////////////////////////////
155 void Indexable
<T
>::clear()
156 { for (int i
= segments
- 1; i
>= 0; i
--)
158 limit
= segments
= 0;
161 //////////////////////////////////////////////////////////////////////////////
163 //////////////////////////////////////////////////////////////////////////////
165 const T
& Indexable
<T
>::operator [] (int i
) const
166 { for (int j
= 0; j
< Max_segments
; j
++)
167 if (fibonacci
[j
+6] > i
) break;
168 return tables
[j
][ i
- fibonacci
[j
+5] ];
171 //////////////////////////////////////////////////////////////////////////////
173 //////////////////////////////////////////////////////////////////////////////
175 T
& Indexable
<T
>::operator [] (int i
)
176 { if (i
>= limit
) resize(i
);
177 for (int j
= 0; j
< Max_segments
; j
++)
178 if (fibonacci
[j
+6] > i
) break;
179 return tables
[j
][ i
- fibonacci
[j
+5] ];
182 //////////////////////////////////////////////////////////////////////////////
184 //////////////////////////////////////////////////////////////////////////////
186 void Indexable
<T
>::resize(int n
)
187 { if (n
< limit
) return;
188 while (fibonacci
[segments
+6] < n
) {
189 table
[segments
] = new T fibonacci
[segments
+5];
192 limit
= fibonacci
[segments
+6];