GNU Octave 10.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-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_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
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
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
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,
135 mach_info::float_format fmt);
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
168protected:
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
183OCTAVE_END_NAMESPACE(octave)
184
185class OCTINTERP_API octave_fcn_handle : public octave_base_value
186{
187public:
188
189 static const std::string anonymous;
190
191 // Creates an invalid function handle. Used to create generic
192 // function handle objects when loading function handles. Further
193 // dispatch happens in the octave_fcn_handle load/save functions.
195
196 // Create a handle to a built-in or internal function.
197 octave_fcn_handle (const octave_value& fcn);
198
199 // Create a simple function handle that is not bound to a function.
200 // Lookup happens when a function call is attempted.
201 octave_fcn_handle (const std::string& name);
202
203 // Create a simple function handle that is bound to a function.
204 octave_fcn_handle (const octave_value& fcn, const std::string& name);
205
206 // Create a function handle that might be bound to a class method.
207 octave_fcn_handle (const std::string& class_nm, const std::string& meth_nm);
208
209 // Create a function handle bound to a class method.
210 octave_fcn_handle (const octave_value& fcn, const std::string& class_nm,
211 const std::string& meth_nm);
212
213 // Create a function handle bound to a class method.
214 octave_fcn_handle (const octave_value& obj, const octave_value& fcn,
215 const std::string& class_nm,
216 const std::string& meth_nm);
217
218 // Create a function handle bound to a scoped function.
219 octave_fcn_handle (const octave_value& fcn, const std::string& name,
220 const std::list<std::string>& parentage);
221
222 // Create a handle to a nested function.
223 octave_fcn_handle (const octave_value& fcn, const std::string& name,
224 const std::shared_ptr<octave::stack_frame>& closure_frames);
225
226 // Create an anonymous function handle with local variable values
227 // provided in LOCAL_VARS.
229 const octave::stack_frame::local_vars_map& local_vars,
230 const std::shared_ptr<octave::stack_frame>& closure_frames
231 = std::shared_ptr<octave::stack_frame> ());
232
233 // Create a simple function handle that is not bound to a function.
234 // Lookup happens when a function call is attempted and the function
235 // lookup is cached in a octave_fcn_cache.
236 octave_fcn_handle (const std::string& name, octave_value cache);
237
238 octave_fcn_handle (octave::base_fcn_handle *rep);
239
241
242 ~octave_fcn_handle () = default;
243
245 {
246 return new octave_fcn_handle (*this);
247 }
248
250 {
251 return new octave_fcn_handle ();
252 }
253
254 // We don't need to override all three forms of subsref. The using
255 // declaration will avoid warnings about partially-overloaded virtual
256 // functions.
258
259 octave_value subsref (const std::string& type,
260 const std::list<octave_value_list>& idx)
261 {
262 octave_value_list tmp = subsref (type, idx, 1);
263 return tmp.length () > 0 ? tmp(0) : octave_value ();
264 }
265
266 octave_value_list subsref (const std::string& type,
267 const std::list<octave_value_list>& idx,
268 int nargout)
269 {
270 return m_rep->subsref (type, idx, nargout);
271 }
272
273 octave_value_list call (int nargout, const octave_value_list& args);
274
275 bool is_defined () const { return true; }
276
278
279 bool is_function_handle () const { return true; }
280
281 bool is_internal () const { return m_rep->is_internal (); }
282
283 bool is_simple () const { return m_rep->is_simple (); }
284
285 bool is_scoped () const { return m_rep->is_scoped (); }
286
287 bool is_nested () const { return m_rep->is_nested (); }
288
289 bool is_nested (const std::shared_ptr<octave::stack_frame>& frame) const
290 {
291 return m_rep->is_nested (frame);
292 }
293
294 bool is_weak_nested () const { return m_rep->is_weak_nested (); }
295
296 bool is_class_simple () const { return m_rep->is_class_simple (); }
297
298 bool is_anonymous () const { return m_rep->is_anonymous (); }
299
300 bool is_weak_anonymous () const { return m_rep->is_weak_anonymous (); }
301
303 {
304 return m_rep->make_weak_nested_handle ();
305 }
306
308 {
309 return m_rep->make_weak_anonymous_handle ();
310 }
311
312 dim_vector dims () const;
313
314 // FIXME: These must go away. They don't do the right thing for
315 // scoping or overloads.
317 {
318 return m_rep->function_value ();
319 }
320
322 {
323 return m_rep->user_function_value ();
324 }
325
326 octave_fcn_handle * fcn_handle_value (bool = false) { return this; }
327
328 octave_value fcn_val () { return m_rep->fcn_val (); }
329
330 // FCN_NAME should be eliminated.
331 std::string fcn_name () const { return m_rep->fcn_name (); }
332
334 {
335 return m_rep->workspace ();
336 }
337
338 octave_scalar_map info () { return m_rep->info (); }
339
340 void set_dispatch_class (const std::string& class_name)
341 {
342 m_rep->set_dispatch_class (class_name);
343 }
344
345 std::string get_dispatch_class () const
346 {
347 return m_rep->get_dispatch_class ();
348 }
349
350 octave_value convert_to_str_internal (bool pad, bool force, char type) const
351 {
352 return m_rep->convert_to_str_internal (pad, force, type);
353 }
354
355 bool save_ascii (std::ostream& os);
356
357 bool load_ascii (std::istream& is);
358
359 bool save_binary (std::ostream& os, bool save_as_floats);
360
361 bool load_binary (std::istream& is, bool swap,
362 octave::mach_info::float_format fmt);
363
364 bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
365
366 bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
367
368 void print (std::ostream& os, bool pr_as_read_syntax = false);
369
370 void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
371
372 // Simple function handles are printed without a newline.
373 bool print_as_scalar () const { return m_rep->print_as_scalar (); }
374
375 friend bool
376 is_equal_to (const octave_fcn_handle& fh1, const octave_fcn_handle& fh2);
377
378private:
379
380 std::shared_ptr<octave::base_fcn_handle> m_rep;
381
382 octave::base_fcn_handle * get_rep () const { return m_rep.get (); }
383
385};
386
387extern bool
388is_equal_to (const octave_fcn_handle& fh1, const octave_fcn_handle& fh2);
389
390#endif
virtual bool is_weak_nested() const
virtual bool save_binary(std::ostream &os, bool save_as_floats)
virtual bool is_scoped() const
virtual bool is_weak_anonymous() const
virtual bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
virtual bool is_class_simple() const
virtual octave_function * function_value(bool=false)
std::string m_name
void unimplemented(const char *op, const char *fmt) const
std::string file() const
virtual bool print_as_scalar() const
virtual bool is_nested(const std::shared_ptr< stack_frame > &) const
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
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 bool load_hdf5(octave_hdf5_id &group_hid, octave_hdf5_id &space_hid, octave_hdf5_id &type_hid)
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 base_fcn_handle * clone() const =0
base_fcn_handle(const std::string &name="", const std::string &file="")
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
virtual bool load_ascii(std::istream &is)
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
virtual octave_value make_weak_nested_handle() 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:90
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:230
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:1327
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)