X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/45c534845b49ab429532df59efde578e7b959bdb..d83a91c663ced211bb7e4509f800859c3fa086e9:/lib/sod.h diff --git a/lib/sod.h b/lib/sod.h index 6a444e9..8270895 100644 --- a/lib/sod.h +++ b/lib/sod.h @@ -9,19 +9,20 @@ * * This file is part of the Sensble 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 General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * The SOD Runtime Library 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, + * The SOD Runtime 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 General Public License for more details. + * GNU Library General Public License for more details. * - * You should have received a copy of the GNU 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. + * 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. */ #ifndef SOD_H @@ -52,7 +53,7 @@ struct sod_vtable { * these. */ struct sod_instance { - struct sod_vtable *_vt; /* Pointer to (chain's) vtable */ + const struct sod_vtable *_vt; /* Pointer to (chain's) vtable */ }; /* Information about a particular chain of superclasses. In each class, @@ -73,7 +74,7 @@ struct sod_chain { /* --- @SOD_XCHAIN@ --- * * * Arguments: @chead@ = nickname of target chain's head - * @p@ = pointer to an instance chain + * @obj@ = pointer to an instance chain * * Returns: Pointer to target chain, as a @char *@. * @@ -82,7 +83,7 @@ struct sod_chain { * the automatically-generated upcast macros more palatable. */ -#define SOD_XCHAIN(chead, p) ((char *)(p) + (p)->_vt->_off_##chead) +#define SOD_XCHAIN(chead, obj) ((char *)(obj) + (obj)->_vt->_off_##chead) /* --- @SOD_OFFSETDIFF@ --- * * @@ -101,8 +102,8 @@ struct sod_chain { * * Arguments: @cls@ = name of a class * @chead@ = nickname of chain head of @cls@ - * @p@ = pointer to the @chead@ ichain of an (exact) instance of - * @cls@ + * @obj@ = pointer to the @chead@ ichain of an (exact) instance + * of @cls@ * * Returns: A pointer to the instance's base, cast as a pointer to the * ilayout structure. @@ -119,16 +120,39 @@ struct sod_chain { * necessary to use it safely. */ -#define SOD_ILAYOUT(cls, chead, p) \ +#define SOD_ILAYOUT(cls, chead, obj) \ ((struct cls##__ilayout *) \ - ((char *)(p) - offsetof(struct cls##__ilayout, chead))) + ((char *)(obj) - offsetof(struct cls##__ilayout, chead))) + +/* --- @SOD__CAR@ --- * + * + * Arguments: @...@ = a nonempty list of arguments + * + * Returns: The first argument only. + */ + +#if __STDC_VERSION__ >= 199901 +# define SOD__CAR(...) SOD__CARx(__VA_LIST__, _) +# define SOD__CARx(a, ...) a +#endif + +/*----- Utility macros ----------------------------------------------------*/ + +/* --- @SOD_CLASSOF@ --- * + * + * Arguments: @p@ = pointer to an instance chain + * + * Returns: A pointer to the instance's class, as a const SodClass. + */ + +#define SOD_CLASSOF(obj) ((const SodClass *)(obj)->_vt->_class) /* --- @SOD_INSTBASE@ --- * * - * Arguments: @p@ = pointer to an instance (i.e., the address of one of its - * instance chains) + * Arguments: @obj@ = pointer to an instance (i.e., the address of one of + * its instance chains) * - * Returns: The base address of @p@'s instance layout. + * Returns: The base address of @obj@'s instance layout, as a @void *@. * * Use: Finds the base address of an instance. If you know the * dynamic class of the object then @SOD_ILAYOUT@ is faster. If @@ -138,18 +162,36 @@ struct sod_chain { * zeroizing the instance structure. */ -#define SOD_INSTBASE(p) ((void *)((char *)(p) - (p)->_vt->_base)) +#define SOD_INSTBASE(obj) ((void *)((char *)(obj) - (obj)->_vt->_base)) -/*----- Utility macros ----------------------------------------------------*/ +/* --- @SOD_CONVERT@ --- * + * + * Arguments: @cls@ = a class type name + * @const void *obj@ = a pointer to an instance + * + * Returns: Pointer to appropriate instance ichain, or null if the + * instance isn't of the specified class. + * + * Use: This is a simple wrapper around the @sod_convert@, which + * you should see for full details. It accepts a class type + * name rather than a pointer to a class object, and arranges to + * return a pointer of the correct type. + */ -/* --- @SOD_CLASSOF@ --- * +#define SOD_CONVERT(cls, obj) ((cls *)sod_convert(cls##__class, (obj))) + +/* --- @SOD_DECL@ --- * * - * Arguments: @p@ = pointer to an instance chain + * Arguments: @cls_@ = a class type name + * @var_@ = a variable name * - * Returns: A pointer to the instance's class, as a const SodClass. + * Use: Declare @var_@ as a pointer to an initialized instance of + * @cls_@ with automatic lifetime. */ -#define SOD_CLASSOF(p) ((const SodClass *)(p)->_vt->_class) +#define SOD_DECL(cls_, var_) \ + struct cls_##__ilayout var_##__layout; \ + cls_ *var_ = cls_##__class->cls.init(&var_##__layout) /*----- Functions provided ------------------------------------------------*/ @@ -188,7 +230,7 @@ extern int sod_subclassp(const SodClass */*sub*/, const SodClass */*super*/); * to know what either C or S actually are. */ -extern void *sod_convert(const SodClass */*cls*/, void */*p*/); +extern void *sod_convert(const SodClass */*cls*/, const void */*obj*/); /*----- That's all, folks -------------------------------------------------*/