1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2012-2021 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_cdef_package_h) 27 #define octave_cdef_package_h 1 28 29 #include "octave-config.h" 30 31 #include <map> 32 #include <set> 33 #include <string> 34 35 #include "oct-refcount.h" 36 37 #include "cdef-object.h" 38 #include "ov.h" 39 40 namespace octave 41 { 42 class interpreter; 43 44 class 45 cdef_package : public cdef_meta_object 46 { 47 friend class cdef_class; 48 49 private: 50 51 class 52 cdef_package_rep : public cdef_meta_object_rep 53 { 54 public: 55 cdef_package_rep(void)56 cdef_package_rep (void) : cdef_meta_object_rep (), member_count (0) { } 57 58 cdef_package_rep& operator = (const cdef_package_rep&) = delete; 59 60 ~cdef_package_rep (void) = default; 61 copy(void)62 cdef_object_rep * copy (void) const { return new cdef_package_rep (*this); } 63 is_package(void)64 bool is_package (void) const { return true; } 65 get_name(void)66 std::string get_name (void) const { return get("Name").string_value (); } 67 set_name(const std::string & nm)68 void set_name (const std::string& nm) { put ("Name", nm); } 69 70 void install_class (const cdef_class& cls, const std::string& nm); 71 72 void install_function (const octave_value& fcn, const std::string& nm); 73 74 void install_package (const cdef_package& pack, const std::string& nm); 75 76 Cell get_classes (void) const; 77 78 Cell get_functions (void) const; 79 80 Cell get_packages (void) const; 81 static_count(void)82 octave_idx_type static_count (void) const { return member_count; } 83 destroy(void)84 void destroy (void) 85 { 86 if (member_count) 87 { 88 m_count++; 89 cdef_package lock (this); 90 91 member_count = 0; 92 class_map.clear (); 93 package_map.clear (); 94 } 95 else 96 delete this; 97 } 98 99 octave_value_list 100 meta_subsref (const std::string& type, 101 const std::list<octave_value_list>& idx, int nargout); 102 103 void meta_release (void); 104 meta_accepts_postfix_index(char type)105 bool meta_accepts_postfix_index (char type) const 106 { 107 return (type == '.'); 108 } 109 110 octave_value find (const std::string& nm); 111 112 private: 113 114 std::string full_name; 115 std::map<std::string, cdef_class> class_map; 116 std::map<std::string, octave_value> function_map; 117 std::map<std::string, cdef_package> package_map; 118 119 // The number of registered members in this package (classes, packages). 120 // This only accounts for the members that back-reference to this package. 121 octave_idx_type member_count; 122 123 typedef std::map<std::string, cdef_class>::iterator class_iterator; 124 typedef std::map<std::string, cdef_class>::const_iterator class_const_iterator; 125 typedef std::map<std::string, octave_value>::iterator function_iterator; 126 typedef std::map<std::string, octave_value>::const_iterator 127 function_const_iterator; 128 typedef std::map<std::string, cdef_package>::iterator package_iterator; 129 typedef std::map<std::string, cdef_package>::const_iterator 130 package_const_iterator; 131 cdef_package_rep(const cdef_package_rep & p)132 cdef_package_rep (const cdef_package_rep& p) 133 : cdef_meta_object_rep (p), full_name (p.full_name), 134 class_map (p.class_map), function_map (p.function_map), 135 package_map (p.package_map), member_count (p.member_count) 136 { } 137 wrap(void)138 cdef_package wrap (void) 139 { 140 m_count++; 141 return cdef_package (this); 142 } 143 }; 144 145 public: 146 cdef_package(void)147 cdef_package (void) : cdef_meta_object () { } 148 cdef_package(const std::string & nm)149 cdef_package (const std::string& nm) 150 : cdef_meta_object (new cdef_package_rep ()) 151 { 152 get_rep ()->set_name (nm); 153 } 154 cdef_package(const cdef_package & pack)155 cdef_package (const cdef_package& pack) : cdef_meta_object (pack) { } 156 cdef_package(const cdef_object & obj)157 cdef_package (const cdef_object& obj) 158 : cdef_meta_object (obj) 159 { 160 // This should never happen... 161 if (! is_package ()) 162 error ("internal error: invalid assignment from %s to meta.package object", 163 class_name ().c_str ()); 164 } 165 166 cdef_package& operator = (const cdef_package& pack) 167 { 168 cdef_object::operator = (pack); 169 170 return *this; 171 } 172 173 ~cdef_package (void) = default; 174 install_class(const cdef_class & cls,const std::string & nm)175 void install_class (const cdef_class& cls, const std::string& nm) 176 { 177 get_rep ()->install_class (cls, nm); 178 } 179 install_function(const octave_value & fcn,const std::string & nm)180 void install_function (const octave_value& fcn, const std::string& nm) 181 { 182 get_rep ()->install_function (fcn, nm); 183 } 184 install_package(const cdef_package & pack,const std::string & nm)185 void install_package (const cdef_package& pack, const std::string& nm) 186 { 187 get_rep ()->install_package (pack, nm); 188 } 189 get_classes(void)190 Cell get_classes (void) const 191 { 192 return get_rep ()->get_classes (); 193 } 194 get_functions(void)195 Cell get_functions (void) const 196 { 197 return get_rep ()->get_functions (); 198 } 199 get_packages(void)200 Cell get_packages (void) const 201 { 202 return get_rep ()->get_packages (); 203 } 204 get_name(void)205 std::string get_name (void) const { return get_rep ()->get_name (); } 206 find(const std::string & nm)207 octave_value find (const std::string& nm) 208 { 209 return get_rep ()->find (nm); 210 } 211 212 private: 213 get_rep(void)214 cdef_package_rep * get_rep (void) 215 { 216 return dynamic_cast<cdef_package_rep *> (cdef_object::get_rep ()); 217 } 218 get_rep(void)219 const cdef_package_rep * get_rep (void) const 220 { 221 return dynamic_cast<const cdef_package_rep *> (cdef_object::get_rep ()); 222 } 223 224 friend void install_classdef (interpreter& interp); 225 }; 226 } 227 228 #endif 229