GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-map.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2018 John W. Eaton
4 Copyright (C) 2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if ! defined (octave_oct_map_h)
25 #define octave_oct_map_h 1
26 
27 #include "octave-config.h"
28 
29 #include <algorithm>
30 #include <map>
31 
32 #include "oct-refcount.h"
33 
34 #include "Cell.h"
35 #include "ovl.h"
36 
37 class string_vector;
38 
39 // A class holding a map field->index. Supports reference-counting.
40 class OCTINTERP_API
42 {
43  class fields_rep : public std::map<std::string, octave_idx_type>
44  {
45  public:
46  fields_rep (void) : std::map<std::string, octave_idx_type> (), count (1) { }
47  fields_rep (const fields_rep& other)
48  : std::map<std::string, octave_idx_type> (other), count (1) { }
49 
51 
52  private:
53  fields_rep& operator = (const fields_rep&); // no assignment!
54  };
55 
57 
58  static fields_rep *nil_rep (void);
59 
60 public:
61 
62  octave_fields (void) : rep (nil_rep ()) { rep->count++; }
64  octave_fields (const char * const *);
65 
67  {
68  if (--rep->count == 0)
69  delete rep;
70  }
71 
72  void make_unique (void)
73  {
74  if (rep->count > 1)
75  {
76  fields_rep *r = new fields_rep (*rep);
77 
78  if (--rep->count == 0)
79  delete rep;
80 
81  rep = r;
82  }
83  }
84 
85  octave_fields (const octave_fields& o) : rep (o.rep) { rep->count++; }
86 
88  operator = (const octave_fields& o)
89  {
90  o.rep->count++;
91  if (--rep->count == 0)
92  delete rep;
93  rep = o.rep;
94 
95  return *this;
96  }
97 
98  // constant iteration support. non-const iteration intentionally unsupported.
99 
100  typedef std::map<std::string, octave_idx_type>::const_iterator const_iterator;
102 
103  const_iterator begin (void) const { return rep->begin (); }
104  const_iterator end (void) const { return rep->end (); }
105 
106  std::string key (const_iterator p) const { return p->first; }
107  octave_idx_type index (const_iterator p) const { return p->second; }
108 
110  { return rep->find (k); }
111 
112  // high-level methods.
113 
114  // number of fields.
115  octave_idx_type nfields (void) const { return rep->size (); }
116 
117  // check whether a field exists.
118  bool isfield (const std::string& name) const;
119 
120  // get index of field. return -1 if not exist
121  octave_idx_type getfield (const std::string& name) const;
122  // get index of field. add if not exist
124  // remove field and return the index. -1 if didn't exist.
126 
127  // order the fields of this map.
128  // creates a permutation used to order the fields.
129  void orderfields (Array<octave_idx_type>& perm);
130 
131  // compares two instances for equality up to order of fields.
132  // returns a permutation needed to bring the fields of *other*
133  // into the order of *this*.
134  bool equal_up_to_order (const octave_fields& other,
135  octave_idx_type *perm) const;
136 
137  bool equal_up_to_order (const octave_fields& other,
138  Array<octave_idx_type>& perm) const;
139 
140  bool is_same (const octave_fields& other) const
141  { return rep == other.rep; }
142 
143  // Returns the fields as a vector of strings.
144  string_vector fieldnames (void) const;
145 
146  void clear (void)
147  {
148  *this = octave_fields ();
149  }
150 };
151 
152 class OCTINTERP_API
154 {
155 public:
156 
158  : xkeys (k), xvals (k.nfields ()) { }
159 
160  octave_scalar_map (void) : xkeys (), xvals () { }
161 
163  : xkeys (k), xvals (k.numel ()) { }
164 
166  : xkeys (m.xkeys), xvals (m.xvals) { }
167 
168  octave_scalar_map (const std::map<std::string, octave_value>& m);
169 
170  octave_scalar_map& operator = (const octave_scalar_map& m)
171  {
172  xkeys = m.xkeys;
173  xvals = m.xvals;
174 
175  return *this;
176  }
177 
178  // iteration support.
179  // note that both const and non-const iterators are the same.
180  // The const/non-const distinction is made by the key & contents method.
183 
184  const_iterator begin (void) const { return xkeys.begin (); }
185  const_iterator end (void) const { return xkeys.end (); }
186 
187  const_iterator seek (const std::string& k) const { return xkeys.seek (k); }
188 
190  { return xkeys.key (p); }
192  { return xkeys.index (p); }
193 
195  { return xvals[xkeys.index (p)]; }
196 
198  { return xvals[xkeys.index (p)]; }
199 
201  { return xvals[i]; }
202 
204  { return xvals[i]; }
205 
206  // number of fields.
207  octave_idx_type nfields (void) const { return xkeys.nfields (); }
208 
209  // check whether a field exists.
210  bool isfield (const std::string& name) const
211  { return xkeys.isfield (name); }
212 
213  bool contains (const std::string& name) const
214  { return isfield (name); }
215 
217  { return xkeys.fieldnames (); }
218 
219  string_vector keys (void) const
220  { return fieldnames (); }
221 
222  // get contents of a given field. empty value if not exist.
223  octave_value getfield (const std::string& key) const;
224 
225  // set contents of a given field. add if not exist.
226  void setfield (const std::string& key, const octave_value& val);
227  void assign (const std::string& k, const octave_value& val)
228  { setfield (k, val); }
229 
230  // remove a given field. do nothing if not exist.
231  void rmfield (const std::string& key);
232  void del (const std::string& k) { rmfield (k); }
233 
234  // return a copy with fields ordered, optionally along with permutation.
235  octave_scalar_map orderfields (void) const;
238  Array<octave_idx_type>& perm) const;
239 
240  // aka getfield/setfield, but the latter returns a reference.
241  octave_value contents (const std::string& k) const;
242  octave_value& contents (const std::string& k);
243 
244  void clear (void)
245  {
246  xkeys.clear ();
247  xvals.clear ();
248  }
249 
250  friend class octave_map;
251 
252 private:
253 
255  std::vector<octave_value> xvals;
256 
257 };
258 
259 template <>
260 inline octave_scalar_map
262 { return v.scalar_map_value (); }
263 
264 class OCTINTERP_API
266 {
267 public:
268 
270  : xkeys (k), xvals (k.nfields ()), dimensions () { }
271 
273  : xkeys (k), xvals (k.nfields (), Cell (dv)), dimensions (dv) { }
274 
276 
277  octave_map (void) : xkeys (), xvals (), dimensions () { }
278 
279  octave_map (const dim_vector& dv) : xkeys (), xvals (), dimensions (dv) { }
280 
282  : xkeys (k), xvals (k.numel (), Cell (1, 1)), dimensions (1, 1) { }
283 
285  : xkeys (k), xvals (k.numel (), Cell (dv)), dimensions (dv) { }
286 
288  : xkeys (m.xkeys), xvals (m.xvals), dimensions (m.dimensions) { }
289 
290  octave_map (const octave_scalar_map& m);
291 
292  octave_map& operator = (const octave_map& m)
293  {
294  xkeys = m.xkeys;
295  xvals = m.xvals;
296  dimensions = m.dimensions;
297 
298  return *this;
299  }
300 
301  // iteration support.
302  // note that both const and non-const iterators are the same.
303  // The const/non-const distinction is made by the key & contents method.
306 
307  const_iterator begin (void) const { return xkeys.begin (); }
308  const_iterator end (void) const { return xkeys.end (); }
309 
310  const_iterator seek (const std::string& k) const { return xkeys.seek (k); }
311 
313  { return xkeys.key (p); }
315  { return xkeys.index (p); }
316 
317  const Cell& contents (const_iterator p) const
318  { return xvals[xkeys.index (p)]; }
319 
321  { return xvals[xkeys.index (p)]; }
322 
324  { return xvals[i]; }
325 
327  { return xvals[i]; }
328 
329  // number of fields.
330  octave_idx_type nfields (void) const { return xkeys.nfields (); }
331 
332  // check whether a field exists.
333  bool isfield (const std::string& name) const
334  { return xkeys.isfield (name); }
335 
336  bool contains (const std::string& name) const
337  { return isfield (name); }
338 
340  { return xkeys.fieldnames (); }
341 
342  string_vector keys (void) const
343  { return fieldnames (); }
344 
345  // get contents of a given field. empty value if not exist.
346  Cell getfield (const std::string& key) const;
347 
348  // set contents of a given field. add if not exist. checks for
349  // correct dimensions.
350  void setfield (const std::string& key, const Cell& val);
351  void assign (const std::string& k, const Cell& val)
352  { setfield (k, val); }
353 
354  // remove a given field. do nothing if not exist.
355  void rmfield (const std::string& key);
356  void del (const std::string& k) { rmfield (k); }
357 
358  // return a copy with fields ordered, optionally along with permutation.
359  octave_map orderfields (void) const;
361  octave_map orderfields (const octave_map& other,
362  Array<octave_idx_type>& perm) const;
363 
364  // aka getfield/setfield, but the latter returns a reference.
365  Cell contents (const std::string& k) const;
366  Cell& contents (const std::string& k);
367 
368  void clear (void)
369  {
370  xkeys.clear ();
371  xvals.clear ();
372  }
373 
374  // The Array-like methods.
375  octave_idx_type numel (void) const { return dimensions.numel (); }
376  octave_idx_type length (void) const { return numel (); }
377  bool isempty (void) const { return dimensions.any_zero (); }
378 
379  octave_idx_type rows (void) const { return dimensions(0); }
380  octave_idx_type cols (void) const { return dimensions(1); }
381  octave_idx_type columns (void) const { return dimensions(1); }
382 
383  // Extract a scalar substructure.
384  // FIXME: actually check something.
386  { return elem (n); }
387 
388  // FIXME: actually check something.
390  { return elem (i, j); }
391 
392  // FIXME: actually check something.
394  { return elem (ra_idx); }
395 
397 
399 
401 
402  octave_scalar_map operator () (octave_idx_type n) const
403  { return elem (n); }
404 
406  { return elem (i, j); }
407 
409  operator () (const Array<octave_idx_type>& ra_idx) const
410  { return elem (ra_idx); }
411 
412  octave_map squeeze (void) const;
413 
414  octave_map permute (const Array<int>& vec, bool inv = false) const;
415 
416  dim_vector dims (void) const { return dimensions; }
417 
418  int ndims (void) const { return dimensions.ndims (); }
419 
420  octave_map transpose (void) const;
421 
422  octave_map reshape (const dim_vector& dv) const;
423 
424  void resize (const dim_vector& dv, bool fill = false);
425 
426  static octave_map
427  cat (int dim, octave_idx_type n, const octave_scalar_map *map_list);
428 
429  static octave_map
430  cat (int dim, octave_idx_type n, const octave_map *map_list);
431 
432  octave_map index (const idx_vector& i, bool resize_ok = false) const;
433 
434  octave_map index (const idx_vector& i, const idx_vector& j,
435  bool resize_ok = false) const;
436 
437  octave_map index (const Array<idx_vector>& ia,
438  bool resize_ok = false) const;
439 
440  octave_map index (const octave_value_list&, bool resize_ok = false) const;
441 
444 
445  void assign (const idx_vector& i, const octave_map& rhs);
446 
447  void assign (const idx_vector& i, const idx_vector& j, const octave_map& rhs);
448 
449  void assign (const Array<idx_vector>& ia, const octave_map& rhs);
450 
451  void assign (const octave_value_list&, const octave_map& rhs);
452 
453  void assign (const octave_value_list& idx, const std::string& k,
454  const Cell& rhs);
455 
456  void delete_elements (const idx_vector& i);
457 
458  void delete_elements (int dim, const idx_vector& i);
459 
460  void delete_elements (const Array<idx_vector>& ia);
461 
462  void delete_elements (const octave_value_list&);
463 
464  octave_map concat (const octave_map& rb,
466 
467  // like checkelem, but no check.
468  octave_scalar_map fast_elem_extract (octave_idx_type n) const;
469 
470  // element assignment, no bounds check
471  bool fast_elem_insert (octave_idx_type n, const octave_scalar_map& rhs);
472 
473 private:
474 
476  std::vector<Cell> xvals;
478 
479  void optimize_dimensions (void);
480  void extract_scalar (octave_scalar_map& dest,
481  octave_idx_type index) const;
482  static void do_cat (int dim, octave_idx_type n,
483  const octave_scalar_map *map_list, octave_map& retval);
484  static void do_cat (int dim, octave_idx_type n,
485  const octave_map *map_list, octave_map& retval);
486 };
487 
488 template <>
490 { return v.map_value (); }
491 
492 #endif
string_vector fieldnames(void) const
Definition: oct-map.h:216
octave_idx_type rows(void) const
Definition: oct-map.h:379
dim_vector dimensions
Definition: oct-map.h:477
octave_value & contents(iterator p)
Definition: oct-map.h:197
octave_value & contents(octave_idx_type i)
Definition: oct-map.h:203
octave_scalar_map element_type
Definition: oct-map.h:275
octave_map(const dim_vector &dv)
Definition: oct-map.h:279
OCTAVE_EXPORT octave_value_list column
Definition: sparse.cc:123
Definition: Cell.h:37
bool contains(const std::string &name) const
Definition: oct-map.h:336
Cell & contents(octave_idx_type i)
Definition: oct-map.h:326
const_iterator begin(void) const
Definition: oct-map.h:103
const octave_base_value const Array< octave_idx_type > & ra_idx
Cell & contents(iterator p)
Definition: oct-map.h:320
string_vector keys(void) const
Definition: oct-map.h:342
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:351
octave_map(const string_vector &k)
Definition: oct-map.h:281
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode fieldnames
string_vector fieldnames(void) const
Definition: oct-map.h:339
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
int ndims(void) const
Definition: oct-map.h:418
const octave_value & contents(octave_idx_type i) const
Definition: oct-map.h:200
const_iterator iterator
Definition: oct-map.h:305
octave_scalar_map checkelem(octave_idx_type n) const
Definition: oct-map.h:385
for large enough k
Definition: lu.cc:617
OCTAVE_EXPORT octave_value_list page
Definition: sub2ind.cc:107
std::string key(const_iterator p) const
Definition: oct-map.h:106
octave_scalar_map checkelem(octave_idx_type i, octave_idx_type j) const
Definition: oct-map.h:389
static void transpose(octave_idx_type N, const octave_idx_type *ridx, const octave_idx_type *cidx, octave_idx_type *ridx2, octave_idx_type *cidx2)
Definition: symrcm.cc:386
const Cell & contents(octave_idx_type i) const
Definition: oct-map.h:323
ComplexNDArray concat(NDArray &ra, ComplexNDArray &rb, const Array< octave_idx_type > &ra_idx)
Definition: CNDArray.cc:653
cat(2, A, B) esult
Definition: data.cc:2278
octave_idx_type nfields(void) const
Definition: oct-map.h:115
std::string key(const_iterator p) const
Definition: oct-map.h:312
STL namespace.
const_iterator seek(const std::string &k) const
Definition: oct-map.h:187
octave_map(const octave_fields &k)
Definition: oct-map.h:269
octave_map(const octave_map &m)
Definition: oct-map.h:287
octave_fields(void)
Definition: oct-map.h:62
bool isfield(const std::string &name) const
Definition: oct-map.h:210
const_iterator end(void) const
Definition: oct-map.h:308
octave_scalar_map(const octave_scalar_map &m)
Definition: oct-map.h:165
std::vector< Cell > xvals
Definition: oct-map.h:476
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode orderfields
octave_scalar_map octave_value_extract< octave_scalar_map >(const octave_value &v)
Definition: oct-map.h:261
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode rmfield
octave_fields xkeys
Definition: oct-map.h:254
void clear(void)
Definition: oct-map.h:146
string_vector keys(void) const
Definition: oct-map.h:219
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:314
bool isfield(const std::string &name) const
Definition: oct-map.h:333
bool contains(const std::string &name) const
Definition: oct-map.h:213
std::vector< octave_value > xvals
Definition: oct-map.h:255
nd deftypefn *std::string name
Definition: sysdep.cc:647
octave_map(const dim_vector &dv, const string_vector &k)
Definition: oct-map.h:284
void clear(void)
Definition: oct-map.h:368
octave_fields::const_iterator const_iterator
Definition: oct-map.h:181
octave_fields xkeys
Definition: oct-map.h:475
octave_idx_type columns(void) const
Definition: oct-map.h:381
const_iterator end(void) const
Definition: oct-map.h:185
octave_map(const dim_vector &dv, const octave_fields &k)
Definition: oct-map.h:272
static int elem
Definition: __contourc__.cc:47
const_iterator begin(void) const
Definition: oct-map.h:184
octave_value retval
Definition: data.cc:6246
const Cell & contents(const_iterator p) const
Definition: oct-map.h:317
fields_rep * rep
Definition: oct-map.h:56
std::string key(const_iterator p) const
Definition: oct-map.h:189
octave_idx_type numel(void) const
Definition: oct-map.h:375
octave_map(void)
Definition: oct-map.h:277
void make_unique(void)
Definition: oct-map.h:72
octave_scalar_map checkelem(const Array< octave_idx_type > &ra_idx) const
Definition: oct-map.h:393
octave_idx_type cols(void) const
Definition: oct-map.h:380
octave_idx_type nfields(void) const
Definition: oct-map.h:330
const_iterator seek(const std::string &k) const
Definition: oct-map.h:109
octave_fields(const octave_fields &o)
Definition: oct-map.h:85
octave_scalar_map(const octave_fields &k)
Definition: oct-map.h:157
T::size_type numel(const T &str)
Definition: oct-string.cc:61
const octave_value & contents(const_iterator p) const
Definition: oct-map.h:194
~octave_fields(void)
Definition: oct-map.h:66
bool is_same(const octave_fields &other) const
Definition: oct-map.h:140
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode isfield
void del(const std::string &k)
Definition: oct-map.h:232
octave_map octave_value_extract< octave_map >(const octave_value &v)
Definition: oct-map.h:489
const_iterator iterator
Definition: oct-map.h:101
std::map< std::string, octave_idx_type >::const_iterator const_iterator
Definition: oct-map.h:100
p
Definition: lu.cc:138
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:227
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:191
octave_map map(dims)
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode setfield
bool isempty(void) const
Definition: oct-map.h:377
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode getfield
fields_rep(const fields_rep &other)
Definition: oct-map.h:47
for i
Definition: data.cc:5264
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:107
dim_vector dims(void) const
Definition: oct-map.h:416
octave::refcount< int > count
Definition: oct-map.h:50
octave_fields::const_iterator const_iterator
Definition: oct-map.h:304
octave_idx_type length(void) const
Definition: oct-map.h:376
octave_idx_type nfields(void) const
Definition: oct-map.h:207
octave_scalar_map(const string_vector &k)
Definition: oct-map.h:162
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
const_iterator begin(void) const
Definition: oct-map.h:307
const_iterator iterator
Definition: oct-map.h:182
const_iterator seek(const std::string &k) const
Definition: oct-map.h:310
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
void del(const std::string &k)
Definition: oct-map.h:356
dim_vector dv
Definition: sub2ind.cc:263
octave_scalar_map(void)
Definition: oct-map.h:160
void clear(void)
Definition: oct-map.h:244
const_iterator end(void) const
Definition: oct-map.h:104