Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | List of all members
minxlib::exception Class Reference

Base class for minxlib exceptions. More...

#include <exception.hh>

Public Member Functions

virtual ~exception () throw ()
 Virtual destructor. More...
 

Static Public Member Functions

static void pythonize ()
 Expose exception interface to Python. More...
 

Protected Types

typedef void(* py_func )()
 Signature for Pythonize functions. More...
 

Protected Member Functions

 exception (const std::string &msg)
 Construct base exception object. More...
 

Static Protected Member Functions

static bool register_pythonize (type_info t, py_func f)
 Register subclass's pythonize function. More...
 
static void set_py_exception (type_info t, PyObject *e)
 Register Python exception class object for a subclass. More...
 
static PyObject * get_py_exception (type_info t)
 Retrieve Python exception class for specified C++ type. More...
 
template<typename T >
static void translate (const T &e)
 Generic Boost.Python exception translator. More...
 
template<typename T >
static void register_translator ()
 Register Boost.Python exception translator for type T. More...
 

Detailed Description

Base class for minxlib exceptions.

This class acts as a base for the various exceptions thrown by minxlib. This class is exposed as a Python class that is derived from Python's standard Exception class. Thus, subclasses of this one inherit Python's Exception interface.

Note
This class cannot be instantiated directly by client code (neither inside minxlib nor in the Python side of Minx). It is meant to be a common base from which other, specific types of errors are derived.

Member Typedef Documentation

typedef void(* minxlib::exception::py_func)()
protected

Signature for Pythonize functions.

Each subclass has to define a static Pythonize function that will export its interface to minxlib's Python module using the appropriate Boost.Python incantations. All the Pythonize functions of direct subclasses will be called by exception::pythonize(), which is called by the main Python initialization module python.cc.

Note
The Pythonize functions of indirect subclasses, i.e., subclasses of subclasses of minxlib::exception, should be called by the Pythonize functions of their respective direct base classes. To clarify, if we have two classes foo and bar derived from some_error, which is derived from minxlib::exception, exception::pythonize() will call some_error::pythonize(), which should, in turn, call foo::pythonize() and bar::pythonize().

Constructor & Destructor Documentation

minxlib::exception::exception ( const std::string &  msg)
protected

Construct base exception object.

Parameters
msgAn error message describing the problem.
Returns
A properly constructed minxlib::exception object.

A protected constructor to ensure that only subclasses can construct objects of this type. The msg parameter is simply passed as-is to the std::runtime_error constructor.

virtual minxlib::exception::~exception ( )
throw (
)
virtual

Virtual destructor.

Returns
Nothing.

Since this is a base class, it's good to have a virtual destructor in place.

Note
std::runtime_error already has a virtual destructor. However, if we skip this definition, the compiler complains about this class's auto-generated destructor having looser throw specifications than the base class.

Member Function Documentation

static PyObject* minxlib::exception::get_py_exception ( type_info  t)
staticprotected

Retrieve Python exception class for specified C++ type.

Parameters
tC++ exception class/subclass typeid.
Returns
Python exception class object corresponding to t.

When we raise a minxlib exception to inform the Python side of Minx of some problem, we need the Python exception class corresponding to the C++ exception type. This function retrieves the desired Python exception class object from the registry maintained by the minxlib::exception base class.

If a (direct or indirect) subclass of minxlib::exception fails to register a Python exception class corresponding to its C++ type, this function will return the Python exception class corresponding to the minxlib::exception class. If this ever happens, it indicates a bug in the implementation of type t!

static void minxlib::exception::pythonize ( )
static

Expose exception interface to Python.

Returns
Nothing.

This function is meant to be called as part of the Boost.Python module initialization. It will call the Pythonize functions of all minxlib::exception subclasses in order to export the entire minxlib exception hierarchy to Python.

static bool minxlib::exception::register_pythonize ( type_info  t,
py_func  f 
)
staticprotected

Register subclass's pythonize function.

Parameters
tSubclass typeid.
fPointer to subclass's pythonize function.
Returns
Nothing really.

The main Python initialization module, python.cc, calls exception::pythonize() to export the entire minxlib exception class hierarchy to the Python parts of Minx. All subclasses of minxlib::exception are expected to implement a Pythonize function that takes care of exporting their respective Python interfaces. To ensure that minxlib::exception::pythonize() can call the Pythonize functions of subclasses, all direct subclasses of minxlib::exception should call this function to let the base exception class know the address of the subclass's Pythonize function.

Note
Only direct subclasses of minxlib::exception should use this function. If a subclass of a subclass of minxlib::exception registers its Pythonize function using this routine, it could happen that the indirect subclass's Pythonize function gets called before its base class's Pythonize function, which can mess up the Boost.Python interface initialization sequence. Base classes of subclasses of subclasses of minxlib::exception should provide their own mechanisms for registering the Pythonize functions of their subclasses.

To make the registration mechanism described above work, direct subclasses of minxlib::exception should declare a static bool variable and in its initializer, call this function.

template<typename T >
static void minxlib::exception::register_translator ( )
inlinestaticprotected

Register Boost.Python exception translator for type T.

Returns
Nothing.

This function is meant to be used in the Pythonize routines of minxlib::exception and its subclasses that need an exception translator for their type. It simply generates a translator for type T (which is the exception::translate<T>() function) and calls the appropriate Boost.Python API to register exception::translate<T>() as the exception translator for type T.

static void minxlib::exception::set_py_exception ( type_info  t,
PyObject *  e 
)
staticprotected

Register Python exception class object for a subclass.

Parameters
tSubclass typeid.
eThe subclass's Python exception class.
Returns
Nothing.

Each minxlib exception class must have a corresponding Python exception class object, which must be registered with the minxlib::exception base class. In their respective Pythonize functions, all subclasses of minxlib::exception have to create a Python exception class corresponding to their C++ types and then call this function to insert that Python class object into the base class's registry of exception classes.

Note
Unlike register_pythonize(), which is meant only for direct subclasses of minxlib::exception, this function can and should be used by all subclasses (direct or indirect).
template<typename T >
static void minxlib::exception::translate ( const T &  e)
staticprotected

Generic Boost.Python exception translator.

Parameters
eC++ exception object that needs to be translated to Python.
Returns
Nothing.

This function sets up an exception translator for an exception of type T, which is expected to be either minxlib::exception or one of its subclasses.

All these translators follow the same pattern, viz., calling PyErr_SetString() using the Python exception class corresponding to type T as stored in exception::m_py_exception_map. Thus, we can use a generic function for this purpose.