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