GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-fcn-handle.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2003-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_ov_fcn_handle_h)
27 #define octave_ov_fcn_handle_h 1
28 
29 #include "octave-config.h"
30 
31 #include <iosfwd>
32 #include <list>
33 #include <memory>
34 #include <string>
35 
36 #include "oct-map.h"
37 #include "ov-base.h"
38 #include "ov-fcn.h"
39 #include "ov-typeinfo.h"
40 #include "stack-frame.h"
41 #include "symscope.h"
42 
44 
45 class interpreter;
46 class tree_evaluator;
47 
48 // Function handles.
49 
51 {
52 public:
53 
54  base_fcn_handle (const std::string& name = "",
55  const std::string& file = "")
56  : m_name (name), m_file (file)
57  { }
58 
59  base_fcn_handle (const base_fcn_handle&) = default;
60 
61  virtual ~base_fcn_handle () = default;
62 
63  virtual base_fcn_handle * clone () const = 0;
64 
65  virtual std::string type () const = 0;
66 
67  virtual bool is_internal () const { return false; }
68 
69  virtual bool is_simple () const { return false; }
70 
71  virtual bool is_scoped () const { return false; }
72 
73  virtual bool is_nested () const { return false; }
74 
75  virtual bool is_nested (const std::shared_ptr<stack_frame>&) const
76  {
77  return false;
78  }
79 
80  virtual bool is_weak_nested () const { return false; }
81 
82  virtual bool is_class_simple () const { return false; }
83 
84  virtual bool is_anonymous () const { return false; }
85 
86  virtual bool is_weak_anonymous () const { return false; }
87 
88  virtual octave_value make_weak_nested_handle () const;
89 
91 
92  std::string fcn_name () const { return m_name; }
93 
94  std::string file () const { return m_file; }
95 
97  subsref (const std::string& type, const std::list<octave_value_list>& idx,
98  int nargout);
99 
100  virtual octave_value_list
101  call (int nargout, const octave_value_list& args) = 0;
102 
103  // FIXME: These must go away. They don't do the right thing for
104  // scoping or overloads.
105  virtual octave_function * function_value (bool = false)
106  {
107  return nullptr;
108  }
109 
110  virtual octave_user_function * user_function_value (bool = false)
111  {
112  return nullptr;
113  }
114 
115  virtual octave_value fcn_val () { return octave_value (); }
116 
117  virtual octave_value workspace () const { return octave_value (); }
118 
119  // Should be const.
120  virtual octave_scalar_map info () { return octave_scalar_map (); }
121 
122  virtual void set_dispatch_class (const std::string& /*class_name*/) { }
123 
124  virtual std::string get_dispatch_class () const { return ""; }
125 
126  octave_value convert_to_str_internal (bool pad, bool force, char type) const;
127 
128  virtual bool save_ascii (std::ostream& os);
129 
130  virtual bool load_ascii (std::istream& is);
131 
132  virtual bool save_binary (std::ostream& os, bool save_as_floats);
133 
134  virtual bool load_binary (std::istream& is, bool swap,
136 
137  virtual bool save_hdf5 (octave_hdf5_id loc_id, const char *name,
138  bool save_as_floats);
139 
140  virtual bool load_hdf5 (octave_hdf5_id& group_hid,
141  octave_hdf5_id& space_hid,
142  octave_hdf5_id& type_hid);
143 
144  virtual void print_raw (std::ostream&, bool /*pr_as_read_syntax*/,
145  int /*current_print_indent_level*/) const
146  { }
147 
148  // Function handles are printed without a newline by default.
149  virtual bool print_as_scalar () const { return true; }
150 
151  virtual bool
152  set_fcn (const std::string& /*octaveroot*/, const std::string& /*fpath*/)
153  {
154  return false;
155  }
156 
157  virtual octave_function *
158  get_cached_fcn (void *, void *) { return nullptr; }
159 
160  virtual octave_function *
161  get_cached_fcn (const octave_value_list&) { return nullptr; }
162 
163  virtual bool
164  has_function_cache () const { return false; }
165 
166  virtual void compile () { }
167 
168 protected:
169 
170  void warn_load (const char *file_type) const;
171  void warn_save (const char *file_type) const;
172 
173  void unimplemented (const char *op, const char *fmt) const;
174 
175  // The name of the handle, not including the "@", or the text of the
176  // anonymous function.
177  std::string m_name;
178 
179  // The name of the file where the named function was defined.
180  std::string m_file;
181 };
182 
183 OCTAVE_END_NAMESPACE(octave)
184 
185 class
186 OCTINTERP_API
188 {
189 public:
190 
191  static const std::string anonymous;
192 
193  // Creates an invalid function handle. Used to create generic
194  // function handle objects when loading function handles. Further
195  // dispatch happens in the octave_fcn_handle load/save functions.
197 
198  // Create a handle to a built-in or internal function.
199  octave_fcn_handle (const octave_value& fcn);
200 
201  // Create a simple function handle that is not bound to a function.
202  // Lookup happens when a function call is attempted.
203  octave_fcn_handle (const std::string& name);
204 
205  // Create a simple function handle that is bound to a function.
206  octave_fcn_handle (const octave_value& fcn, const std::string& name);
207 
208  // Create a function handle that might be bound to a class method.
209  octave_fcn_handle (const std::string& class_nm, const std::string& meth_nm);
210 
211  // Create a function handle bound to a class method.
212  octave_fcn_handle (const octave_value& fcn, const std::string& class_nm,
213  const std::string& meth_nm);
214 
215  // Create a function handle bound to a class method.
216  octave_fcn_handle (const octave_value& obj, const octave_value& fcn,
217  const std::string& class_nm,
218  const std::string& meth_nm);
219 
220  // Create a function handle bound to a scoped function.
221  octave_fcn_handle (const octave_value& fcn, const std::string& name,
222  const std::list<std::string>& parentage);
223 
224  // Create a handle to a nested function.
225  octave_fcn_handle (const octave_value& fcn, const std::string& name,
226  const std::shared_ptr<octave::stack_frame>& closure_frames);
227 
228  // Create an anonymous function handle with local variable values
229  // provided in LOCAL_VARS.
230  octave_fcn_handle (const octave_value& fcn,
231  const octave::stack_frame::local_vars_map& local_vars,
232  const std::shared_ptr<octave::stack_frame>& closure_frames
233  = std::shared_ptr<octave::stack_frame> ());
234 
235  // Create a simple function handle that is not bound to a function.
236  // Lookup happens when a function call is attempted and the function
237  // lookup is cached in a octave_fcn_cache.
238  octave_fcn_handle (const std::string& name, octave_value cache);
239 
240  octave_fcn_handle (octave::base_fcn_handle *rep);
241 
243 
244  ~octave_fcn_handle () = default;
245 
247  {
248  return new octave_fcn_handle (*this);
249  }
250 
252  {
253  return new octave_fcn_handle ();
254  }
255 
256  // We don't need to override all three forms of subsref. The using
257  // declaration will avoid warnings about partially-overloaded virtual
258  // functions.
260 
261  octave_value subsref (const std::string& type,
262  const std::list<octave_value_list>& idx)
263  {
264  octave_value_list tmp = subsref (type, idx, 1);
265  return tmp.length () > 0 ? tmp(0) : octave_value ();
266  }
267 
268  octave_value_list subsref (const std::string& type,
269  const std::list<octave_value_list>& idx,
270  int nargout)
271  {
272  return m_rep->subsref (type, idx, nargout);
273  }
274 
275  octave_value_list call (int nargout, const octave_value_list& args);
276 
277  bool is_defined () const { return true; }
278 
280 
281  bool is_function_handle () const { return true; }
282 
283  bool is_internal () const { return m_rep->is_internal (); }
284 
285  bool is_simple () const { return m_rep->is_simple (); }
286 
287  bool is_scoped () const { return m_rep->is_scoped (); }
288 
289  bool is_nested () const { return m_rep->is_nested (); }
290 
291  bool is_nested (const std::shared_ptr<octave::stack_frame>& frame) const
292  {
293  return m_rep->is_nested (frame);
294  }
295 
296  bool is_weak_nested () const { return m_rep->is_weak_nested (); }
297 
298  bool is_class_simple () const { return m_rep->is_class_simple (); }
299 
300  bool is_anonymous () const { return m_rep->is_anonymous (); }
301 
302  bool is_weak_anonymous () const { return m_rep->is_weak_anonymous (); }
303 
305  {
306  return m_rep->make_weak_nested_handle ();
307  }
308 
310  {
311  return m_rep->make_weak_anonymous_handle ();
312  }
313 
314  dim_vector dims () const;
315 
316  // FIXME: These must go away. They don't do the right thing for
317  // scoping or overloads.
319  {
320  return m_rep->function_value ();
321  }
322 
324  {
325  return m_rep->user_function_value ();
326  }
327 
328  octave_fcn_handle * fcn_handle_value (bool = false) { return this; }
329 
330  octave_value fcn_val () { return m_rep->fcn_val (); }
331 
332  // FCN_NAME should be eliminated.
333  std::string fcn_name () const { return m_rep->fcn_name (); }
334 
336  {
337  return m_rep->workspace ();
338  }
339 
340  octave_scalar_map info () { return m_rep->info (); }
341 
342  void set_dispatch_class (const std::string& class_name)
343  {
344  m_rep->set_dispatch_class (class_name);
345  }
346 
347  std::string get_dispatch_class () const
348  {
349  return m_rep->get_dispatch_class ();
350  }
351 
352  octave_value convert_to_str_internal (bool pad, bool force, char type) const
353  {
354  return m_rep->convert_to_str_internal (pad, force, type);
355  }
356 
357  bool save_ascii (std::ostream& os);
358 
359  bool load_ascii (std::istream& is);
360 
361  bool save_binary (std::ostream& os, bool save_as_floats);
362 
363  bool load_binary (std::istream& is, bool swap,
365 
366  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
367 
368  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
369 
370  void print (std::ostream& os, bool pr_as_read_syntax = false);
371 
372  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
373 
374  // Simple function handles are printed without a newline.
375  bool print_as_scalar () const { return m_rep->print_as_scalar (); }
376 
377  friend bool
378  is_equal_to (const octave_fcn_handle& fh1, const octave_fcn_handle& fh2);
379 
380 private:
381 
382  std::shared_ptr<octave::base_fcn_handle> m_rep;
383 
384  octave::base_fcn_handle * get_rep () const { return m_rep.get (); }
385 
387 };
388 
389 extern bool
390 is_equal_to (const octave_fcn_handle& fh1, const octave_fcn_handle& fh2);
391 
392 #endif
virtual bool is_weak_nested() const
Definition: ov-fcn-handle.h:80
virtual bool save_binary(std::ostream &os, bool save_as_floats)
virtual bool is_scoped() const
Definition: ov-fcn-handle.h:71
virtual bool is_weak_anonymous() const
Definition: ov-fcn-handle.h:86
virtual bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
virtual bool is_class_simple() const
Definition: ov-fcn-handle.h:82
std::string m_name
void unimplemented(const char *op, const char *fmt) const
std::string file() const
Definition: ov-fcn-handle.h:94
virtual bool print_as_scalar() const
virtual bool is_nested(const std::shared_ptr< stack_frame > &) const
Definition: ov-fcn-handle.h:75
virtual bool save_ascii(std::ostream &os)
virtual void set_dispatch_class(const std::string &)
void warn_save(const char *file_type) const
virtual bool load_binary(std::istream &is, bool swap, mach_info::float_format fmt)
virtual bool is_simple() const
Definition: ov-fcn-handle.h:69
virtual void compile()
virtual bool has_function_cache() const
virtual bool load_hdf5(octave_hdf5_id &group_hid, octave_hdf5_id &space_hid, octave_hdf5_id &type_hid)
virtual octave_function * get_cached_fcn(void *, void *)
virtual octave_scalar_map info()
base_fcn_handle(const base_fcn_handle &)=default
virtual octave_value_list call(int nargout, const octave_value_list &args)=0
void warn_load(const char *file_type) const
virtual octave_function * function_value(bool=false)
base_fcn_handle(const std::string &name="", const std::string &file="")
Definition: ov-fcn-handle.h:54
virtual ~base_fcn_handle()=default
virtual octave_value make_weak_anonymous_handle() const
virtual std::string get_dispatch_class() const
virtual octave_value workspace() const
virtual bool is_nested() const
Definition: ov-fcn-handle.h:73
virtual bool load_ascii(std::istream &is)
virtual base_fcn_handle * clone() const =0
virtual octave_value fcn_val()
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
octave_value convert_to_str_internal(bool pad, bool force, char type) const
std::string fcn_name() const
Definition: ov-fcn-handle.h:92
virtual octave_function * get_cached_fcn(const octave_value_list &)
virtual octave_user_function * user_function_value(bool=false)
virtual octave_value make_weak_nested_handle() const
virtual bool is_anonymous() const
Definition: ov-fcn-handle.h:84
virtual std::string type() const =0
virtual bool set_fcn(const std::string &, const std::string &)
std::string m_file
virtual void print_raw(std::ostream &, bool, int) const
virtual bool is_internal() const
Definition: ov-fcn-handle.h:67
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
virtual octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-base.cc:248
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:940
~octave_fcn_handle()=default
static const std::string anonymous
bool is_defined() const
bool is_nested() const
octave_scalar_map info()
bool is_class_simple() const
bool print_as_scalar() const
std::string get_dispatch_class() const
octave_fcn_handle(const std::string &name, octave_value cache)
octave_user_function * user_function_value(bool=false)
octave_value fcn_val()
octave_value_list call(int nargout, const octave_value_list &args)
builtin_type_t builtin_type() const
octave_value convert_to_str_internal(bool pad, bool force, char type) const
octave_fcn_handle * fcn_handle_value(bool=false)
octave_value make_weak_anonymous_handle() const
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
bool is_internal() const
octave_base_value * clone() const
std::string fcn_name() const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
bool is_anonymous() const
octave_function * function_value(bool=false)
octave_value workspace() const
bool is_simple() const
bool is_scoped() const
bool is_function_handle() const
octave_value make_weak_nested_handle() const
octave_base_value * empty_clone() const
bool is_weak_anonymous() const
bool is_weak_nested() const
bool is_nested(const std::shared_ptr< octave::stack_frame > &frame) const
void set_dispatch_class(const std::string &class_name)
octave_user_function * user_function_value(bool=false)
Definition: ov-usr-fcn.h:218
octave_idx_type length() const
Definition: ovl.h:113
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition: ov.h:1312
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
float_format
Definition: mach-info.h:38
int64_t octave_hdf5_id
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
Definition: ov-base.h:181
builtin_type_t
Definition: ov-base.h:83
@ btyp_func_handle
Definition: ov-base.h:100
bool is_equal_to(const octave_fcn_handle &fh1, const octave_fcn_handle &fh2)