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