File: cdef-class.h

package info (click to toggle)
octave 6.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 124,192 kB
  • sloc: cpp: 322,665; ansic: 68,088; fortran: 20,980; objc: 8,121; sh: 7,719; yacc: 4,266; lex: 4,123; perl: 1,530; java: 1,366; awk: 1,257; makefile: 424; xml: 147
file content (450 lines) | stat: -rw-r--r-- 12,255 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2012-2021 The Octave Project Developers
//
// See the file COPYRIGHT.md in the top-level directory of this
// distribution or <https://octave.org/copyright/>.
//
// This file is part of Octave.
//
// Octave is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Octave is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Octave; see the file COPYING.  If not, see
// <https://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////

#if ! defined (octave_cdef_class_h)
#define octave_cdef_class_h 1

#include "octave-config.h"

#include <map>
#include <set>
#include <string>

#include "oct-refcount.h"

#include "cdef-method.h"
#include "cdef-object.h"
#include "cdef-package.h"
#include "cdef-property.h"
#include "error.h"
#include "ov.h"
#include "ovl.h"

namespace octave
{
  class interpreter;
  class tree_classdef;

  class
  cdef_class : public cdef_meta_object
  {
  private:

    class
    cdef_class_rep : public cdef_meta_object_rep
    {
    public:
      cdef_class_rep (void)
        : cdef_meta_object_rep (), member_count (0), handle_class (false),
          meta (false)
      { }

      cdef_class_rep (const std::list<cdef_class>& superclasses);

      cdef_class_rep& operator = (const cdef_class_rep&) = delete;

      ~cdef_class_rep (void) = default;

      cdef_object_rep * copy (void) const { return new cdef_class_rep (*this); }

      bool is_class (void) const { return true; }

      std::string get_name (void) const
      { return get ("Name").string_value (); }

      void set_name (const std::string& nm) { put ("Name", nm); }

      bool is_abstract (void) const { return get ("Abstract").bool_value (); }

      bool is_sealed (void) const { return get ("Sealed").bool_value (); }

      cdef_method find_method (const std::string& nm, bool local = false);

      void install_method (const cdef_method& meth);

      Cell get_methods (bool include_ctor);

      std::map<std::string, cdef_method>
      get_method_map (bool only_inherited, bool include_ctor);

      cdef_property find_property (const std::string& nm);

      void install_property (const cdef_property& prop);

      Cell get_properties (int mode);

      std::map<std::string, cdef_property> get_property_map (int mode);

      string_vector get_names (void);

      void set_directory (const std::string& dir) { directory = dir; }

      std::string get_directory (void) const { return directory; }

      void delete_object (const cdef_object& obj);

      octave_value_list
      meta_subsref (const std::string& type,
                    const std::list<octave_value_list>& idx, int nargout);

      void meta_release (void);

      bool meta_accepts_postfix_index (char type) const
      {
        return (type == '(' || type == '.');
      }

      octave_value get_method (const std::string& name) const;

      octave_value construct (const octave_value_list& args);

      cdef_object construct_object (const octave_value_list& args);

      void initialize_object (cdef_object& obj);

      void run_constructor (cdef_object& obj, const octave_value_list& args);

      void mark_as_handle_class (void) { handle_class = true; }

      bool is_handle_class (void) const { return handle_class; }

      octave_idx_type static_count (void) const { return member_count; }

      void destroy (void)
      {
        if (member_count)
          {
            m_count++;
            cdef_class lock (this);

            member_count = 0;
            method_map.clear ();
            property_map.clear ();
          }
        else
          delete this;
      }

      void mark_as_meta_class (void) { meta = true; }

      bool is_meta_class (void) const { return meta; }

      void doc_string (const std::string& txt) { m_doc_string = txt; }

      std::string doc_string (void) const { return m_doc_string; }

    private:

      void load_all_methods (void);

      void find_names (std::set<std::string>& names, bool all);

      void find_properties (std::map<std::string,cdef_property>& props,
                            int mode = 0);

      void find_methods (std::map<std::string, cdef_method>& meths,
                         bool only_inherited, bool include_ctor = false);

      cdef_class wrap (void)
      {
        m_count++;
        return cdef_class (this);
      }

      // The @-directory were this class is loaded from.
      // (not used yet)

      std::string directory;

      std::string m_doc_string;

      // The methods defined by this class.

      std::map<std::string,cdef_method> method_map;

      // The properties defined by this class.

      std::map<std::string,cdef_property> property_map;

      // The number of members in this class (methods, properties...)

      octave_idx_type member_count;

      // TRUE if this class is a handle class.  A class is a handle
      // class when the abstract "handle" class is one of its superclasses.

      bool handle_class;

      // The list of super-class constructors that are called implicitly by the
      // the classdef engine when creating an object.  These constructors are not
      // called explicitly by the class constructor.

      std::list<cdef_class> implicit_ctor_list;

      // TRUE if this class is a built-in meta class.

      bool meta;

      // Utility iterator typedefs.

      typedef std::map<std::string,cdef_method>::iterator method_iterator;
      typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator;
      typedef std::map<std::string,cdef_property>::iterator property_iterator;
      typedef std::map<std::string,cdef_property>::const_iterator property_const_iterator;

      cdef_class_rep (const cdef_class_rep& c) = default;
    };

  public:

    // Create an invalid class object.

    cdef_class (void) : cdef_meta_object () { }

    cdef_class (const std::string& nm, const std::list<cdef_class>& superclasses)
      : cdef_meta_object (new cdef_class_rep (superclasses))
    {
      get_rep ()->set_name (nm);
    }

    cdef_class (const cdef_class& cls) : cdef_meta_object (cls) { }

    cdef_class (const cdef_object& obj)
      : cdef_meta_object (obj)
    {
      // This should never happen...
      if (! is_class ())
        error ("internal error: invalid assignment from %s to meta.class object",
               class_name ().c_str ());
    }

    cdef_class& operator = (const cdef_class& cls)
    {
      cdef_object::operator = (cls);

      return *this;
    }

    ~cdef_class (void) = default;

    cdef_method find_method (const std::string& nm, bool local = false);

    void install_method (const cdef_method& meth)
    {
      get_rep ()->install_method (meth);
    }

    Cell get_methods (bool include_ctor = false)
    {
      return get_rep ()->get_methods (include_ctor);
    }

    std::map<std::string, cdef_method>
    get_method_map (bool only_inherited = false, bool include_ctor = false)
    {
      return get_rep ()->get_method_map (only_inherited, include_ctor);
    }

    cdef_property find_property (const std::string& nm);

    void install_property (const cdef_property& prop)
    {
      get_rep ()->install_property (prop);
    }

    Cell get_properties (int mode = property_normal)
    {
      return get_rep ()->get_properties (mode);
    }

    std::map<std::string, cdef_property>
    get_property_map (int mode = property_normal)
    {
      return get_rep ()->get_property_map (mode);
    }

    string_vector get_names (void) { return get_rep ()->get_names (); }

    bool is_abstract (void) const { return get_rep ()->is_abstract (); }

    bool is_sealed (void) const { return get_rep ()->is_sealed (); }

    void set_directory (const std::string& dir)
    {
      get_rep ()->set_directory (dir);
    }

    std::string get_directory (void) const
    {
      return get_rep ()->get_directory ();
    }

    std::string get_name (void) const { return get_rep ()->get_name (); }

    bool is_builtin (void) const { return get_directory ().empty (); }

    void delete_object (const cdef_object& obj)
    {
      get_rep ()->delete_object (obj);
    }

    //! Analyze the tree_classdef tree and transform it to a cdef_class
    //!
    //! <b>All attribute validation should occur here.</b>
    //!
    //! Classdef attribute values can be given in the form of
    //! expressions.  These expressions must be evaluated before
    //! assigning them as attribute values.  Evaluating them as they are
    //! parsed causes trouble with possible recursion in the parser so we
    //! do it here.  For example
    //!
    //! @code
    //! classdef recursion_class
    //!   methods (Access = ?recursion_class)
    //!   endmethods
    //! endclassdef
    //! @endcode
    //!
    //! will fail because each attempt to compute the metaclass of
    //! recursion_class will cause recursion_class to be parsed again.

    static cdef_class
    make_meta_class (interpreter& interp, tree_classdef *t,
                     bool is_at_folder = false);

    octave_value get_method (const std::string& nm) const
    {
      return get_rep ()->get_method (nm);
    }

    octave_value get_method_function (const std::string& nm);

    octave_value get_constructor_function (void)
    {
      return get_method_function (get_name ());
    }

    octave_value construct (const octave_value_list& args)
    {
      return get_rep ()->construct (args);
    }

    cdef_object construct_object (const octave_value_list& args)
    {
      return get_rep ()->construct_object (args);
    }

    void initialize_object (cdef_object& obj)
    {
      get_rep ()->initialize_object (obj);
    }

    void run_constructor (cdef_object& obj, const octave_value_list& args)
    {
      get_rep ()->run_constructor (obj, args);
    }

    void mark_as_handle_class (void)
    {
      get_rep ()->mark_as_handle_class ();
    }

    bool is_handle_class (void) const
    {
      return get_rep ()->is_handle_class ();
    }

    void mark_as_meta_class (void) { get_rep ()->mark_as_meta_class (); }

    bool is_meta_class (void) const { return get_rep ()->is_meta_class (); }

    void doc_string (const std::string& txt) { get_rep ()->doc_string (txt); }

    std::string doc_string (void) const { return get_rep ()->doc_string (); }

  public:

    enum
      {
       property_normal,
       property_inherited,
       property_all
      };

  private:

    cdef_class_rep * get_rep (void)
    {
      return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ());
    }

    const cdef_class_rep * get_rep (void) const
    {
      return dynamic_cast<const cdef_class_rep *> (cdef_object::get_rep ());
    }

    friend bool operator == (const cdef_class&, const cdef_class&);
    friend bool operator != (const cdef_class&, const cdef_class&);
    friend bool operator < (const cdef_class&, const cdef_class&);

    friend void install_classdef (interpreter& interp);
  };

  inline bool
  operator == (const cdef_class& clsa, const cdef_class& clsb)
  {
    // FIXME: is this really the right way to check class equality?

    return (clsa.get_rep () == clsb.get_rep ());
  }

  inline bool
  operator != (const cdef_class& clsa, const cdef_class& clsb)
  {
    return ! (clsa == clsb);
  }

  // This is only to be able to use cdef_class as map keys.

  inline bool
  operator < (const cdef_class& clsa, const cdef_class& clsb)
  {
    return clsa.get_rep () < clsb.get_rep ();
  }

  inline cdef_method
  cdef_class::find_method (const std::string& nm, bool local)
  {
    return get_rep ()->find_method (nm, local);
  }

  inline cdef_property
  cdef_class::find_property (const std::string& nm)
  {
    return get_rep ()->find_property (nm);
  }
}

#endif