.\" -*-nroff-*- .\" .\" The Sod runtime library .\" .\" (c) 2015 Straylight/Edgeware .\" . .\"----- Licensing notice --------------------------------------------------- .\" .\" This file is part of the Sensible Object Design, an object system for C. .\" .\" SOD is free software; you can redistribute it and/or modify .\" it under the terms of the GNU Library General Public License as .\" published by the Free Software Foundation; either version 2 of the .\" License, or (at your option) any later version. .\" .\" SOD 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 Library General Public License for more details. .\" .\" You should have received a copy of the GNU Library General Public .\" License along with SOD; if not, write to the Free .\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, .\" MA 02111-1307, USA. . .\" Highlight using terminal escapes, rather than overstriking. .\"\X'tty: sgr 1' . .\" String definitions and font selection. .ie t \{\ . ds o \(bu . if \n(.g .fam P .\} .el \{\ . ds o o .\} . .\" .hP TEXT -- start an indented paragraph with TEXT hanging off to the left .de hP .IP \h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c .. . .\"-------------------------------------------------------------------------- .TH sod 3 "8 September 2015" "Straylight/Edgeware" "Sensible Object Design" . .SH NAME sod \- Sensible Object Design runtime library . .\"-------------------------------------------------------------------------- .SH SYNOPSIS .B #include .PP .B void *\c .B SOD_XCHAIN(\c .IB chead , .BI "const " cls " *" obj ); .br .B ptrdiff_t .B SOD_OFFSETDIFF(\c .IB type , .IB mema , .IB memb ); .br .IB cls "__ilayout *" \c .B SOD_ILAYOUT(\c .IB cls , .IB chead , .BI "const void *" obj ); .br .B void *\c .B SOD_INSTBASE(\c .BI "const " cls " *" obj ); .PP .B const void *\c .B SOD_CLASSOF(\c .BI "const " cls " *" obj ); .br .B int .B sod_subclassp(\c .BI "const SodClass *" sub , .BI "const SodClass *" super ); .PP .IB cls " *" \c .B SOD_CONVERT(\c .IB cls , .BI "const void *" obj ); .br .B int .B sod_convert(\c .BI "const SodClass *" cls , .BI "const void *" obj ); .PP .IB cls " *" \c .B SOD_INIT(\c .IB cls , .BI "void *" p , .IB keywords ); .br .B void *\c .B sod_init(\c .BI "const SodClass *" cls , .BI "void *" p , .B ...); .br .B void *\c .B sod_initv(\c .BI "const SodClass *" cls , .BI "void *" p , .BI "va_list " ap ); .br .B SOD_DECL(\c .IB cls , .IB var ); .PP . .\"-------------------------------------------------------------------------- .SH DESCRIPTION . The functions and macros defined here generally expect that instances and classes inherit from the standard .B SodObject root object. While the translator can (at some effort) support alternative roots, they will require different run-time support machinery. . .SS Layout utilities The following macros are useful in finding one's way around an instance layout structure, given various levels of information about what kind of object one is dealing with, or for computing the tables which are used for this kind of navigation. .PP These macros are mostly intended for use in code generated by the Sod translator. Others may find them useful for special effects, but they can be tricky to understand and use correctly and can't really be recommended for general use. .PP The .B SOD_OFFSETDIFF macro returns the signed offset between two members of a structure or union type. Given a structure or union type .IR type , and two member names .I mema and .IR memb , then .B SOD_OFFSETDIFF(\c .IB type , .IB mema , .IB memb ) gives the difference, in bytes, between the objects .IB x . mema and .IB x . memb for any object .I x of type .IR type . This macro is used internally when generating vtables and is not expected to be very useful elsewhere. .PP The .B SOD_ILAYOUT macro recovers the instance layout base address from a pointer to one of its instance chains. Specifically, given a class name .IR cls , the nickname .I chead of the least specific class in one of .IR cls 's superclass chains, and a pointer .I obj to the instance storage for the chain containing .I chead within an exact instance of .I cls (i.e., not an instance of any proper subclass), .B SOD_ILAYOUT(\c .IB cls , .IB chead , .IB obj ) returns the a pointer to the layout structure containing .IB obj . This macro is used internally in effective method bodies and is not expected to be very useful elsewhere since it's unusual to have such specific knowledge about the dynamic type of an instance. The .B SOD_INSTBASE macro (described below) is more suited to general use. .PP The .B SOD_INSTBASE macro finds the base address of an instance's layout. Given a pointer .BI "const " cls " *" obj to an instance, .BI SOD_INSTBASE( obj ) returns the base address of the storage allocated to .IR obj . This is useful if you want to free a dynamically allocated instance, for example. This macro needs to look up an offset in .IR obj 's vtable to do its work. Compare .B SOD_ILAYOUT above, which is faster but requires precise knowledge of the instance's dynamic class. . .SS Classes The following macros and functions query the runtime relationhips between instances and classes. .PP The .B SOD_CLASSOF macro returns the class object describing an instance's dynamic class. Given a pointer .BI "const " cls " *" obj to an instance, .BI SOD_CLASSOF( obj ) returns a pointer to .IR obj 's dynamic class, which (assuming .I obj is typed correctly in the first place) will be a subclass of .IR cls . (If you wanted the class object for .I cls itself, it's called .IB cls __class \fR.) .PP The .B sod_subclassp function answers whether one class .I sub is actually a subclass of another class .IR super . .B sod_subclassp(\c .IB sub , .IB super ) returns nonzero if and only if .I sub is a subclass of .IR super . This involves a run-time trawl through the class structures: while some effort has been made to make it perform well it's still not very fast. . .SS Conversions The following macros and functions are used to convert instance pointers of some (static) type into instance pointers of other static types to the same instance. .PP The .B SOD_XCHAIN macro performs a `cross-chain upcast'. Given a pointer .I cls .BI * obj to an instance of a class of type .I cls and the nickname .I chead of the least specific class in one of .IR cls 's superclass chains which does not contain .I cls itself, .B SOD_XCHAIN(\c .IB chead , .IB obj ) returns the address of that chain's storage within the instance layout as a raw .B void * pointer. (Note that .I cls is not mentioned explicitly.) This macro is used by the generated .IB cls __CONV_ c conversion macros, which you are encouraged to use instead where possible. .PP The .B SOD_CONVERT macro and .B sod_convert function perform general conversions (up-, down-, and cross-casts) on instance pointers. Given a class .I cls and a pointer .BI "const void *" obj to an instance, they return an appropriately converted pointer to .I obj if .I obj is indeed an instance of (some subclass of) .IR cls ; otherwise they return a null pointer. .PP The .B SOD_CONVERT macro expects .I cls to be a class name; the .B sod_convert function expects a pointer to a class object instead. .PP This involves a run-time trawl through the class structures: while some effort has been made to make it perform well it's still not very fast. For upcasts (where .I cls is a superclass of the static type of .IR obj ) the automatically defined conversion macros should be used instead, because they're much faster and can't fail. .PP When the target class is known statically, it's slightly more convenient to use the .B SOD_CONVERT macro rather than the .B sod_convert function, since the class object name is longer and uglier, and the macro returns a pointer of the correct type. . .SS Instance lifecycle The following macros and functions manage the standard steps along an instance's lifecycle. .PP The .B SOD_INIT macro, and the .B sod_init and .B sod_initv functions, imprint and initialize an instance of a class .I cls in the storage starting at address .IR p . .PP The direct class for the new instance is specified as a class name to .BR SOD_INIT , or a pointer to a class object to the functions. .PP Keyword arguments for the initialization message may be provided. The .B SOD_INIT macro expects a single preprocessor-time argument which is a use of one of .B KWARGS or .B NO_KWARGS (see .BR keyword (3)); the .B sod_init function expects the keywords as a variable-length argument tail; and .B sod_initv expects the keywords to be passed indirectly, through the captured argument-tail cursor .IR ap . .PP The return value is an instance pointer for the class .IR cls ; the .B SOD_INIT macro will have converted it to the correct type, so it should probably be used where possible. In fact, this is guaranteed to be equal to .I p by the layout rules described in .BR sod-structs (3). .PP The .B SOD_DECL macro declares and initializes an instance with automatic storage duration. Given a class name .I cls and an identifier .IR var , .B SOD_DECL(\c .IB cls , .IB var ) declares .I var to be a pointer to an instance of .IR cls . The instance is initialized in the sense that its vtable and class pointers have been set up, and slots for which initializers are defined are set to the appropriate initial values. The instance has automatic storage duration: pointers to it will become invalid when control exits the scope of the declaration. . .\"-------------------------------------------------------------------------- .SH SEE ALSO .BR keyword (3), .BR sod (1), .BR sod-structs (3). . .\"-------------------------------------------------------------------------- .SH AUTHOR Mark Wooding, . .\"----- That's all, folks --------------------------------------------------