interface.h 3.87 KB
/**
 * \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 <http://www.gnu.org/licenses/>.
 */

#ifndef __TR_INTERFACE_H__
#define __TR_INTERFACE_H__

#include <sys/types.h>

/**
 * 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: