00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CASA_ORDEREDMAP_H
00029 #define CASA_ORDEREDMAP_H
00030
00031 #include <casacore/casa/aips.h>
00032 #include <casacore/casa/Exceptions/Error.h>
00033 #include <casacore/casa/Containers/Block.h>
00034 #include <casacore/casa/BasicSL/String.h>
00035 #include <casacore/casa/Containers/Map.h>
00036 #include <casacore/casa/Containers/OrderedPair.h>
00037 #include <casacore/casa/Utilities/Register.h>
00038 #include <casacore/casa/Utilities/Notice.h>
00039
00040 namespace casacore {
00041
00042 template<class t, class v> class OrderedMap;
00043 template<class t, class v> class OrderedMapRep;
00044 template<class t, class v> class OrderedMapIterRep;
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 template<class t,class v> class OrderedMapNotice : public Notice {
00057 friend class OrderedMapRep<t,v>;
00058 friend class OrderedMapIterRep<t,v>;
00059 private:
00060 enum NoticeType {CLEAR,DEFINE,REMOVE,DELETE} changeType;
00061 uInt modPos;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 OrderedMapNotice(uInt pos, NoticeType typ) : changeType(typ), modPos(pos) {}
00072
00073 public:
00074
00075
00076
00077
00078 uInt type() const {return Register(this);}
00079
00080
00081
00082
00083
00084 int operator==(const Notice &op) const {
00085 if (type() != op.type()) {
00086 return 0;
00087 } else {
00088 const OrderedMapNotice<t,v> &opD = (const OrderedMapNotice<t,v> &) op;
00089 return (modPos == opD.modPos && changeType == opD.changeType);
00090 }
00091 }
00092 };
00093
00094
00095
00096
00097
00098 template<class key, class value> class OrderedMapRep : public NoticeSource, public MapRep<key,value> {
00099 friend class OrderedMap<key,value>;
00100 public:
00101
00102
00103
00104
00105 OrderedMapRep (const value&, uInt size);
00106
00107
00108
00109
00110 OrderedMapRep (const value&);
00111
00112
00113
00114
00115
00116
00117
00118 value *isDefined(const key&);
00119 const value *isDefined(const key&) const;
00120
00121
00122
00123
00124
00125 uInt ndefined() const;
00126
00127
00128
00129
00130 value &define (const key&, const value&);
00131
00132
00133
00134
00135 void remove (const key&);
00136
00137
00138
00139
00140 void clear ();
00141
00142 MapIterRep<key,value> *getRep(Map<key,value> *) const;
00143
00144 MapRep<key,value> *Clone() const;
00145
00146
00147
00148
00149 uInt nused() const { return nrused; }
00150 uInt ntot() const { return nrtot; }
00151
00152
00153
00154
00155
00156 uInt incr() const { return nrincr; }
00157 uInt incr(uInt nri) { return (nrincr = nri); }
00158
00159
00160
00161
00162
00163 ~OrderedMapRep ();
00164
00165 enum {OrderedMapRepVersion = 1};
00166
00167 protected:
00168
00169
00170 PtrBlock<OrderedPair<key,value>*> kvblk;
00171 uInt nrtot;
00172 uInt nrused;
00173 uInt nrincr;
00174
00175
00176 uInt lastRef;
00177
00178
00179 Int findKey (const key&, Bool&) const;
00180 };
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 template<class key, class value> class OrderedMap : public Map<key,value> {
00210 friend class OrderedMapIterRep<key,value>;
00211 protected:
00212
00213 void throwgetKey(uInt) const;
00214 void throwgetValue(uInt) const;
00215
00216 value &getVal(uInt inx) {
00217 if (!this->Rep || inx >= nused())
00218 throwgetValue(inx);
00219 return (((OrderedMapRep<key,value> *)(this->Rep))->kvblk[inx]->y());
00220 }
00221
00222 const value &getVal(uInt inx) const {
00223 if (!this->Rep || inx >= nused())
00224 throwgetValue(inx);
00225 return (((OrderedMapRep<key,value> *)(this->Rep))->kvblk[inx]->y());
00226 }
00227
00228 key &getKey (uInt inx) {
00229 if (!this->Rep || inx >= nused())
00230 throwgetKey(inx);
00231 return (((OrderedMapRep<key,value> *)(this->Rep))->kvblk[inx]->x());
00232 }
00233
00234 const key &getKey (uInt inx) const {
00235 if (!this->Rep || inx >= nused())
00236 throwgetKey(inx);
00237 return (((OrderedMapRep<key,value> *)(this->Rep))->kvblk[inx]->x());
00238 }
00239
00240 public:
00241
00242
00243
00244
00245 OrderedMap (const value& dflt, uInt size) : Map<key,value>(new OrderedMapRep<key,value>(dflt,size)) { }
00246
00247
00248
00249
00250 explicit OrderedMap (const value& dflt) : Map<key,value>(new OrderedMapRep<key,value>(dflt)) { }
00251
00252
00253
00254
00255 OrderedMap (const OrderedMap<key,value>& other) : Map<key,value>(other.Rep->Clone()) { }
00256
00257
00258
00259
00260
00261 ~OrderedMap();
00262
00263
00264
00265
00266 OrderedMap<key,value>& operator= (const OrderedMap<key,value>& other) {
00267 this->SetRep(other.Rep->Clone());
00268 return *this;
00269 }
00270
00271
00272
00273
00274 uInt nused() const { return ((OrderedMapRep<key,value> *)(this->Rep))->nused(); }
00275 uInt ntot() const { return ((OrderedMapRep<key,value> *)(this->Rep))->ntot(); }
00276
00277
00278
00279
00280
00281 uInt incr() const { return ((OrderedMapRep<key,value> *)(this->Rep))->incr(); }
00282 uInt incr(uInt nri) { return ((OrderedMapRep<key,value> *)(this->Rep))->incr(nri);}
00283
00284
00285 enum {OrderedMapVersion = 1};
00286 };
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 template<class key, class value> class OrderedMapIterRep : virtual public MapIterRep<key,value>, public NoticeTarget {
00299 protected:
00300
00301
00302
00303
00304
00305
00306 void thrownext() const;
00307 void throwInvalidIter() const;
00308
00309
00310 OrderedMap<key,value> *container;
00311
00312 uInt CurIndex;
00313
00314 public:
00315
00316
00317
00318
00319 Bool isValid() const;
00320
00321
00322
00323
00324
00325
00326 Bool atEnd() const;
00327 Bool atStart() const;
00328
00329
00330
00331
00332
00333 void toStart();
00334
00335
00336
00337
00338
00339 void operator++();
00340 void operator++(int);
00341
00342
00343
00344
00345
00346
00347 const key &getKey () const;
00348 const key &getKey (uInt inx) const {
00349 if (!container || !isValid())
00350 throwInvalidIter();
00351 return ((*container).getKey(inx));
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 value &getVal(uInt inx) {
00363 if (!container || !isValid())
00364 throwInvalidIter();
00365 return ((*container).getVal(inx));
00366 }
00367
00368
00369
00370
00371
00372
00373 const value &getVal() const;
00374 const value &getVal(uInt inx) const {
00375 if (!container || !isValid())
00376 throwInvalidIter();
00377 return ((*container).getVal(inx));
00378 }
00379
00380 value &getVal() {return getVal(CurIndex);}
00381
00382
00383
00384 MapIterRep<key,value> *Clone() {
00385 OrderedMapIterRep<key,value> *ret = new OrderedMapIterRep<key,value>(container);
00386 return ret;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396 void notify(const Notice &);
00397
00398
00399
00400
00401
00402
00403 OrderedMapIterRep(OrderedMap<key,value> *st)
00404 : MapIterRep<key,value>(st),
00405 NoticeTarget((NoticeSource *)((OrderedMapRep<key,value> *) st->Rep)),
00406 container(st),
00407 CurIndex(0)
00408 {}
00409
00410 OrderedMapIterRep(OrderedMap<key,value> &st)
00411 : MapIterRep<key,value>(st),
00412 NoticeTarget((NoticeSource *)((OrderedMapRep<key,value> *) st.Rep)),
00413 container(&st),
00414 CurIndex(0)
00415 {}
00416
00417
00418 enum {OrderedMapIterRepVersion = 1};
00419
00420 };
00421
00422 }
00423 #ifndef CASACORE_NO_AUTO_TEMPLATES
00424 #include <casacore/casa/Containers/OrderedMap.tcc>
00425 #endif //# CASACORE_NO_AUTO_TEMPLATES
00426 #endif