libtrbase  1.0.2
Web server and task management solution.
interface.h
Go to the documentation of this file.
1 /**
2  * \file
3  * Interface definition code. Each interface is a set of selector functions
4  * as well as a data structure where the concrete implementation will be stored.
5  * This structure is the intergrated in the class that implements the
6  * interface.
7  *
8  * \author Georg Hopp
9  *
10  * \copyright
11  * Copyright © 2014 Georg Hopp
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #ifndef __TR_INTERFACE_H__
28 #define __TR_INTERFACE_H__
29 
30 #include <sys/types.h>
31 
32 /**
33  * The maximum number of interfaces per class.
34  *
35  * \cond PRIVATE
36  */
37 #define TR_MAX_IFACE 32 // ATTENTION: every iface_impl will use
38  // MAX_IFACE * sizeof(void*)
39 /** \endcond */
40 
41 /**
42  * Get interface implementation in the current compile context
43  * by it's interface name.
44  * TR_CREATE_CLASS accepts a list of interface implementations for
45  * initialization of the class. This makes it easier to add these.
46  *
47  * \see TR_CREATE_CLASS
48  */
49 #define TR_IF(name) ((const struct i_##name const*)&i_##name##_impl)
50 
51 /**
52  * Create an implementation of the interface "name" with the functions
53  * given in the variable argument list. This in turn can then be used
54  * within class initializations.
55  *
56  * \see TR_IF
57  */
58 #define TR_INIT_IFACE(name,...) \
59  static const struct i_##name i_##name##_impl = {&i_##name,__VA_ARGS__}
60 
61 #define TR_IFID const struct TR_interface * const _
62 
63 #define TR_INTERFACE(name) \
64  extern const struct TR_interface i_##name; \
65  struct i_##name
66 
67 /**
68  * Initialize the TR_interface structure for a new interface
69  */
70 #define TR_CREATE_INTERFACE(name, nfunc) \
71  const struct TR_interface i_##name = { nfunc }
72 
73 /**
74  * calculate the number of argument given to a macro during compile
75  * time. Helper for TR_INIT_IFACE_IMPL.
76  *
77  * \see TR_INIT_IFACE_IMPL
78  *
79  * \cond PRIVATE
80  */
81 #define TR_IFACE_NUMARGS(...) \
82  (sizeof((const void*[]){__VA_ARGS__})/sizeof(void*))
83 
84 /**
85  * Create a static struct TR_ifac_imp for the initializarion of a new
86  * created class. This is only internally used in TR_CREATE_CLASS.
87  *
88  * \see TR_CREATE_CLASS
89  */
90 #define TR_INIT_IFACE_IMPL(...) \
91  {TR_IFACE_NUMARGS(__VA_ARGS__), {__VA_ARGS__}}
92 
93 /**
94  * The interface implementations for a class.
95  * This will be initialized statically during class creation.
96  *
97  * \see TR_INIT_IFACE_IMPL
98  */
99 struct TR_iface_impl {
100  /** the number of interface implementations */
101  const size_t nimpl;
102  /** Array to hold the used interface implementations. */
103  const void * impl[TR_MAX_IFACE];
104 };
105 typedef struct TR_iface_impl * TR_iface_impl_ptr;
106 
107 /**
108  * Interface identifier structure. Each interface has to initialize one
109  * of these. All implementations of the interface then contain this
110  * pointer so that they can easily be identified.
111  */
112 struct TR_interface {
113  const size_t nmethods;
114 };
115 
116 typedef const struct TR_interface * TR_iface_ptr;
117 
118 /**
119  * Get the interface implementation for the interface identified by
120  * TR_iface_ptr.
121  */
122 TR_iface_ptr TR_interfaceGet(TR_iface_impl_ptr, const TR_iface_ptr);
123 /** endcond */
124 
125 #endif // __TR_INTERFACE_H__
126 
127 // vim: set ts=4 sw=4:
TR_iface_ptr TR_interfaceGet(TR_iface_impl_ptr iface_impl, const TR_iface_ptr iface)
Definition: interface.c:35