Writing Kernel Independent CodeHeader FilesWe use the C++ precompilation mechanism to write code that is independent of the kernel. The kernels are designed such that all functions that are available in a rational kernel are also available in the corresponding floating point kernel.The only difference between the rational and the floating point kernel is the interpretation of the generic names POINT, SEGMENT, LINE, ... . In order to give the generic names the interpretation required in a particular kernel one of the following headers must be included. #include <LEDA/rat_kernel_names.h> #include <LEDA/float_kernel_names.h> #include <LEDA/d3_rat_kernel_names.h> #include <LEDA/d3_rat_kernel_names.h>Every one of these files consists of a sequence of define-statements which define the generic names for the corresponding kernel. There are also files to undefine all names used in a kernel: #include <LEDA/kernel_names_undef.h> #include <LEDA/d3_kernel_names_undef.h> ExampleSuppose we want to write a program that has to work with both two-dimensional kernels . We write a generic version of the program using only generic names:FOO.c : int main() { window W; W.display(); POINT p; while (W >> p) W << p.to_point(); return 0; }Then we derive the two specialized versions from it. With the first version the rational kernel is used: rat_foo_test.c: #include <LEDA/rat_point.h> #include <LEDA/window.h> #include <LEDA/rat_window.h> //lets W >> p work for rat_points #include <LEDA/rat_kernel_names.h> #include "FOO.c" #include <LEDA/kernel_names_undef.h>And with the second version the floating point kernel is used: foo_test.c: #include <LEDA/point.h> #include <LEDA/window.h> #include <LEDA/float_kernel_names.h> #include "FOO.c" #include <LEDA/kernel_names_undef.h> WarningThe header file window.h is included in both specializations and it is hence tempting to writeBAD_FOO.c : #include <window.h> int main() { window W; W.display(); POINT p; while (W >> p) W << p.to_point(); return 0; }This is very dangerous. The header window.h includes the entire floating point kernel which in turn includes files like transform.h. The latter file uses the renaming mechanism. Never include a file in a piece of code that is subject to renaming. Undefining all names at the end of the relevant piece of code helps to guard against this problem, since the compiler will generate a message that certain names later in the code are not defined.Kernel Specific CodeSometimes a small part of the code is specific to a particular kernel. We use conditional compilation in this situation. For example,//an error was just discovered #if (KERNEL == FLOAT_KERNEL) cerr << "Please move to the rational kernel.\n"; #else cerr << "Please report this error.\n"; #endifFor more details about writing kernel independent code have a look at the corresponding sections of the LEDA Book . |
See also:Advanced Data types for 2-D geometry Manual Entries: |