GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
symscope.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1993-2025 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_symscope_h)
27#define octave_symscope_h 1
28
29#include "octave-config.h"
30
31#include <deque>
32#include <list>
33#include <map>
34#include <memory>
35#include <set>
36#include <string>
37
38#include "glob-match.h"
39#include "lo-regexp.h"
40#include "oct-refcount.h"
41
44
45#include "ov.h"
46#include "ovl.h"
47#include "symrec.h"
48
50
51class OCTINTERP_API symbol_scope
52{
53private:
54
55 class symbol_scope_rep
56 : public std::enable_shared_from_this<symbol_scope_rep>
57 {
58 public:
59
60 typedef std::map<std::string, symbol_record>::const_iterator
61 table_const_iterator;
62 typedef std::map<std::string, symbol_record>::iterator
63 table_iterator;
64
65 typedef std::map<std::string, octave_value>::const_iterator
66 subfunctions_const_iterator;
67 typedef std::map<std::string, octave_value>::iterator
68 subfunctions_iterator;
69
70 symbol_scope_rep (const std::string& name = "", bool add_ans = true)
71 : m_name (name), m_symbols (), m_subfunctions (),
72 m_persistent_values (), m_code (nullptr), m_fcn_name (),
73 m_fcn_file_name (), m_dir_name (), m_parent (),
74 m_primary_parent (), m_children (), m_nesting_depth (0),
75 m_is_static (false), m_is_primary_fcn_scope (false)
76 {
77 // Most scopes have ans as the first symbol, initially undefined.
78 if (add_ans)
79 insert_local ("ans");
80 }
81
82 OCTAVE_DISABLE_COPY_MOVE (symbol_scope_rep)
83
84 ~symbol_scope_rep () = default;
85
86 std::size_t num_symbols () const { return m_symbols.size (); }
87
88 // Simply inserts symbol. No non-local searching.
89
90 symbol_record insert_local (const std::string& name);
91
92 void insert_symbol_record (symbol_record& sr);
93
94 bool is_nested () const { return m_nesting_depth > 0; }
95
96 std::size_t nesting_depth () const { return m_nesting_depth; }
97
98 void set_nesting_depth (std::size_t depth) { m_nesting_depth = depth; }
99
100 bool is_parent () const { return ! m_children.empty (); }
101
102 bool is_static () const { return m_is_static; }
103
104 void mark_static () { m_is_static = true; }
105
106 std::shared_ptr<symbol_scope_rep> parent_scope_rep () const
107 {
108 return m_parent.lock ();
109 }
110
111 std::shared_ptr<symbol_scope_rep> primary_parent_scope_rep () const
112 {
113 return m_primary_parent.lock ();
114 }
115
116 std::shared_ptr<symbol_scope_rep> dup () const
117 {
118 std::shared_ptr<symbol_scope_rep> new_sid
119 = std::shared_ptr<symbol_scope_rep> (new symbol_scope_rep (m_name));
120
121 for (const auto& nm_sr : m_symbols)
122 new_sid->m_symbols[nm_sr.first] = nm_sr.second.dup ();
123
124 new_sid->m_subfunctions = m_subfunctions;
125 new_sid->m_persistent_values = m_persistent_values;
126 new_sid->m_subfunction_names = m_subfunction_names;
127 new_sid->m_code = m_code;
128 new_sid->m_fcn_name = m_fcn_name;
129 new_sid->m_fcn_file_name = m_fcn_file_name;
130 new_sid->m_dir_name = m_dir_name;
131 new_sid->m_parent = m_parent;
132 new_sid->m_primary_parent = m_primary_parent;
133 new_sid->m_children = m_children;
134 new_sid->m_nesting_depth = m_nesting_depth;
135 new_sid->m_is_static = m_is_static;
136 new_sid->m_is_primary_fcn_scope = m_is_primary_fcn_scope;
137
138 return new_sid;
139 }
140
141 octave_value& persistent_varref (std::size_t data_offset)
142 {
143 return m_persistent_values[data_offset];
144 }
145
146 octave_value persistent_varval (std::size_t data_offset) const
147 {
148 auto p = m_persistent_values.find (data_offset);
149
150 return p == m_persistent_values.end () ? octave_value () : p->second;
151 }
152
153 symbol_record find_symbol (const std::string& name)
154 {
155 auto p = m_symbols.find (name);
156
157 if (p == m_symbols.end ())
158 return insert (name);
159 else
160 return p->second;
161 }
162
163 symbol_record lookup_symbol (const std::string& name) const
164 {
165 auto p = m_symbols.find (name);
166
167 return p == m_symbols.end () ? symbol_record () : p->second;
168 }
169
170 symbol_record insert (const std::string& name);
171
172 void rename (const std::string& old_name, const std::string& new_name)
173 {
174 auto p = m_symbols.find (old_name);
175
176 if (p != m_symbols.end ())
177 {
178 symbol_record sr = p->second;
179
180 sr.rename (new_name);
181
182 m_symbols.erase (p);
183
184 m_symbols[new_name] = sr;
185 }
186 }
187
188 void install_subfunction (const std::string& name,
189 const octave_value& fval)
190 {
191 m_subfunctions[name] = fval;
192 }
193
194 void install_nestfunction (const std::string& name,
195 const octave_value& fval,
196 const symbol_scope& fcn_scope)
197 {
198 m_subfunctions[name] = fval;
199
200 m_children.push_back (fcn_scope);
201 }
202
203 octave_value find_subfunction (const std::string& name) const;
204
205 void lock_subfunctions ()
206 {
207 for (auto& nm_sf : m_subfunctions)
208 nm_sf.second.lock ();
209 }
210
211 void unlock_subfunctions ()
212 {
213 for (auto& nm_sf : m_subfunctions)
214 nm_sf.second.unlock ();
215 }
216
217 // Pairs of name, function objects.
218 std::map<std::string, octave_value> subfunctions () const
219 {
220 return m_subfunctions;
221 }
222
223 void erase_subfunctions ()
224 {
225 m_subfunctions.clear ();
226 }
227
228 void mark_subfunctions_in_scope_as_private (const std::string& class_name);
229
230 bool has_subfunctions () const
231 {
232 return ! m_subfunction_names.empty ();
233 }
234
235 void stash_subfunction_names (const std::list<std::string>& names)
236 {
237 m_subfunction_names = names;
238 }
239
240 std::list<std::string> subfunction_names () const
241 {
242 return m_subfunction_names;
243 }
244
245 std::list<octave_value> localfunctions () const;
246
247 octave_value dump () const;
248
249 std::string name () const { return m_name; }
250
251 void cache_name (const std::string& name) { m_name = name; }
252
253 std::string fcn_name () const { return m_fcn_name; }
254
255 void cache_fcn_name (const std::string& name) { m_fcn_name = name; }
256
257 std::list<std::string> parent_fcn_names () const;
258
259 octave_user_code * user_code () const { return m_code; }
260
261 void set_user_code (octave_user_code *code) { m_code = code; }
262
263 void set_parent (const std::shared_ptr<symbol_scope_rep>& parent);
264
265 void set_primary_parent (const std::shared_ptr<symbol_scope_rep>& parent);
266
267 void cache_fcn_file_name (const std::string& name)
268 {
269 m_fcn_file_name = name;
270 }
271
272 std::string fcn_file_name () const { return m_fcn_file_name; }
273
274 void cache_dir_name (const std::string& name);
275
276 std::string dir_name () const { return m_dir_name; }
277
278 void mark_primary_fcn_scope () { m_is_primary_fcn_scope = true; }
279
280 bool is_primary_fcn_scope () const { return m_is_primary_fcn_scope; }
281
282 bool is_relative (const std::shared_ptr<symbol_scope_rep>& scope) const;
283
284 void mark_as_variable (const std::string& nm);
285 void mark_as_variables (const std::list<std::string>& lst);
286
287 bool is_variable (const std::string& nm) const;
288
289 void update_nest ();
290
291 bool look_nonlocal (const std::string& name, std::size_t offset,
292 symbol_record& result);
293
294 octave_value dump_symbols_map () const;
295
296 const std::map<std::string, symbol_record>& symbols () const
297 {
298 return m_symbols;
299 }
300
301 std::map<std::string, symbol_record>& symbols ()
302 {
303 return m_symbols;
304 }
305
306 std::list<symbol_record> symbol_list () const;
307
308 private:
309
310 //! Name for this scope (usually the corresponding filename of the
311 //! function corresponding to the scope).
312
313 std::string m_name;
314
315 //! Map from symbol names to symbol info.
316
317 std::map<std::string, symbol_record> m_symbols;
318
319 //! Map from symbol names to subfunctions.
320
321 std::map<std::string, octave_value> m_subfunctions;
322
323 //! Map from data offset to persistent values in this scope.
324 std::map<std::size_t, octave_value> m_persistent_values;
325
326 //! The list of subfunctions (if any) in the order they appear in
327 //! the function file.
328
329 std::list<std::string> m_subfunction_names;
330
331 //! The associated user code (may be null).
332
333 octave_user_code *m_code;
334
335 //! Simple name of the function corresponding to this scope.
336
337 std::string m_fcn_name;
338
339 //! The file name associated with m_code.
340
341 std::string m_fcn_file_name;
342
343 //! The directory associated with m_code.
344
345 std::string m_dir_name;
346
347 //! Parent of nested function (may be null).
348
349 std::weak_ptr<symbol_scope_rep> m_parent;
350
351 //! Primary (top) parent of nested function (may be null). Used
352 //! to determine whether two nested functions are related.
353
354 std::weak_ptr<symbol_scope_rep> m_primary_parent;
355
356 //! Child nested functions.
357
358 std::vector<symbol_scope> m_children;
359
360 //! If true, then this scope belongs to a nested function.
361
362 std::size_t m_nesting_depth;
363
364 //! If true then no variables can be added.
365
366 bool m_is_static;
367
368 //! If true, this is the scope of a primary function.
369 bool m_is_primary_fcn_scope;
370 };
371
372public:
373
374 symbol_scope () = delete;
375
376 // Create a valid but possibly anonymous scope. If NAME is empty, the
377 // scope is anonymous, but it is better to state that intent clearly
378 // by using the symbol_scope::anonymous function instead.
379 symbol_scope (const std::string& name)
380 : m_rep (new symbol_scope_rep (name))
381 { }
382
383 // FIXME: is there a way to make the following constructor private and
384 // not expose the symbol_scope_rep object in the interface (see the
385 // parent_scope, primary_parent_scope, and get_rep functions)?
386
387 // If NEW_REP is nullptr, the scope is invalid. But if you wish to
388 // create an invalid scope, it is probably better to state that intent
389 // clearly by using the symbol_scope::invalid function instead.
390 symbol_scope (const std::shared_ptr<symbol_scope_rep> new_rep)
391 : m_rep (new_rep)
392 { }
393
394 symbol_scope (const symbol_scope&) = default;
395
396 symbol_scope& operator = (const symbol_scope&) = default;
397
398 ~symbol_scope () = default;
399
401 {
402 return symbol_scope (std::shared_ptr<symbol_scope_rep> (nullptr));
403 }
404
406 {
407 return symbol_scope ("");
408 }
409
410 bool is_valid () const { return bool (m_rep); }
411
412 explicit operator bool () const { return is_valid (); }
413
414 std::size_t num_symbols () const
415 {
416 return m_rep ? m_rep->num_symbols () : 0;
417 }
418
419 symbol_record insert_local (const std::string& name)
420 {
421 return m_rep ? m_rep->insert_local (name) : symbol_record ();
422 }
423
425 {
426 if (m_rep)
427 m_rep->insert_symbol_record (sr);
428 }
429
430 bool is_nested () const
431 {
432 return m_rep ? m_rep->is_nested () : false;
433 }
434
435 bool is_parent () const
436 {
437 return m_rep ? m_rep->is_parent () : false;
438 }
439
440 void set_nesting_depth (std::size_t depth)
441 {
442 if (m_rep)
443 m_rep->set_nesting_depth (depth);
444 }
445
446 std::size_t nesting_depth () const
447 {
448 return m_rep ? m_rep->nesting_depth () : 0;
449 }
450
451 bool is_static () const
452 {
453 return m_rep ? m_rep->is_static () : false;
454 }
455
457 {
458 if (m_rep)
459 m_rep->mark_static ();
460 }
461
462 std::shared_ptr<symbol_scope_rep> parent_scope () const
463 {
464 return m_rep ? m_rep->parent_scope_rep () : nullptr;
465 }
466
467 std::shared_ptr<symbol_scope_rep> primary_parent_scope () const
468 {
469 return m_rep ? m_rep->primary_parent_scope_rep () : nullptr;
470 }
471
473 {
474 return symbol_scope (m_rep ? m_rep->dup () : nullptr);
475 }
476
477 octave_value& persistent_varref (std::size_t data_offset)
478 {
479 static octave_value dummy_value;
480
481 return m_rep ? m_rep->persistent_varref (data_offset) : dummy_value;
482 }
483
484 octave_value persistent_varval (std::size_t data_offset) const
485 {
486 return m_rep ? m_rep->persistent_varval (data_offset) : octave_value ();
487 }
488
489 symbol_record find_symbol (const std::string& name)
490 {
491 return m_rep ? m_rep->find_symbol (name) : symbol_record ();
492 }
493
494 // Like find_symbol, but does not insert.
495 symbol_record lookup_symbol (const std::string& name) const
496 {
497 return m_rep ? m_rep->lookup_symbol (name) : symbol_record ();
498 }
499
500 symbol_record insert (const std::string& name)
501 {
502 return m_rep ? m_rep->insert (name) : symbol_record ();
503 }
504
505 void rename (const std::string& old_name, const std::string& new_name)
506 {
507 if (m_rep)
508 m_rep->rename (old_name, new_name);
509 }
510
511 void install_subfunction (const std::string& name,
512 const octave_value& fval)
513 {
514 if (m_rep)
515 m_rep->install_subfunction (name, fval);
516 }
517
518 void install_nestfunction (const std::string& name,
519 const octave_value& fval,
520 const symbol_scope& fcn_scope)
521 {
522 if (m_rep)
523 m_rep->install_nestfunction (name, fval, fcn_scope);
524 }
525
526 octave_value find_subfunction (const std::string& name) const
527 {
528 return m_rep ? m_rep->find_subfunction (name) : octave_value ();
529 }
530
532 {
533 if (m_rep)
534 m_rep->lock_subfunctions ();
535 }
536
538 {
539 if (m_rep)
540 m_rep->unlock_subfunctions ();
541 }
542
543 std::map<std::string, octave_value> subfunctions () const
544 {
545 return (m_rep
546 ? m_rep->subfunctions ()
547 : std::map<std::string, octave_value> ());
548 }
549
551 {
552 if (m_rep)
553 m_rep->erase_subfunctions ();
554 }
555
556 void mark_subfunctions_in_scope_as_private (const std::string& class_name)
557 {
558 if (m_rep)
559 m_rep->mark_subfunctions_in_scope_as_private (class_name);
560 }
561
562 bool has_subfunctions () const
563 {
564 return m_rep ? m_rep->has_subfunctions () : false;
565 }
566
567 void stash_subfunction_names (const std::list<std::string>& names)
568 {
569 if (m_rep)
570 m_rep->stash_subfunction_names (names);
571 }
572
573 std::list<std::string> subfunction_names () const
574 {
575 return m_rep ? m_rep->subfunction_names () : std::list<std::string> ();
576 }
577
578 // List of function handle objects.
579 std::list<octave_value> localfunctions () const;
580
582 {
583 return m_rep ? m_rep->dump () : octave_value ();
584 }
585
586 std::string name () const
587 {
588 return m_rep ? m_rep->name () : "";
589 }
590
591 void cache_name (const std::string& name)
592 {
593 if (m_rep)
594 m_rep->cache_name (name);
595 }
596
597 std::string fcn_name () const
598 {
599 return m_rep ? m_rep->fcn_name () : "";
600 }
601
602 void cache_fcn_name (const std::string& name)
603 {
604 if (m_rep)
605 m_rep->cache_fcn_name (name);
606 }
607
608 std::list<std::string> parent_fcn_names () const
609 {
610 return m_rep ? m_rep->parent_fcn_names () : std::list<std::string> ();
611 }
612
614 {
615 return m_rep ? m_rep->user_code () : nullptr;
616 }
617
619 {
620 if (m_rep)
621 m_rep->set_user_code (code);
622 }
623
624 void set_parent (const symbol_scope& p)
625 {
626 if (m_rep)
627 m_rep->set_parent (p.get_rep ());
628 }
629
631 {
632 if (m_rep)
633 m_rep->set_primary_parent (p.get_rep ());
634 }
635
636 void cache_fcn_file_name (const std::string& name)
637 {
638 if (m_rep)
639 m_rep->cache_fcn_file_name (name);
640 }
641
642 void cache_dir_name (const std::string& name)
643 {
644 if (m_rep)
645 m_rep->cache_dir_name (name);
646 }
647
648 std::string fcn_file_name () const
649 {
650 return m_rep ? m_rep->fcn_file_name () : "";
651 }
652
653 std::string dir_name () const
654 {
655 return m_rep ? m_rep->dir_name () : "";
656 }
657
659 {
660 if (m_rep)
661 m_rep->mark_primary_fcn_scope ();
662 }
663
665 {
666 return m_rep ? m_rep->is_primary_fcn_scope () : false;
667 }
668
669 bool is_relative (const symbol_scope& scope) const
670 {
671 return m_rep ? m_rep->is_relative (scope.get_rep ()) : false;
672 }
673
674 void mark_as_variable (const std::string& nm)
675 {
676 if (m_rep)
677 m_rep->mark_as_variable (nm);
678 }
679
680 void mark_as_variables (const std::list<std::string>& lst)
681 {
682 if (m_rep)
683 m_rep->mark_as_variables (lst);
684 }
685
686 bool is_variable (const std::string& nm) const
687 {
688 return m_rep ? m_rep->is_variable (nm) : false;
689 }
690
692 {
693 if (m_rep)
694 m_rep->update_nest ();
695 }
696
697 bool look_nonlocal (const std::string& name, std::size_t offset,
698 symbol_record& result)
699 {
700 return m_rep ? m_rep->look_nonlocal (name, offset, result) : false;
701 }
702
703 std::shared_ptr<symbol_scope_rep> get_rep () const
704 {
705 return m_rep;
706 }
707
708 friend bool operator == (const symbol_scope& a, const symbol_scope& b)
709 {
710 return a.m_rep == b.m_rep;
711 }
712
713 friend bool operator != (const symbol_scope& a, const symbol_scope& b)
714 {
715 return a.m_rep != b.m_rep;
716 }
717
718 const std::map<std::string, symbol_record>& symbols () const
719 {
720 static const std::map<std::string, symbol_record> empty_map;
721
722 return m_rep ? m_rep->symbols () : empty_map;
723 }
724
725 std::map<std::string, symbol_record>& symbols ()
726 {
727 static std::map<std::string, symbol_record> empty_map;
728
729 return m_rep ? m_rep->symbols () : empty_map;
730 }
731
732 std::list<symbol_record> symbol_list () const
733 {
734 static const std::list<symbol_record> empty_list;
735
736 return m_rep ? m_rep->symbol_list () : empty_list;
737 }
738
739private:
740
741 std::shared_ptr<symbol_scope_rep> m_rep;
742};
743
744OCTAVE_END_NAMESPACE(octave)
745
746#endif
octave_value dump() const
Definition ov.h:1454
void rename(const std::string &new_name)
Definition symrec.h:220
bool is_primary_fcn_scope() const
Definition symscope.h:664
symbol_record insert_local(const std::string &name)
Definition symscope.h:419
std::string name() const
Definition symscope.h:586
const std::map< std::string, symbol_record > & symbols() const
Definition symscope.h:718
void lock_subfunctions()
Definition symscope.h:531
bool is_parent() const
Definition symscope.h:435
bool is_valid() const
Definition symscope.h:410
std::string fcn_file_name() const
Definition symscope.h:648
std::list< std::string > subfunction_names() const
Definition symscope.h:573
void set_user_code(octave_user_code *code)
Definition symscope.h:618
bool is_static() const
Definition symscope.h:451
std::list< symbol_record > symbol_list() const
Definition symscope.h:732
void insert_symbol_record(symbol_record &sr)
Definition symscope.h:424
void stash_subfunction_names(const std::list< std::string > &names)
Definition symscope.h:567
symbol_scope(const std::shared_ptr< symbol_scope_rep > new_rep)
Definition symscope.h:390
void cache_fcn_name(const std::string &name)
Definition symscope.h:602
void mark_as_variable(const std::string &nm)
Definition symscope.h:674
bool is_nested() const
Definition symscope.h:430
symbol_scope(const std::string &name)
Definition symscope.h:379
octave_value find_subfunction(const std::string &name) const
Definition symscope.h:526
bool is_variable(const std::string &nm) const
Definition symscope.h:686
static symbol_scope anonymous()
Definition symscope.h:405
symbol_record find_symbol(const std::string &name)
Definition symscope.h:489
std::size_t num_symbols() const
Definition symscope.h:414
void update_nest()
Definition symscope.h:691
void mark_primary_fcn_scope()
Definition symscope.h:658
symbol_scope()=delete
static symbol_scope invalid()
Definition symscope.h:400
std::string dir_name() const
Definition symscope.h:653
symbol_scope(const symbol_scope &)=default
void set_parent(const symbol_scope &p)
Definition symscope.h:624
void mark_as_variables(const std::list< std::string > &lst)
Definition symscope.h:680
void install_subfunction(const std::string &name, const octave_value &fval)
Definition symscope.h:511
bool has_subfunctions() const
Definition symscope.h:562
octave_value dump() const
Definition symscope.h:581
std::shared_ptr< symbol_scope_rep > get_rep() const
Definition symscope.h:703
octave_value persistent_varval(std::size_t data_offset) const
Definition symscope.h:484
void mark_static()
Definition symscope.h:456
symbol_record insert(const std::string &name)
Definition symscope.h:500
std::map< std::string, symbol_record > & symbols()
Definition symscope.h:725
void cache_fcn_file_name(const std::string &name)
Definition symscope.h:636
void unlock_subfunctions()
Definition symscope.h:537
std::shared_ptr< symbol_scope_rep > primary_parent_scope() const
Definition symscope.h:467
octave_value & persistent_varref(std::size_t data_offset)
Definition symscope.h:477
void erase_subfunctions()
Definition symscope.h:550
void set_nesting_depth(std::size_t depth)
Definition symscope.h:440
void rename(const std::string &old_name, const std::string &new_name)
Definition symscope.h:505
void set_primary_parent(const symbol_scope &p)
Definition symscope.h:630
bool is_relative(const symbol_scope &scope) const
Definition symscope.h:669
symbol_record lookup_symbol(const std::string &name) const
Definition symscope.h:495
void mark_subfunctions_in_scope_as_private(const std::string &class_name)
Definition symscope.h:556
symbol_scope dup() const
Definition symscope.h:472
void cache_name(const std::string &name)
Definition symscope.h:591
std::shared_ptr< symbol_scope_rep > parent_scope() const
Definition symscope.h:462
void install_nestfunction(const std::string &name, const octave_value &fval, const symbol_scope &fcn_scope)
Definition symscope.h:518
std::map< std::string, octave_value > subfunctions() const
Definition symscope.h:543
~symbol_scope()=default
void cache_dir_name(const std::string &name)
Definition symscope.h:642
std::string fcn_name() const
Definition symscope.h:597
bool look_nonlocal(const std::string &name, std::size_t offset, symbol_record &result)
Definition symscope.h:697
std::list< std::string > parent_fcn_names() const
Definition symscope.h:608
octave_user_code * user_code() const
Definition symscope.h:613
std::size_t nesting_depth() const
Definition symscope.h:446
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
bool operator!=(const dim_vector &a, const dim_vector &b)
Definition dim-vector.h:532
bool operator==(const dim_vector &a, const dim_vector &b)
Definition dim-vector.h:516
int rename(const std::string &from, const std::string &to)
Definition file-ops.cc:582