GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ov-fcn-handle.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2003-2026 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
45class interpreter;
46class tree_evaluator;
47
48// Function handles.
49
50class OCTINTERP_API base_fcn_handle
51{
52public:
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 OCTINTERP_API octave_value make_weak_nested_handle () const;
89
90 virtual OCTINTERP_API octave_value make_weak_anonymous_handle () const;
91
92 std::string fcn_name () const { return m_name; }
93
94 std::string file () const { return m_file; }
95
96 OCTINTERP_API octave_value_list
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
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 OCTINTERP_API octave_value
127 convert_to_str_internal (bool pad, bool force, char type) const;
128
129 virtual OCTINTERP_API bool save_ascii (std::ostream& os);
130
131 virtual OCTINTERP_API bool load_ascii (std::istream& is);
132
133 virtual OCTINTERP_API bool
134 save_binary (std::ostream& os, bool save_as_floats);
135
136 virtual OCTINTERP_API bool
137 load_binary (std::istream& is, bool swap, mach_info::float_format fmt);
138
139 virtual OCTINTERP_API bool
140 save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
141
142 virtual OCTINTERP_API bool
143 load_hdf5 (octave_hdf5_id& group_hid, octave_hdf5_id& space_hid,
144 octave_hdf5_id& type_hid);
145
146 virtual void print_raw (std::ostream&, bool /*pr_as_read_syntax*/,
147 int /*current_print_indent_level*/) const
148 { }
149
150 // Function handles are printed without a newline by default.
151 virtual bool print_as_scalar () const { return true; }
152
153 virtual bool
154 set_fcn (const std::string& /*octaveroot*/, const std::string& /*fpath*/)
155 {
156 return false;
157 }
158
159 virtual octave_function *
160 get_cached_fcn (void *, void *) { return nullptr; }
161
162 virtual octave_function *
163 get_cached_fcn (const octave_value_list&) { return nullptr; }
164
165 virtual bool
166 has_function_cache () const { return false; }
167
168 virtual void compile () { }
169
170protected:
171
172 OCTINTERP_API void warn_load (const char *file_type) const;
173 OCTINTERP_API void warn_save (const char *file_type) const;
174
175 OCTINTERP_API void unimplemented (const char *op, const char *fmt) const;
176
177 // The name of the handle, not including the "@", or the text of the
178 // anonymous function.
179 std::string m_name;
180
181 // The name of the file where the named function was defined.
182 std::string m_file;
183};
184
185OCTAVE_END_NAMESPACE(octave)
186
187class OCTINTERP_API octave_fcn_handle : public octave_base_value
188{
189public:
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.
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,
364 octave::mach_info::float_format fmt);
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
380private:
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
389extern bool
390is_equal_to (const octave_fcn_handle& fh1, const octave_fcn_handle& fh2);
391
392#endif
virtual bool is_weak_nested() const
virtual bool is_scoped() const
virtual bool is_weak_anonymous() const
virtual bool is_class_simple() const
virtual octave_function * function_value(bool=false)
std::string m_name
std::string file() const
virtual bool print_as_scalar() const
virtual bool is_nested(const std::shared_ptr< stack_frame > &) const
virtual void set_dispatch_class(const std::string &)
virtual bool is_simple() const
virtual void compile()
virtual octave_function * get_cached_fcn(const octave_value_list &)
virtual octave_function * get_cached_fcn(void *, void *)
virtual bool has_function_cache() const
virtual octave_user_function * user_function_value(bool=false)
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
virtual base_fcn_handle * clone() const =0
base_fcn_handle(const std::string &name="", const std::string &file="")
virtual ~base_fcn_handle()=default
virtual std::string get_dispatch_class() const
virtual octave_value workspace() const
virtual bool is_nested() const
virtual octave_value fcn_val()
std::string fcn_name() const
virtual bool is_anonymous() const
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
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:92
virtual octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition ov-base.cc:245
virtual octave_function * function_value(bool silent=false)
Definition ov-base.cc:935
~octave_fcn_handle()=default
static const std::string anonymous
bool is_defined() const
octave_function * function_value(bool=false)
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_value fcn_val()
octave_value_list call(int nargout, const octave_value_list &args)
builtin_type_t builtin_type() const
octave_user_function * user_function_value(bool=false)
octave_value convert_to_str_internal(bool pad, bool force, char type) const
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_fcn_handle * fcn_handle_value(bool=false)
std::string fcn_name() const
octave_base_value * clone() const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
bool is_anonymous() const
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:233
octave_idx_type length() const
Definition ovl.h:111
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition ov.h:1325
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
int64_t octave_hdf5_id
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA_API(API)
Definition ov-base.h:185
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)