• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/gettext-0.17/gnulib-local/lib/
1/* Minimal object-oriented facilities for C.
2   Copyright (C) 2006 Free Software Foundation, Inc.
3   Written by Bruno Haible <bruno@clisp.org>, 2006.
4
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of the GNU Library General Public License as published
7   by the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Library General Public License for more details.
14
15   You should have received a copy of the GNU Library General Public
16   License along with this program; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
18   USA.  */
19
20/* This file defines minimal facilities for object-oriented programming
21   style in ANSI C.
22
23   The facilities allow to define classes with single inheritance and
24   "virtual" methods.
25
26   Strict type checking is provided in combination with a C++ compiler:
27   The code compiles in ANSI C with less strict type checking; when
28   compiled with a C++ compiler, strict type checking is done.
29
30   In contrast to [OOC] and [OOPC], this implementation concentrates on the
31   bare essentials of an object-oriented programming style.  It does not
32   provide features that are "sometimes useful", but not essential.
33
34   Features:
35     - Combination of fields and methods into a single object.      YES
36     - Description of objects of same shape and same behaviour
37       by a class.                                                  YES
38     - Single inheritance.                                          YES
39     - Multiple inheritance.                                        NO
40     - Operator overloading (compile-time polymorphism).            NO
41     - Virtual methods (run-time polymorphism).                     YES
42     - Information hiding: private/protected/public.         private fields
43     - Static fields and methods.                                   NO
44     - Constructors, destructors.                                   NO
45     - 'new', 'delete'.                                             NO
46     - Exception handling.                                          NO
47     - Garbage collection.                                          NO
48     - Templates / Generic classes with parameters.                 NO
49     - Namespaces.                                                  NO
50     - Hidden 'this' pointer in methods.                            NO
51     - Declaring or implementing several classes in the same file.  NO
52
53   Rationale for NO:
54     - Multiple inheritance is not supported because programming languages
55       like Java and C# prove that they are not necessary. Modern design
56       patterns use delegation more often than composition; this reduces
57       the pressure to use multiple inheritance.
58       Multiple inheritance of "interfaces" (classes without fields) might
59       be considered, though.
60     - Operator overloading is not essential: The programmer can rename
61       methods so that they carry unambiguous method names. This also makes
62       the code more readable.
63     - Virtual methods are supported. Non-virtual methods are not: they
64       constitute an assumption about the possible subclasses which is more
65       often wrong than right. In other words, non-virtual methods are a
66       premature optimization - "the root of all evil", according to
67       Donald E. Knuth.
68     - Information hiding: 'protected' is not supported because it is always
69       inappropriate: it prohibits the use of the delegation design pattern.
70       'private' is implemented on fields. There are no 'public' fields,
71       since the use of getters/setters allows for overriding in subclasses
72       and is more maintainable (ability to set breakpoints). On the other
73       hand, all methods are 'public'. 'private` methods are not supported
74       because methods with static linkage can be used instead.
75     - Static fields and methods are not supported because normal variables
76       and functions with static or extern linkage can be used instead.
77     - Constructors and destructors are not supported.  The programmer can
78       define 'init' and 'do_free' methods himself.
79     - 'new', 'delete' are not supported because they only provide the
80       grouping of two lines of code into a single line of code.
81     - Exception handling is not supported because conventions with a return
82       code can be used instead.
83     - Garbage collection is not supported. Without it the programmer's life
84       is harder, but not impossible. The programmer has to think about
85       ownership of objects.
86     - Templates / Generic classes with parameters are not supported because
87       they are mostly used for container classes, and container classes can
88       be implemented in a simpler object-oriented way that requires only a
89       very limited form of class inheritance.
90     - Namespaces are not implemented, because they can be simulated by a
91       consistent naming convention.
92     - A hidden 'this' pointer in methods is not implemented. It reduces the
93       transparency of the code (because what looks like a variable access can
94       be an access through 'this') and is simply not needed.
95     - Declaring or implementing several classes in the same file is not
96       supported, because it is anyway good practice to define each class in
97       its own .oo.h / .oo.c file.
98
99   Syntax:
100
101   The syntax resembles C++, but deviates from C++ where the C++ syntax is
102   just too braindead.
103
104   A root class is declared in a .oo.h file:
105
106     struct rootfoo
107     {
108     methods:
109       int method1 (rootfoo_t x, ...); ...
110     };
111
112   and in the corresponding .oo.c file:
113
114     struct rootfoo
115     {
116     fields:
117       int field1; ...
118     };
119
120   A subclass is declared in a .oo.h file as well:
121
122     struct subclass : struct rootfoo
123     {
124     methods:
125       int method2 (subclass_t x, ...); ...
126     };
127
128   and in the corresponding .oo.c file:
129
130     struct subclass : struct rootfoo
131     {
132     fields:
133       int field2; ...
134     };
135
136   This defines:
137     - An incomplete type 'struct any_rootfoo_representation' or
138       'struct subclass_representation', respectively. It denotes the memory
139       occupied by an object of the respective class. The prefix 'any_' is
140       present only for a root class.
141     - A type 'rootfoo_t' or 'subclass_t' that is equivalent to a pointer
142       'struct any_rootfoo_representation *' or
143       'struct subclass_representation *', respectively.
144     - A type 'struct rootfoo_implementation' or
145       'struct subclass_implementation', respectively. It contains a virtual
146       function table for the corresponding type.
147     - A type 'struct rootfoo_representation_header' or
148       'struct subclass_representation_header', respectively, that defines
149       the part of the memory representation containing the virtual function
150       table pointer.
151     - Functions 'rootfoo_method1 (rootfoo_t x, ...);' ...
152                 'subclass_method1 (subclass_t x, ...);' ...
153                 'subclass_method2 (subclass_t x, ...);' ...
154       that invoke the corresponding methods. They are realized as inline
155       functions if possible.
156     - A declaration of 'rootfoo_typeinfo' or 'subclass_typeinfo', respectively,
157       each being a typeinfo_t instance.
158     - A declaration of 'ROOTFOO_SUPERCLASSES' or 'SUBCLASS_SUPERCLASSES',
159       respectively, each being an initializer for an array of typeinfo_t.
160     - A declaration of 'ROOTFOO_SUPERCLASSES_LENGTH' or
161       'SUBCLASS_SUPERCLASSES_LENGTH', respectively, each denoting the length
162       of that initializer.
163     - A declaration of 'rootfoo_vtable' or 'subclass_vtable', respectively,
164       being an instance of 'struct rootfoo_implementation' or
165       'struct subclass_implementation', respectively.
166     - A header file "rootfoo.priv.h" or "subclass.priv.h" that defines the
167       private fields of 'struct rootfoo_representation' or
168       'struct subclass_representation', respectively.
169
170   A class implementation looks like this, in a .oo.c file:
171
172     struct subclass : struct rootfoo
173     {
174     fields:
175       int field2; ...
176     };
177
178     int subclass::method1 (subclass_t x, ...) { ... } [optional]
179     int subclass::method2 (subclass_t x, ...) { ... }
180     ...
181
182   At the place of the second "struct subclass" definition, the type
183   'struct subclass_representation' is expanded, and the macro 'super' is
184   defined, referring to the vtable of the superclass. For root classes,
185   'super' is not defined. Also, 'subclass_typeinfo' is defined.
186
187   Each method subclass::method_i defines the implementation of a method
188   for the particular class. Its C name is subclass__method_i (not to be
189   confused with subclass_method_i, which is the externally visible function
190   that invokes this method).
191
192   Methods that are not defined implicitly inherited from the superclass.
193
194   At the end of the file, 'subclass_vtable' is defined, as well as
195     'subclass_method1 (subclass_t x, ...);' ...
196     'subclass_method2 (subclass_t x, ...);' ...
197   if they were not already defined as inline functions in the header file.
198
199   Object representation in memory:
200     - Objects have as their first field, called 'vtable', a pointer to a table
201       to data and function pointers that depend only on the class, not on the
202       object instance.
203     - One of the first fields of the vtable is a pointer to the
204       'superclasses'; this is a NULL-terminated array of pointers to
205       typeinfo_t objects, starting with the class itself, then its
206       superclass etc.
207
208
209   [OOC] Axel-Tobias Schreiner: Object-oriented programming with ANSI-C. 1993.
210
211   [OOPC] Laurent Deniau: Object Oriented Programming in C. 2001.
212
213 */
214
215#ifndef _MOO_H
216#define _MOO_H
217
218/* Get size_t, abort().  */
219#include <stdlib.h>
220
221/* An object of this type is defined for each class.  */
222typedef struct
223{
224  const char *classname;
225} typeinfo_t;
226
227/* IS_INSTANCE (OBJ, ROOTCLASSNAME, CLASSNAME)
228   tests whether an object is instance of a given class, given as lower case
229   class name.  */
230#define IS_INSTANCE(obj,rootclassname,classname) \
231  (((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses_length \
232   >= classname##_SUPERCLASSES_LENGTH \
233   && ((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses \
234      [((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses_length \
235       - classname##_SUPERCLASSES_LENGTH] \
236      == & classname##_typeinfo)
237/* This instance test consists of two comparisons.  One could even optimize
238   this to a single comparison, by limiting the inheritance depth to a fixed
239   limit, for example, say, depth <= 10.  The superclasses list would then
240   need to be stored in reverse order, from the root down to the class itself,
241   and be filled up with NULLs so that the array has length 10.  The instance
242   test would look like this:
243     #define IS_INSTANCE(obj,rootclassname,classname) \
244       (((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses \
245        [classname##_SUPERCLASSES_LENGTH - 1] \
246        == & classname##_typeinfo)
247   but the classname##_superclasses_length would no longer be available as a
248   simple sizeof expression.  */
249
250#endif /* _MOO_H */
251