Design Considerations¶
Design contents¶
Design introduction¶
The design goal is to create an object-oriented computing library with classes that perform common numerical tasks. The most important principle is that the library should add functionality to the user while at the same time retaining as much freedom for the user as possible and allowing for ease of use and extensibility. A few recommendations:
The classes which utilize user-specified functions should be able to operate on member functions without requiring a particular inheritance structure,
The interfaces should be generic where possible so that the user can create new classes which perform related numerical tasks through inheritance.
The classes should avoid static variables or static functions.
Const-correctness and type-safety should be respected wherever possible.
Header file dependencies¶
For reference, it is useful to know how the top-level header files depend on each other, since it can be difficult to trace everything down. The following are the most “top-level” header files and their associated dependencies within O₂scl (there are other dependencies on GSL and the C standard library not listed here). Note that not all of the headers in the “base” directory are listed here (because they are less likely to cause problems)
- Tier 1
constants.h : (none)
err_hnd.h : (none)
- Tier 2
exception.h : err_hnd.h
misc.h : err_hnd.h
find_constants.h : constants.h
rng.h (in the mcarlo directory) : err_hnd.h
tridiag.h (in the linalg directory) : err_hnd.h
- Tier 3
string_conv.h : misc.h
- Tier 4
calc_utf8.h : rng.h err_hnd.h string_conv.h find_constants.h
columnify.h : misc.h string_conv.h
uniform_grid.h : string_conv.h err_hnd.h
format_float.h : err_hnd.h misc.h string_conv.h
- Tier 5
funct.h : err_hnd.h calc_utf8.h
vector.h : misc.h uniform_grid.h (vector_special.h)
mm_funct.h : calc_utf8.h
multi_funct.h : calc_utf8.h
- Tier 6
convert_units.h : find_constants.h calc_utf8.h misc.h string_conv.h vector.h constants.h
search_vec.h : err_hnd.h vector.h misc.h
permutation.h : vector.h
interp.h : search_vec.h tridiag.h vector.h
- Tier 7
lib_settings.h : convert_units.h find_constants.h
The interpolation, testing, and table headers are not as top-level as the ones above because they depend on tridiagonalization in the linear algebra directory:
interp.h : search_vec.h tridiag.h vector.h
table.h : misc.h interp.h shunting_yard.h
table_units.h : table.h lib_settings.h
test_mgr.h : string_conv.h misc.h table_units.h
The use of templates¶
Templates are used extensively, and this makes for longer compilation times so any code that can be removed conveniently from the header files should be put into source code files instead.
Error handling¶
Thread safety for errors¶
Two approaches to thread-safe error handling which are worth comparing: the first is GSL which uses return codes and global function for an error handler, and the second is the Math/Special Functions section of Boost, which uses a separate policy type for each function. One issue is thread safety: the GSL approach is thread safe only in the sense that one can in principle use the return codes in different threads to track errors. What one cannot do in GSL is use different user-defined error handlers for different threads. The Special Functions library allows one to choose a different Policy for every special function call, and thus allows quite a bit more flexibility in designing multi-threaded error handling.
Memory allocation functions¶
Several classes have allocate() and free() functions to allocate and deallocate memory. If an error occurs in an allocate() function, the function should free() the partial memory that was allocated and then call the error handler. Functions which deallocate memory should never fail and should never be required to call the error handler. Similarly, class destructors should never be required to call the error handler.
Define constants and macros¶
There are a couple define constants and macros that O₂scl
understands, they are all in upper case and begin with the prefix
O2SCL_
.
Range-checking for arrays and matrices is turned on by default, but
can be turned off by defining O2SCL_NO_RANGE_CHECK
during the
initial configuration of the library. To see how the library was
configured at runtime, use the o2scl::o2scl_settings
class.
There is a define constant O2SCL_NO_SYSTEM_FUNC which permanently
disables the shell command '!'
in cli (when the
constant is defined, the shell command doesn’t work even if
o2scl::cli::shell_cmd_allowed
is true
).
The constant O2SCL_DATA_DIR is defined internally to provide the
directory which contains the O₂scl data files. After
installation, this can be accessed in o2scl::o2scl_settings
.
All of the header files have their own define constant of the form
O2SCL_HEADER_FILE_NAME
which ensures that the header file is only
included once.
Finally, I sometimes comment out sections of code with:
#ifdef O2SCL_NEVER_DEFINED
...
#endif
This constant should not be defined by the user as it will cause compilation to fail.
Parameter ordering¶
In functions where this makes sense, generally input parameters will appear first, while output parameters or parameters which handle both input and output will appear later.
Global objects¶
There four global objects that are created in libo2scl:
o2scl::def_err_hnd
is the default error handlero2scl::alt_err_hnd
is the GSL-like error handlero2scl::err_hnd
is the pointer to the error handler (points too2scl::def_err_hnd
by default)o2scl::o2scl_settings
to control a few library settings
All other global objects should be avoided.
Thread safety¶
Most of the classes are thread-safe, meaning that two instances of the same class will not clash if their methods are called concurrently since static variables are only used for compile-time constants. Additionally, two threads should be able to safely call a const method for the same instance. However, two threads cannot, in general, safely modify the same instance of a class. In this respect, O₂scl is no different from GSL.
Copyright notices¶
For files where it is appropriate to do so, I have followed the prescription suggested in http://lists.gnu.org/archive/html/help-gsl/2008-11/msg00017.html retaining the GSL copyright notices and putting the O₂scl notices at the top. CERNLIB has no such standard, but their licensing information is outlined at http://cernlib.web.cern.ch/cernlib/conditions.html .