/** * \file * Interface definition code. Each interface is a set of selector functions * as well as a data structure where the concrete implementation will be stored. * This structure is the intergrated in the class that implements the * interface. * * \author Georg Hopp * * \copyright * Copyright © 2012-2013 Georg Hopp * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef __TR_INTERFACE_H__ #define __TR_INTERFACE_H__ #include /** * The maximum number of interfaces per class. * * \cond PRIVATE */ #define TR_MAX_IFACE 32 // ATTENTION: every iface_impl will use // MAX_IFACE * sizeof(void*) /** \endcond */ /** * Get interface implementation in the current compile context * by it's interface name. * TR_CREATE_CLASS accepts a list of interface implementations for * initialization of the class. This makes it easier to add these. * * \see TR_CREATE_CLASS */ #define TR_IF(name) ((const struct i_##name const*)&i_##name##_impl) /** * Create an implementation of the interface "name" with the functions * given in the variable argument list. This in turn can then be used * within class initializations. * * \see TR_IF */ #define TR_INIT_IFACE(name,...) \ static const struct i_##name i_##name##_impl = {&i_##name,__VA_ARGS__} #define TR_IFID const struct TR_interface * const _ #define TR_INTERFACE(name) \ extern const struct TR_interface i_##name; \ struct i_##name /** * Initialize the TR_interface structure for a new interface */ #define TR_CREATE_INTERFACE(name, nfunc) \ const struct TR_interface i_##name = { nfunc } /** * calculate the number of argument given to a macro during compile * time. Helper for TR_INIT_IFACE_IMPL. * * \see TR_INIT_IFACE_IMPL * * \cond PRIVATE */ #define TR_IFACE_NUMARGS(...) \ (sizeof((const void*[]){__VA_ARGS__})/sizeof(void*)) /** * Create a static struct TR_ifac_imp for the initializarion of a new * created class. This is only internally used in TR_CREATE_CLASS. * * \see TR_CREATE_CLASS */ #define TR_INIT_IFACE_IMPL(...) \ {TR_IFACE_NUMARGS(__VA_ARGS__), 0, {__VA_ARGS__}} /** * The interface implementations for a class. * This will be initialized statically during class creation. * * \see TR_INIT_IFACE_IMPL */ struct TR_iface_impl { /** the number of interface implementations */ const size_t nimpl; /** * This indicates if impls was sorted. The first time it * will be accessed via TR_interfaceGet, This array will * be sorted with quicksort to make subsequent interface * searches faster. After it was sorted this flag will be set * to true, * * \see TR_interfaceGet */ char simpl; /** Array to hold the used interface implementations. */ const void * impl[TR_MAX_IFACE]; }; typedef struct TR_iface_impl * TR_iface_impl_ptr; /** * Interface identifier structure. Each interface has to initialize one * of these. All implementations of the interface then contain this * pointer so that they can easily be identified. */ struct TR_interface { const size_t nmethods; }; typedef const struct TR_interface * TR_iface_ptr; /** * Get the interface implementation for the interface identified by * TR_iface_ptr. */ TR_iface_ptr TR_interfaceGet(TR_iface_impl_ptr, const TR_iface_ptr); /** endcond */ #endif // __TR_INTERFACE_H__ // vim: set ts=4 sw=4: