MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
octave_object.h
Go to the documentation of this file.
1 /*
2  * MBDyn (C) is a multibody analysis code.
3  * http://www.mbdyn.org
4  *
5  * Copyright (C) 1996-2017
6  *
7  * Pierangelo Masarati <masarati@aero.polimi.it>
8  * Paolo Mantegazza <mantegazza@aero.polimi.it>
9  *
10  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
11  * via La Masa, 34 - 20156 Milano, Italy
12  * http://www.aero.polimi.it
13  *
14  * Changing this copyright notice is forbidden.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation (version 2 of the License).
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  */
30 
31 /*
32  AUTHOR: Reinhard Resch <r.resch@secop.com>
33  Copyright (C) 2011(-2017) all rights reserved.
34 
35  The copyright of this code is transferred
36  to Pierangelo Masarati and Paolo Mantegazza
37  for use in the software MBDyn as described
38  in the GNU Public License version 2.1
39 */
40 
41 #ifndef OCTAVE_OBJECT_H_
42 #define OCTAVE_OBJECT_H_
43 
44 #include <mbconfig.h>
45 
46 #ifdef USE_OCTAVE
47 
48 #include <octave/oct.h>
49 #include <cassert>
50 #include <typeinfo>
51 #include <stdarg.h>
52 #include <stdexcept>
53 #include <string>
54 #include <map>
55 
56 namespace oct {
57 
58 class octave_object: public octave_base_value
59 {
60 protected:
61  typedef octave_value_list method_function(octave_object*, const octave_value_list&, int);
62  typedef void setup_class_object_function();
63  class class_object
64  {
65  public:
66  explicit class_object(class_object* parent_obj,setup_class_object_function* setup_class_obj_func)
67  :parent_object(parent_obj)
68  {
69  if ( NULL != setup_class_obj_func )
70  (*setup_class_obj_func)();
71  }
72 
73  method_function*& operator[](const std::string& method_name)
74  {
75  return method_table[method_name];
76  }
77 
78  size_t size()const
79  {
80  return method_table.size();
81  }
82  method_function* lookup_method(const std::string& method_name)const;
83  private:
84  typedef std::map<std::string,method_function*> method_table_t;
85  method_table_t method_table;
86  class_object* const parent_object;
87  };
88 protected:
89  octave_object();
90  virtual ~octave_object();
91 protected:
92  static class_object dispatch_class_object;
93 private:
94  virtual octave_value operator()(const octave_value_list& idx) const;
95  virtual const class_object* get_class_object()=0;
96  virtual octave_value_list subsref(const std::string& type,
97  const std::list<octave_value_list>& idx,
98  int nargout);
99  virtual octave_value subsref(const std::string& type,
100  const std::list<octave_value_list>& idx);
101  method_function* lookup_method(const std::string& method_name);
102 
103  virtual bool is_constant(void)const{ return true; }
104  virtual bool is_defined(void)const{ return true; }
105 };
106 
107 template <typename T>
108 class octave_object_ptr: public octave_value
109 {
110 public:
111  octave_object_ptr()
112  {
113 
114  }
115 
116  explicit octave_object_ptr(T* p)
117  :octave_value(p)
118  {
119 
120  }
121 
122  explicit octave_object_ptr(octave_base_value* p)
123  :octave_value(p)
124  {
125  check_type(*p);
126  }
127 
128  octave_object_ptr(const octave_object_ptr& ptr)
129  :octave_value(ptr)
130  {
131  }
132 
133  octave_object_ptr(const octave_value& rhs)
134  :octave_value(rhs)
135  {
136  check_type(rhs.get_rep());
137  }
138 
139  template <typename U>
140  octave_object_ptr(const octave_object_ptr<U>& rhs)
141  :octave_value(rhs)
142  {
143  check_type(rhs.get_rep());
144  }
145 
146  octave_object_ptr& operator=(const octave_object_ptr& rhs)
147  {
148  octave_value::operator =(rhs);
149  return *this;
150  }
151 
152  octave_object_ptr& operator=(const octave_value& rhs)
153  {
154  check_type(rhs.get_rep());
155 
156  octave_value::operator=(rhs);
157  return *this;
158  }
159 
160  template <typename U>
161  octave_object_ptr& operator=(const octave_object_ptr<U>& rhs)
162  {
163  check_type(rhs.get_rep());
164 
165  octave_value::operator=(rhs);
166  return *this;
167  }
168 
169  T& get_rep()const
170  {
171  return static_cast<T&>(const_cast<octave_base_value&>(octave_value::get_rep()));
172  }
173 
174  T* operator->()const
175  {
176  return &get_rep();
177  }
178 
179 private:
180  static void check_type(const octave_base_value& ref) throw(std::bad_cast)
181  {
182  if ( NULL == dynamic_cast<const T*>(&ref) )
183  throw std::bad_cast();
184  }
185 };
186 
187 extern void error(const char* fmt, ...)
188 #ifdef __GNUC__
189  __attribute__((format (printf, 1, 2)))
190 #else
191  #warning "printf format will not be checked!"
192 #endif
193 ;
194 
195 #define BEGIN_METHOD_TABLE_DECLARE() \
196  virtual const class_object* get_class_object(); \
197  static class_object dispatch_class_object; \
198  static void setup_class_object();
199 
200 #define METHOD_DECLARE(method_name) \
201  octave_value_list method_name(const octave_value_list&, int); \
202  static octave_value_list method_name(octave_object* object__,const octave_value_list&,int);
203 
204 #define END_METHOD_TABLE_DECLARE()
205 
206 #define METHOD_DEFINE(class_name,method_name,args,nargout) \
207  octave_value_list class_name::method_name(octave_object *object__, \
208  const octave_value_list& args, \
209  int nargout) \
210  { \
211  return dynamic_cast<class_name&>(*object__).method_name(args,nargout); \
212  } \
213  octave_value_list class_name::method_name(const octave_value_list& args, int nargout)
214 
215 #define BEGIN_METHOD_TABLE(class_name,base_class_name) \
216  octave_object::class_object class_name::dispatch_class_object(&base_class_name::dispatch_class_object,&class_name::setup_class_object); \
217  const octave_object::class_object* class_name::get_class_object() \
218  { \
219  return &dispatch_class_object; \
220  } \
221  void class_name::setup_class_object() \
222  { \
223  if ( dispatch_class_object.size() == 0 ) \
224  {
225 
226 #define METHOD_DISPATCH(class_name,method_name) \
227  dispatch_class_object[#method_name] = &class_name::method_name;
228 
229 #define END_METHOD_TABLE() \
230  } else assert(false); \
231  }
232 
233 } // namespace
234 
235 #endif // USE_OCTAVE
236 
237 #endif /* OCTAVE_OBJECT_H_ */
int error(const char *test, int value)