GNU Octave  9.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-2024 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 
49  fields_rep () : std::map<std::string, octave_idx_type> (), m_count (1) { }
50 
51  fields_rep (const fields_rep& other)
52  : std::map<std::string, octave_idx_type> (other), m_count (1) { }
53 
54  fields_rep& operator = (const fields_rep&) = delete;
55 
56  ~fields_rep () = default;
57 
58  octave::refcount<octave_idx_type> m_count;
59  };
60 
61  fields_rep *m_rep;
62 
63  static fields_rep * nil_rep ();
64 
65 public:
66 
67  octave_fields () : m_rep (nil_rep ()) { m_rep->m_count++; }
69  octave_fields (const char *const *);
70 
72  {
73  if (--m_rep->m_count == 0)
74  delete m_rep;
75  }
76 
77  void make_unique ()
78  {
79  if (m_rep->m_count > 1)
80  {
81  fields_rep *r = new fields_rep (*m_rep);
82 
83  if (--m_rep->m_count == 0)
84  delete m_rep;
85 
86  m_rep = r;
87  }
88  }
89 
90  octave_fields (const octave_fields& o) : m_rep (o.m_rep) { m_rep->m_count++; }
91 
93  operator = (const octave_fields& o)
94  {
95  if (&o != this)
96  {
97  o.m_rep->m_count++;
98  if (--m_rep->m_count == 0)
99  delete m_rep;
100  m_rep = o.m_rep;
101  }
102 
103  return *this;
104  }
105 
106  // constant iteration support. non-const iteration intentionally unsupported.
107 
108  typedef std::map<std::string, octave_idx_type>::const_iterator const_iterator;
110 
111  const_iterator begin () const { return m_rep->begin (); }
112  const_iterator end () const { return m_rep->end (); }
113 
114  const_iterator cbegin () const { return m_rep->cbegin (); }
115  const_iterator cend () const { return m_rep->cend (); }
116 
117  std::string key (const_iterator p) const { return p->first; }
118  octave_idx_type index (const_iterator p) const { return p->second; }
119 
120  const_iterator seek (const std::string& k) const
121  { return m_rep->find (k); }
122 
123  // high-level methods.
124 
125  // number of fields.
126  octave_idx_type nfields () const { return m_rep->size (); }
127 
128  // check whether a field exists.
129  bool isfield (const std::string& name) const;
130 
131  // get index of field. return -1 if not exist
132  octave_idx_type getfield (const std::string& name) const;
133  // get index of field. add if not exist
134  octave_idx_type getfield (const std::string& name);
135  // remove field and return the index. -1 if didn't exist.
136  octave_idx_type rmfield (const std::string& name);
137 
138  // order the fields of this map.
139  // creates a permutation used to order the fields.
140  void orderfields (Array<octave_idx_type>& perm);
141 
142  // compares two instances for equality up to order of fields.
143  // returns a permutation needed to bring the fields of *other*
144  // into the order of *this*.
145  bool equal_up_to_order (const octave_fields& other,
146  octave_idx_type *perm) const;
147 
148  bool equal_up_to_order (const octave_fields& other,
149  Array<octave_idx_type>& perm) const;
150 
151  bool is_same (const octave_fields& other) const
152  { return m_rep == other.m_rep; }
153 
154  // Returns the fields as a vector of strings.
155  string_vector fieldnames () const;
156 
157  void clear ()
158  {
159  *this = octave_fields ();
160  }
161 };
162 
163 class OCTINTERP_API
165 {
166 public:
167 
169  : m_keys (k), m_vals (k.nfields ()) { }
170 
172  : m_keys (k), m_vals (k.numel ()) { }
173 
174  octave_scalar_map (const std::map<std::string, octave_value>& m);
175 
176  OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (octave_scalar_map)
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 () const { return m_keys.begin (); }
185  const_iterator end () const { return m_keys.end (); }
186 
187  const_iterator cbegin () const { return m_keys.cbegin (); }
188  const_iterator cend () const { return m_keys.cend (); }
189 
190  const_iterator seek (const std::string& k) const { return m_keys.seek (k); }
191 
192  std::string key (const_iterator p) const
193  { return m_keys.key (p); }
195  { return m_keys.index (p); }
196 
198  { return m_vals[m_keys.index (p)]; }
199 
201  { return m_vals[m_keys.index (p)]; }
202 
204  { return m_vals[i]; }
205 
207  { return m_vals[i]; }
208 
209  // number of fields.
210  octave_idx_type nfields () const { return m_keys.nfields (); }
211 
212  // check whether a field exists.
213  bool isfield (const std::string& name) const
214  { return m_keys.isfield (name); }
215 
216  bool contains (const std::string& name) const
217  { return isfield (name); }
218 
220  { return m_keys.fieldnames (); }
221 
223  { return fieldnames (); }
224 
225  // get contents of a given field. empty value if not exist.
226  octave_value getfield (const std::string& key) const;
227 
228  // set contents of a given field. add if not exist.
229  void setfield (const std::string& key, const octave_value& val);
230  void assign (const std::string& k, const octave_value& val)
231  { setfield (k, val); }
232 
233  // remove a given field. do nothing if not exist.
234  void rmfield (const std::string& key);
235  void del (const std::string& k) { rmfield (k); }
236 
237  // return a copy with fields ordered, optionally along with permutation.
238  octave_scalar_map orderfields () const;
239  octave_scalar_map orderfields (Array<octave_idx_type>& perm) const;
240  octave_scalar_map orderfields (const octave_scalar_map& other,
241  Array<octave_idx_type>& perm) const;
242 
243  // aka getfield/setfield, but the latter returns a reference.
244  octave_value contents (const std::string& k) const;
245  octave_value& contents (const std::string& k);
246 
247  void clear ()
248  {
249  m_keys.clear ();
250  m_vals.clear ();
251  }
252 
253  friend class octave_map;
254 
255 private:
256 
257  octave_fields m_keys;
258  std::vector<octave_value> m_vals;
259 };
260 
261 template <>
264 { return v.scalar_map_value (); }
265 
266 class OCTINTERP_API
268 {
269 public:
270 
272  : m_keys (k), m_vals (k.nfields ()), m_dimensions () { }
273 
274  octave_map (const dim_vector& dv, const octave_fields& k)
275  : m_keys (k), m_vals (k.nfields (), Cell (dv)), m_dimensions (dv) { }
276 
278 
279  octave_map (const dim_vector& dv) : m_keys (), m_vals (), m_dimensions (dv) { }
280 
282  : m_keys (k), m_vals (k.numel (), Cell (1, 1)), m_dimensions (1, 1) { }
283 
284  octave_map (const dim_vector& dv, const string_vector& k)
285  : m_keys (k), m_vals (k.numel (), Cell (dv)), m_dimensions (dv) { }
286 
287  octave_map (const octave_scalar_map& m);
288 
289  OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (octave_map)
290 
291  // iteration support.
292  // note that both const and non-const iterators are the same.
293  // The const/non-const distinction is made by the key & contents method.
296 
297  const_iterator begin () const { return m_keys.begin (); }
298  const_iterator end () const { return m_keys.end (); }
299 
300  const_iterator cbegin () const { return m_keys.cbegin (); }
301  const_iterator cend () const { return m_keys.cend (); }
302 
303  const_iterator seek (const std::string& k) const { return m_keys.seek (k); }
304 
305  std::string key (const_iterator p) const
306  { return m_keys.key (p); }
308  { return m_keys.index (p); }
309 
310  const Cell& contents (const_iterator p) const
311  { return m_vals[m_keys.index (p)]; }
312 
314  { return m_vals[m_keys.index (p)]; }
315 
316  const Cell& contents (octave_idx_type i) const
317  { return m_vals[i]; }
318 
320  { return m_vals[i]; }
321 
322  // number of fields.
323  octave_idx_type nfields () const { return m_keys.nfields (); }
324 
325  // check whether a field exists.
326  bool isfield (const std::string& name) const
327  { return m_keys.isfield (name); }
328 
329  bool contains (const std::string& name) const
330  { return isfield (name); }
331 
333  { return m_keys.fieldnames (); }
334 
336  { return fieldnames (); }
337 
338  // get contents of a given field. empty value if not exist.
339  Cell getfield (const std::string& key) const;
340 
341  // set contents of a given field. add if not exist. checks for
342  // correct m_dimensions.
343  void setfield (const std::string& key, const Cell& val);
344  void assign (const std::string& k, const Cell& val)
345  { setfield (k, val); }
346 
347  // remove a given field. do nothing if not exist.
348  void rmfield (const std::string& key);
349  void del (const std::string& k) { rmfield (k); }
350 
351  // return a copy with fields ordered, optionally along with permutation.
352  octave_map orderfields () const;
353  octave_map orderfields (Array<octave_idx_type>& perm) const;
354  octave_map orderfields (const octave_map& other,
355  Array<octave_idx_type>& perm) const;
356 
357  // aka getfield/setfield, but the latter returns a reference.
358  Cell contents (const std::string& k) const;
359  Cell& contents (const std::string& k);
360 
361  void clear ()
362  {
363  m_keys.clear ();
364  m_vals.clear ();
365  }
366 
367  // The Array-like methods.
368  octave_idx_type numel () const { return m_dimensions.numel (); }
369  octave_idx_type length () const { return numel (); }
370  bool isempty () const { return m_dimensions.any_zero (); }
371 
372  octave_idx_type rows () const { return m_dimensions(0); }
373  octave_idx_type cols () const { return m_dimensions(1); }
374  octave_idx_type columns () const { return m_dimensions(1); }
375 
376  // Extract a scalar substructure.
377  // FIXME: actually check something.
379  { return elem (n); }
380 
381  // FIXME: actually check something.
383  { return elem (i, j); }
384 
385  // FIXME: actually check something.
387  { return elem (ra_idx); }
388 
389  octave_scalar_map elem (octave_idx_type n) const;
390 
392 
393  octave_scalar_map elem (const Array<octave_idx_type>& ra_idx) const;
394 
395  octave_scalar_map operator () (octave_idx_type n) const
396  { return elem (n); }
397 
399  { return elem (i, j); }
400 
402  operator () (const Array<octave_idx_type>& ra_idx) const
403  { return elem (ra_idx); }
404 
405  octave_map squeeze () const;
406 
407  octave_map permute (const Array<int>& vec, bool inv = false) const;
408 
409  dim_vector dims () const { return m_dimensions; }
410 
411  int ndims () const { return m_dimensions.ndims (); }
412 
413  octave_map transpose () const;
414 
415  octave_map reshape (const dim_vector& dv) const;
416 
417  void resize (const dim_vector& dv, bool fill = false);
418 
419  static octave_map
420  cat (int dim, octave_idx_type n, const octave_scalar_map *map_list);
421 
422  static octave_map
423  cat (int dim, octave_idx_type n, const octave_map *map_list);
424 
425  octave_map index (const octave::idx_vector& i, bool resize_ok = false) const;
426 
427  octave_map index (const octave::idx_vector& i, const octave::idx_vector& j,
428  bool resize_ok = false) const;
429 
430  octave_map index (const Array<octave::idx_vector>& ia,
431  bool resize_ok = false) const;
432 
433  octave_map index (const octave_value_list&, bool resize_ok = false) const;
434 
435  octave_map column (octave_idx_type k) const;
436  octave_map page (octave_idx_type k) const;
437 
438  void assign (const octave::idx_vector& i, const octave_map& rhs);
439 
440  void assign (const octave::idx_vector& i, const octave::idx_vector& j,
441  const octave_map& rhs);
442 
443  void assign (const Array<octave::idx_vector>& ia, const octave_map& rhs);
444 
445  void assign (const octave_value_list&, const octave_map& rhs);
446 
447  void assign (const octave_value_list& idx, const std::string& k,
448  const Cell& rhs);
449 
450  void delete_elements (const octave::idx_vector& i);
451 
452  void delete_elements (int dim, const octave::idx_vector& i);
453 
454  void delete_elements (const Array<octave::idx_vector>& ia);
455 
456  void delete_elements (const octave_value_list&);
457 
458  octave_map concat (const octave_map& rb,
460 
461  // like checkelem, but no check.
462  octave_scalar_map fast_elem_extract (octave_idx_type n) const;
463 
464  // element assignment, no bounds check
465  bool fast_elem_insert (octave_idx_type n, const octave_scalar_map& rhs);
466 
467 private:
468 
469  octave_fields m_keys;
470  std::vector<Cell> m_vals;
471  dim_vector m_dimensions;
472 
473  void optimize_dimensions ();
474  void extract_scalar (octave_scalar_map& dest,
475  octave_idx_type index) const;
476  static void do_cat (int dim, octave_idx_type n,
477  const octave_scalar_map *map_list, octave_map& retval);
478  static void do_cat (int dim, octave_idx_type n,
479  const octave_map *map_list, octave_map& retval);
480 };
481 
482 template <>
484 { return v.map_value (); }
485 
486 #endif
ComplexNDArray concat(NDArray &ra, ComplexNDArray &rb, const Array< octave_idx_type > &ra_idx)
Definition: CNDArray.cc:418
Definition: Cell.h:43
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
const_iterator end() const
Definition: oct-map.h:112
void make_unique()
Definition: oct-map.h:77
std::map< std::string, octave_idx_type >::const_iterator const_iterator
Definition: oct-map.h:108
const_iterator iterator
Definition: oct-map.h:109
std::string key(const_iterator p) const
Definition: oct-map.h:117
void clear()
Definition: oct-map.h:157
const_iterator cbegin() const
Definition: oct-map.h:114
const_iterator begin() const
Definition: oct-map.h:111
octave_idx_type nfields() const
Definition: oct-map.h:126
bool is_same(const octave_fields &other) const
Definition: oct-map.h:151
octave_fields(const octave_fields &o)
Definition: oct-map.h:90
~octave_fields()
Definition: oct-map.h:71
octave_fields()
Definition: oct-map.h:67
const_iterator seek(const std::string &k) const
Definition: oct-map.h:120
const_iterator cend() const
Definition: oct-map.h:115
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:118
const_iterator cbegin() const
Definition: oct-map.h:300
void del(const std::string &k)
Definition: oct-map.h:349
const Cell & contents(octave_idx_type i) const
Definition: oct-map.h:316
octave_idx_type nfields() const
Definition: oct-map.h:323
octave_idx_type cols() const
Definition: oct-map.h:373
octave_idx_type length() const
Definition: oct-map.h:369
const_iterator end() const
Definition: oct-map.h:298
octave_idx_type rows() const
Definition: oct-map.h:372
string_vector keys() const
Definition: oct-map.h:335
void clear()
Definition: oct-map.h:361
octave_scalar_map checkelem(const Array< octave_idx_type > &ra_idx) const
Definition: oct-map.h:386
octave_scalar_map checkelem(octave_idx_type n) const
Definition: oct-map.h:378
dim_vector dims() const
Definition: oct-map.h:409
string_vector fieldnames() const
Definition: oct-map.h:332
octave_fields::const_iterator const_iterator
Definition: oct-map.h:294
octave_idx_type columns() const
Definition: oct-map.h:374
bool isfield(const std::string &name) const
Definition: oct-map.h:326
octave_idx_type numel() const
Definition: oct-map.h:368
Cell & contents(iterator p)
Definition: oct-map.h:313
const_iterator seek(const std::string &k) const
Definition: oct-map.h:303
bool contains(const std::string &name) const
Definition: oct-map.h:329
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:344
octave_scalar_map element_type
Definition: oct-map.h:277
std::string key(const_iterator p) const
Definition: oct-map.h:305
const_iterator iterator
Definition: oct-map.h:295
Cell & contents(octave_idx_type i)
Definition: oct-map.h:319
octave_map(const dim_vector &dv, const string_vector &k)
Definition: oct-map.h:284
octave_map(const string_vector &k)
Definition: oct-map.h:281
const Cell & contents(const_iterator p) const
Definition: oct-map.h:310
octave_map(const dim_vector &dv, const octave_fields &k)
Definition: oct-map.h:274
const_iterator cend() const
Definition: oct-map.h:301
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:307
octave_scalar_map checkelem(octave_idx_type i, octave_idx_type j) const
Definition: oct-map.h:382
int ndims() const
Definition: oct-map.h:411
octave_map(const octave_fields &k)
Definition: oct-map.h:271
octave_map(const dim_vector &dv)
Definition: oct-map.h:279
bool isempty() const
Definition: oct-map.h:370
octave_fields::const_iterator const_iterator
Definition: oct-map.h:181
const_iterator cend() const
Definition: oct-map.h:188
string_vector keys() const
Definition: oct-map.h:222
const_iterator cbegin() const
Definition: oct-map.h:187
const_iterator end() const
Definition: oct-map.h:185
octave_scalar_map(const octave_fields &k)
Definition: oct-map.h:168
octave_value & contents(octave_idx_type i)
Definition: oct-map.h:206
const_iterator iterator
Definition: oct-map.h:182
bool contains(const std::string &name) const
Definition: oct-map.h:216
const octave_value & contents(const_iterator p) const
Definition: oct-map.h:197
const octave_value & contents(octave_idx_type i) const
Definition: oct-map.h:203
string_vector fieldnames() const
Definition: oct-map.h:219
bool isfield(const std::string &name) const
Definition: oct-map.h:213
octave_scalar_map(const string_vector &k)
Definition: oct-map.h:171
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:230
octave_value & contents(iterator p)
Definition: oct-map.h:200
octave_idx_type index(const_iterator p) const
Definition: oct-map.h:194
const_iterator seek(const std::string &k) const
Definition: oct-map.h:190
void del(const std::string &k)
Definition: oct-map.h:235
octave_idx_type nfields() const
Definition: oct-map.h:210
std::string key(const_iterator p) const
Definition: oct-map.h:192
octave_scalar_map scalar_map_value() const
octave_map map_value() const
octave::idx_vector idx_vector
Definition: idx-vector.h:1022
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_idx_type n
Definition: mx-inlines.cc:761
T * r
Definition: mx-inlines.cc:781
octave_scalar_map octave_value_extract< octave_scalar_map >(const octave_value &v)
Definition: oct-map.h:263
octave_map octave_value_extract< octave_map >(const octave_value &v)
Definition: oct-map.h:483
T::size_type numel(const T &str)
Definition: oct-string.cc:74
const octave_base_value const Array< octave_idx_type > & ra_idx