00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined (octave_oct_map_h)
00025 #define octave_oct_map_h 1
00026
00027 #include <algorithm>
00028 #include <map>
00029
00030 #include "Cell.h"
00031 #include "oct-obj.h"
00032
00033 class string_vector;
00034
00035
00036 class OCTINTERP_API
00037 octave_fields
00038 {
00039 class fields_rep : public std::map<std::string, octave_idx_type>
00040 {
00041 public:
00042 fields_rep (void) : std::map<std::string, octave_idx_type> (), count (1) { }
00043 fields_rep (const fields_rep& other)
00044 : std::map<std::string, octave_idx_type> (other), count (1) { }
00045
00046 octave_refcount<int> count;
00047
00048 private:
00049 fields_rep& operator = (const fields_rep&);
00050 };
00051
00052 fields_rep *rep;
00053
00054 static fields_rep *nil_rep (void)
00055 {
00056 static fields_rep *nr = new fields_rep ();
00057 return nr;
00058 }
00059
00060 public:
00061
00062 octave_fields (void) : rep (nil_rep ()) { rep->count++; }
00063 octave_fields (const string_vector&);
00064 octave_fields (const char * const *);
00065
00066 ~octave_fields (void)
00067 {
00068 if (--rep->count == 0)
00069 delete rep;
00070 }
00071
00072 void make_unique (void)
00073 {
00074 if (rep->count > 1)
00075 {
00076 --rep->count;
00077 rep = new fields_rep (*rep);
00078 }
00079 }
00080
00081 octave_fields (const octave_fields& o) : rep (o.rep) { rep->count++; }
00082
00083 octave_fields&
00084 operator = (const octave_fields& o)
00085 {
00086 o.rep->count++;
00087 if (--rep->count == 0)
00088 delete rep;
00089 rep = o.rep;
00090
00091 return *this;
00092 }
00093
00094
00095
00096 typedef std::map<std::string, octave_idx_type>::const_iterator const_iterator;
00097 typedef const_iterator iterator;
00098
00099 const_iterator begin (void) const { return rep->begin (); }
00100 const_iterator end (void) const { return rep->end (); }
00101
00102 std::string key (const_iterator p) const { return p->first; }
00103 octave_idx_type index (const_iterator p) const { return p->second; }
00104
00105 const_iterator seek (const std::string& k) const
00106 { return rep->find (k); }
00107
00108
00109
00110
00111 octave_idx_type nfields (void) const { return rep->size (); }
00112
00113
00114 bool isfield (const std::string& name) const;
00115
00116
00117 octave_idx_type getfield (const std::string& name) const;
00118
00119 octave_idx_type getfield (const std::string& name);
00120
00121 octave_idx_type rmfield (const std::string& name);
00122
00123
00124
00125 void orderfields (Array<octave_idx_type>& perm);
00126
00127
00128
00129
00130 bool equal_up_to_order (const octave_fields& other,
00131 octave_idx_type* perm) const;
00132
00133 bool equal_up_to_order (const octave_fields& other,
00134 Array<octave_idx_type>& perm) const;
00135
00136 bool is_same (const octave_fields& other) const
00137 { return rep == other.rep; }
00138
00139
00140 string_vector fieldnames (void) const;
00141
00142 void clear (void)
00143 {
00144 *this = octave_fields ();
00145 }
00146 };
00147
00148
00149 class OCTINTERP_API
00150 octave_scalar_map
00151 {
00152 public:
00153
00154 octave_scalar_map (const octave_fields& k)
00155 : xkeys (k), xvals (k.nfields ()) { }
00156
00157 octave_scalar_map (void) : xkeys (), xvals () { }
00158
00159 octave_scalar_map (const string_vector& k)
00160 : xkeys (k), xvals (k.length ()) { }
00161
00162 octave_scalar_map (const octave_scalar_map& m)
00163 : xkeys (m.xkeys), xvals(m.xvals) { }
00164
00165 octave_scalar_map& operator = (const octave_scalar_map& m)
00166 {
00167 xkeys = m.xkeys;
00168 xvals = m.xvals;
00169
00170 return *this;
00171 }
00172
00173
00174
00175 typedef octave_fields::const_iterator const_iterator;
00176 typedef const_iterator iterator;
00177
00178 const_iterator begin (void) const { return xkeys.begin (); }
00179 const_iterator end (void) const { return xkeys.end (); }
00180
00181 const_iterator seek (const std::string& k) const { return xkeys.seek (k); }
00182
00183 std::string key (const_iterator p) const
00184 { return xkeys.key (p); }
00185 octave_idx_type index (const_iterator p) const
00186 { return xkeys.index (p); }
00187
00188 const octave_value& contents (const_iterator p) const
00189 { return xvals[xkeys.index (p)]; }
00190
00191 octave_value& contents (iterator p)
00192 { return xvals[xkeys.index (p)]; }
00193
00194 const octave_value& contents (octave_idx_type i) const
00195 { return xvals[i]; }
00196
00197 octave_value& contents (octave_idx_type i)
00198 { return xvals[i]; }
00199
00200
00201 octave_idx_type nfields (void) const { return xkeys.nfields (); }
00202
00203
00204 bool isfield (const std::string& name) const
00205 { return xkeys.isfield (name); }
00206
00207 bool contains (const std::string& name) const
00208 { return isfield (name); }
00209
00210 string_vector fieldnames (void) const
00211 { return xkeys.fieldnames (); }
00212
00213 string_vector keys (void) const
00214 { return fieldnames (); }
00215
00216
00217 octave_value getfield (const std::string& key) const;
00218
00219
00220 void setfield (const std::string& key, const octave_value& val);
00221 void assign (const std::string& k, const octave_value& val)
00222 { setfield (k, val); }
00223
00224
00225 void rmfield (const std::string& key);
00226 void del (const std::string& k) { rmfield (k); }
00227
00228
00229 octave_scalar_map orderfields (void) const;
00230 octave_scalar_map orderfields (Array<octave_idx_type>& perm) const;
00231 octave_scalar_map orderfields (const octave_scalar_map& other,
00232 Array<octave_idx_type>& perm) const;
00233
00234
00235 octave_value contents (const std::string& k) const;
00236 octave_value& contents (const std::string& k);
00237
00238 void clear (void)
00239 {
00240 xkeys.clear ();
00241 xvals.clear ();
00242 }
00243
00244 friend class octave_map;
00245
00246 private:
00247
00248 octave_fields xkeys;
00249 std::vector<octave_value> xvals;
00250
00251 };
00252
00253 template<>
00254 inline octave_scalar_map octave_value_extract<octave_scalar_map> (const octave_value& v)
00255 { return v.scalar_map_value (); }
00256
00257 class OCTINTERP_API
00258 octave_map
00259 {
00260 public:
00261
00262 octave_map (const octave_fields& k)
00263 : xkeys (k), xvals (k.nfields ()), dimensions () { }
00264
00265 octave_map (const dim_vector& dv, const octave_fields& k)
00266 : xkeys (k), xvals (k.nfields (), Cell (dv)), dimensions (dv) { }
00267
00268 typedef octave_scalar_map element_type;
00269
00270 octave_map (void) : xkeys (), xvals (), dimensions () { }
00271
00272 octave_map (const dim_vector& dv) : xkeys (), xvals (), dimensions (dv) { }
00273
00274 octave_map (const string_vector& k)
00275 : xkeys (k), xvals (k.length (), Cell (1, 1)), dimensions (1, 1) { }
00276
00277 octave_map (const dim_vector& dv, const string_vector& k)
00278 : xkeys (k), xvals (k.length (), Cell (dv)), dimensions (dv) { }
00279
00280 octave_map (const octave_map& m)
00281 : xkeys (m.xkeys), xvals (m.xvals), dimensions (m.dimensions) { }
00282
00283 octave_map (const octave_scalar_map& m);
00284
00285 octave_map (const Octave_map& m);
00286
00287 octave_map& operator = (const octave_map& m)
00288 {
00289 xkeys = m.xkeys;
00290 xvals = m.xvals;
00291 dimensions = m.dimensions;
00292
00293 return *this;
00294 }
00295
00296
00297
00298 typedef octave_fields::const_iterator const_iterator;
00299 typedef const_iterator iterator;
00300
00301 const_iterator begin (void) const { return xkeys.begin (); }
00302 const_iterator end (void) const { return xkeys.end (); }
00303
00304 const_iterator seek (const std::string& k) const { return xkeys.seek (k); }
00305
00306 std::string key (const_iterator p) const
00307 { return xkeys.key (p); }
00308 octave_idx_type index (const_iterator p) const
00309 { return xkeys.index (p); }
00310
00311 const Cell& contents (const_iterator p) const
00312 { return xvals[xkeys.index (p)]; }
00313
00314 Cell& contents (iterator p)
00315 { return xvals[xkeys.index (p)]; }
00316
00317 const Cell& contents (octave_idx_type i) const
00318 { return xvals[i]; }
00319
00320 Cell& contents (octave_idx_type i)
00321 { return xvals[i]; }
00322
00323
00324 octave_idx_type nfields (void) const { return xkeys.nfields (); }
00325
00326
00327 bool isfield (const std::string& name) const
00328 { return xkeys.isfield (name); }
00329
00330 bool contains (const std::string& name) const
00331 { return isfield (name); }
00332
00333 string_vector fieldnames (void) const
00334 { return xkeys.fieldnames (); }
00335
00336 string_vector keys (void) const
00337 { return fieldnames (); }
00338
00339
00340 Cell getfield (const std::string& key) const;
00341
00342
00343
00344 void setfield (const std::string& key, const Cell& val);
00345 void assign (const std::string& k, const Cell& val)
00346 { setfield (k, val); }
00347
00348
00349 void rmfield (const std::string& key);
00350 void del (const std::string& k) { rmfield (k); }
00351
00352
00353 octave_map orderfields (void) const;
00354 octave_map orderfields (Array<octave_idx_type>& perm) const;
00355 octave_map orderfields (const octave_map& other,
00356 Array<octave_idx_type>& perm) const;
00357
00358
00359 Cell contents (const std::string& k) const;
00360 Cell& contents (const std::string& k);
00361
00362 void clear (void)
00363 {
00364 xkeys.clear ();
00365 xvals.clear ();
00366 }
00367
00368
00369 octave_idx_type numel (void) const { return dimensions.numel (); }
00370 octave_idx_type length (void) const { return numel (); }
00371 bool is_empty (void) const { return dimensions.any_zero (); }
00372
00373 octave_idx_type rows (void) const { return dimensions(0); }
00374 octave_idx_type cols (void) const { return dimensions(1); }
00375 octave_idx_type columns (void) const { return dimensions(1); }
00376
00377
00378 octave_scalar_map checkelem (octave_idx_type n) const;
00379 octave_scalar_map checkelem (octave_idx_type i, octave_idx_type j) const;
00380
00381 octave_scalar_map
00382 checkelem (const Array<octave_idx_type>& ra_idx) const;
00383
00384 octave_scalar_map operator () (octave_idx_type n) const
00385 { return checkelem (n); }
00386 octave_scalar_map operator () (octave_idx_type i, octave_idx_type j) const
00387 { return checkelem (i, j); }
00388
00389 octave_scalar_map
00390 operator () (const Array<octave_idx_type>& ra_idx) const
00391 { return checkelem (ra_idx); }
00392
00393 octave_map squeeze (void) const;
00394
00395 octave_map permute (const Array<int>& vec, bool inv = false) const;
00396
00397 dim_vector dims (void) const { return dimensions; }
00398
00399 int ndims (void) const { return dimensions.length (); }
00400
00401 octave_map transpose (void) const;
00402
00403 octave_map reshape (const dim_vector& dv) const;
00404
00405 void resize (const dim_vector& dv, bool fill = false);
00406
00407 static octave_map
00408 cat (int dim, octave_idx_type n, const octave_scalar_map *map_list);
00409
00410 static octave_map
00411 cat (int dim, octave_idx_type n, const octave_map *map_list);
00412
00413 octave_map index (const idx_vector& i, bool resize_ok = false) const;
00414
00415 octave_map index (const idx_vector& i, const idx_vector& j,
00416 bool resize_ok = false) const;
00417
00418 octave_map index (const Array<idx_vector>& ia,
00419 bool resize_ok = false) const;
00420
00421 octave_map index (const octave_value_list&, bool resize_ok = false) const;
00422
00423 octave_map column (octave_idx_type k) const;
00424 octave_map page (octave_idx_type k) const;
00425
00426 void assign (const idx_vector& i, const octave_map& rhs);
00427
00428 void assign (const idx_vector& i, const idx_vector& j, const octave_map& rhs);
00429
00430 void assign (const Array<idx_vector>& ia, const octave_map& rhs);
00431
00432 void assign (const octave_value_list&, const octave_map& rhs);
00433
00434 void assign (const octave_value_list& idx, const std::string& k,
00435 const Cell& rhs);
00436
00437 void delete_elements (const idx_vector& i);
00438
00439 void delete_elements (int dim, const idx_vector& i);
00440
00441 void delete_elements (const Array<idx_vector>& ia);
00442
00443 void delete_elements (const octave_value_list&);
00444
00445 octave_map concat (const octave_map& rb, const Array<octave_idx_type>& ra_idx);
00446
00447
00448 octave_scalar_map fast_elem_extract (octave_idx_type n) const;
00449
00450
00451 bool fast_elem_insert (octave_idx_type n, const octave_scalar_map& rhs);
00452
00453 private:
00454
00455 octave_fields xkeys;
00456 std::vector<Cell> xvals;
00457 dim_vector dimensions;
00458
00459 void optimize_dimensions (void);
00460 void extract_scalar (octave_scalar_map& dest,
00461 octave_idx_type index) const;
00462 static void do_cat (int dim, octave_idx_type n,
00463 const octave_scalar_map *map_list, octave_map& retval);
00464 static void do_cat (int dim, octave_idx_type n,
00465 const octave_map *map_list, octave_map& retval);
00466 };
00467
00468 template<>
00469 inline octave_map octave_value_extract<octave_map> (const octave_value& v)
00470 { return v.map_value (); }
00471
00472
00473
00474
00475 class
00476 OCTINTERP_API
00477 Octave_map
00478 {
00479 public:
00480
00481 typedef std::map<std::string, Cell>::iterator iterator;
00482 typedef std::map<std::string, Cell>::const_iterator const_iterator;
00483
00484 typedef std::list<std::string>::iterator key_list_iterator;
00485 typedef std::list<std::string>::const_iterator const_key_list_iterator;
00486
00487
00488
00489 Octave_map (const dim_vector& dv = dim_vector (0, 0),
00490 const Cell& key_vals = Cell ());
00491
00492 Octave_map (const std::string& k, const octave_value& value)
00493 : map (), key_list (), dimensions (1, 1)
00494 {
00495 map[k] = value;
00496 key_list.push_back (k);
00497 }
00498
00499 Octave_map (const string_vector& sv,
00500 const dim_vector& dv = dim_vector (0, 0))
00501 : map (), key_list (), dimensions (dv)
00502 {
00503 for (octave_idx_type i = 0; i < sv.length (); i++)
00504 {
00505 std::string k = sv[i];
00506 map[k] = Cell (dv);
00507 key_list.push_back (k);
00508 }
00509 }
00510
00511 Octave_map (const std::string& k, const Cell& vals)
00512 : map (), key_list (), dimensions (vals.dims ())
00513 {
00514 map[k] = vals;
00515 key_list.push_back (k);
00516 }
00517
00518 Octave_map (const std::string& k, const octave_value_list& val_list)
00519 : map (), key_list (), dimensions (1, val_list.length ())
00520 {
00521 map[k] = val_list;
00522 key_list.push_back (k);
00523 }
00524
00525 Octave_map (const Octave_map& m)
00526 : map (m.map), key_list (m.key_list), dimensions (m.dimensions) { }
00527
00528 Octave_map (const octave_map& m);
00529
00530 Octave_map& operator = (const Octave_map& m)
00531 {
00532 if (this != &m)
00533 {
00534 map = m.map;
00535 key_list = m.key_list;
00536 dimensions = m.dimensions;
00537 }
00538
00539 return *this;
00540 }
00541
00542 ~Octave_map (void) { }
00543
00544 Octave_map squeeze (void) const;
00545
00546 Octave_map permute (const Array<int>& vec, bool inv = false) const;
00547
00548
00549 octave_idx_type nfields (void) const { return map.size (); }
00550
00551 void del (const std::string& k)
00552 {
00553 iterator p = map.find (k);
00554
00555 if (p != map.end ())
00556 {
00557 map.erase (p);
00558
00559 key_list_iterator q
00560 = std::find (key_list.begin (), key_list.end (), k);
00561
00562 assert (q != key_list.end ());
00563
00564 key_list.erase (q);
00565 }
00566 }
00567
00568 iterator begin (void) { return iterator (map.begin ()); }
00569 const_iterator begin (void) const { return const_iterator (map.begin ()); }
00570
00571 iterator end (void) { return iterator (map.end ()); }
00572 const_iterator end (void) const { return const_iterator (map.end ()); }
00573
00574 std::string key (const_iterator p) const { return p->first; }
00575
00576 Cell& contents (const std::string& k);
00577 Cell contents (const std::string& k) const;
00578
00579 Cell& contents (iterator p)
00580 { return p->second; }
00581
00582 Cell contents (const_iterator p) const
00583 { return p->second; }
00584
00585 int intfield (const std::string& k, int def_val = 0) const;
00586
00587 std::string stringfield (const std::string& k,
00588 const std::string& def_val = std::string ()) const;
00589
00590 iterator seek (const std::string& k) { return map.find (k); }
00591 const_iterator seek (const std::string& k) const { return map.find (k); }
00592
00593 bool contains (const std::string& k) const
00594 { return (seek (k) != map.end ()); }
00595
00596 void clear (void)
00597 {
00598 map.clear ();
00599 key_list.clear ();
00600 }
00601
00602 string_vector keys (void) const;
00603
00604 octave_idx_type rows (void) const { return dimensions(0); }
00605
00606 octave_idx_type columns (void) const { return dimensions(1); }
00607
00608 dim_vector dims (void) const { return dimensions; }
00609
00610 int ndims (void) const { return dimensions.length (); }
00611
00612 Octave_map transpose (void) const;
00613
00614 Octave_map reshape (const dim_vector& new_dims) const;
00615
00616 void resize (const dim_vector& dv, bool fill = false);
00617
00618 octave_idx_type numel (void) const { return dimensions.numel (); }
00619
00620 Octave_map concat (const Octave_map& rb, const Array<octave_idx_type>& ra_idx);
00621
00622 Octave_map& maybe_delete_elements (const octave_value_list& idx);
00623
00624 Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
00625
00626 Octave_map& assign (const octave_value_list& idx, const std::string& k,
00627 const Cell& rhs);
00628
00629 Octave_map& assign (const std::string& k, const octave_value& rhs);
00630
00631 Octave_map& assign (const std::string& k, const Cell& rhs);
00632
00633 Octave_map index (const octave_value_list& idx,
00634 bool resize_ok = false) const;
00635
00636 private:
00637
00638
00639 std::map<std::string, Cell> map;
00640
00641
00642
00643 std::list<std::string> key_list;
00644
00645
00646 mutable dim_vector dimensions;
00647
00648 void maybe_add_to_key_list (const std::string& k)
00649 {
00650 if (! contains (k))
00651 key_list.push_back (k);
00652 }
00653 };
00654
00655 #endif