(eXtended Bundle of Tools)</b>.
It is a portable library providing some grounding features such as \ref
-XBT_log, \ref XBT_ex and \ref XBT_config. XBT also encompass
-the following convenient datastructures: \ref XBT_dynar, \ref XBT_fifo, \ref
-XBT_dict, \ref XBT_heap, \ref XBT_set and \ref XBT_swag.
+XBT_log, \ref XBT_ex and \ref XBT_config.
+
+XBT also encompass the following convenient C datastructures:
+\ref XBT_dynar, \ref XBT_fifo, \ref XBT_dict, \ref XBT_heap, \ref XBT_set and
+\ref XBT_swag. The code is being migrated in C++ so you should probably want
+to use standard C++ containers instead of them if possible.
+
+It contains some C++ polyfills and utilies as well.
See the \ref XBT_API section for more details.
- \ref XBT_file
- Grounding features
- \ref XBT_ex
+ - \ref XBT_ex_c
- \ref XBT_log
- \ref XBT_error
- \ref XBT_config
/** @defgroup XBT_syscall Malloc and friends */
/** @defgroup XBT_str String related functions */
- /** @defgroup XBT_ex Exception support */
+ /** @defgroup XBT_ex Exception support (C++) */
+ /** @defgroup XBT_ex_c Exception support (C) */
/** @defgroup XBT_log Logging support */
/** @defgroup XBT_error Assert macro familly */
/** @defgroup XBT_config Configuration support */
/** @} */
+
+
########################################################################
/** @addtogroup XBT_adt
#endif
/*-*-* end of debugging stuff *-*-*/
-/** @brief different kind of errors */
+/** @addtogroup XBT_ex_c
+ * @brief Exceptions support (C)
+ *
+ * Those fonctions are used to throw C++ exceptions from C code. This feature
+ * should probably be removed in the future because C and exception do not
+ * exactly play nicely together.
+ */
+
+/** Categories of errors
+ *
+ * This very similar to std::error_catgory and should probably be replaced
+ * by this in the future.
+ *
+ * @ingroup XBT_ex_c
+ */
typedef enum {
unknown_error = 0, /**< unknown error */
arg_error, /**< Invalid argument */
SG_BEGIN_DECL()
+/** Get the name of a category
+ * @ingroup XBT_ex_c
+ */
XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat);
typedef struct xbt_ex xbt_ex_t;
-XBT_PUBLIC(void) xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func) XBT_ATTRIB_NORETURN;
+/** Helper function used to throw exceptions in C */
+XBT_PUBLIC(void) _xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func) XBT_ATTRIB_NORETURN;
-/** @brief Builds and throws an exception
- @hideinitializer */
-#define THROW(c, v) { xbt_throw(NULL, (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__); }
+/** Builds and throws an exception
+ * @ingroup XBT_ex_c
+ * @hideinitializer
+ */
+#define THROW(c, v) { _xbt_throw(NULL, (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__); }
-/** @brief Builds and throws an exception with a printf-like formatted message
- @hideinitializer */
-#define THROWF(c, v, ...) xbt_throw(bprintf(__VA_ARGS__), (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__)
+/** Builds and throws an exception with a printf-like formatted message
+ * @ingroup XBT_ex_c
+ * @hideinitializer
+ */
+#define THROWF(c, v, ...) _xbt_throw(bprintf(__VA_ARGS__), (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__)
+/** Throw an exception because someting impossible happened
+ * @ingroup XBT_ex_c
+ */
#define THROW_IMPOSSIBLE \
THROWF(unknown_error, 0, "The Impossible Did Happen (yet again)")
+
+/** Throw an exception because someting unimplemented stuff has been attempted
+ * @ingroup XBT_ex_c
+ */
#define THROW_UNIMPLEMENTED \
THROWF(unknown_error, 0, "Function %s unimplemented",__func__)
+
+/** Throw an exception because some dead code was reached
+ * @ingroup XBT_ex_c
+ */
#define THROW_DEADCODE \
THROWF(unknown_error, 0, "Function %s was supposed to be DEADCODE, but it's not",__func__)
+/** Die because something impossible happened
+ * @ingroup XBT_ex_c
+ */
#define DIE_IMPOSSIBLE xbt_die("The Impossible Did Happen (yet again)")
-/** @brief The display made by an exception that is not catched */
+/** Display an exception */
XBT_PUBLIC(void) xbt_ex_display(xbt_ex_t * e);
SG_END_DECL()
#include <xbt/ex.h>
-/** (Deprecated) Generic exception
+/** A legacy exception
*
- * An error is defined by a category and a value within that category.
+ * It is defined by a category and a value within that category (as well as
+ * an optional error message).
*
* This used to be a structure for C exceptions but it has been retrofitted
* as a C++ exception and some of its data has been moved in the
- * WithContextException base class. We should deprecate it and replace it
+ * @ref WithContextException base class. We should deprecate it and replace it
* with either C++ different exceptions or `std::system_error` which already
* provides this (category + error code) logic.
+ *
+ * @ingroup XBT_ex_c
*/
struct XBT_PUBLIC() xbt_ex :
public std::runtime_error,
#include <xbt/misc.h> // xbt_procname
#include <xbt/virtu.h> // xbt_getpid
+/** @addtogroup XBT_ex
+ * @brief Exceptions support
+ */
+
namespace simgrid {
namespace xbt {
+/** A backtrace
+ *
+ * This is used (among other things) in exceptions to store the associated
+ * backtrace.
+ *
+ * @ingroup XBT_ex
+ */
typedef std::vector<xbt_backtrace_location_t> Backtrace;
+/** The location of where an exception has been throwed
+ *
+ * This is a tuple (__FILE__, __LINE__, __func__) and can be created with
+ * @ref XBT_THROW_POINT.
+ *
+ * @ingroup XBT_ex
+ */
struct ThrowPoint {
ThrowPoint() {}
ThrowPoint(const char* file, int line, const char* function) :
const char* function = nullptr;
};
-/** A polymorphic mixin class for adding context to an exception */
+/** Create a ThrowPoint with (__FILE__, __LINE__, __func__) */
+#define XBT_THROW_POINT ::simgrid::xbt::ThrowPoint(__FILE__, __LINE__, __func__)
+
+/** A base class for exceptions with context
+ *
+ * This is a base class for exceptions which store additional contextual
+ * infomations about them: backtrace, throw point, simulated process name
+ * and PID, etc.
+ *
+ * You are not expected to inherit from it. Instead of you use should
+ * @ref XBT_THROW an exception which will throw a subclass of your original
+ * exception with those additional features.
+ *
+ * However, you can try `dynamic_cast` an exception to this type in order to
+ * get contextual information about the exception.
+ */
XBT_PUBLIC_CLASS WithContextException {
public:
WithContextException() :
ThrowPoint throwpoint_;
};
-/** Internal class used to mixin the two classes */
+/** Internal class used to mixin an exception E with WithContextException */
template<class E>
class WithContext : public E, public WithContextException
{
public:
+
+ static_assert(!std::is_base_of<WithContextException,E>::value,
+ "Trying to appli WithContext twice");
+
WithContext(E exception) :
E(std::move(exception)) {}
WithContext(E exception, ThrowPoint throwpoint, Backtrace backtrace) :
~WithContext() override {}
};
-/** Throw a given exception a context
+/** Throw a C++ exception with some context
*
- * @param exception exception to throw
- * @param backtrace backtrace to attach
+ * @param e Exception to throw
+ * @ingroup XBT_ex
*/
-template<class E>
-[[noreturn]] inline
-typename std::enable_if< !std::is_base_of<WithContextException,E>::value >::type
-throwWithContext(
- E exception,
- // Thanks to the default argument, we are taking the backtrace in the caller:
- Backtrace backtrace = simgrid::xbt::backtrace())
-{
- throw WithContext<E>(std::move(exception), std::move(backtrace));
-}
-
-template<class E>
-[[noreturn]] inline
-typename std::enable_if< !std::is_base_of<WithContextException,E>::value >::type
-throwWithContext(
- E exception,
- ThrowPoint throwpoint,
- // Thanks to the default argument, we are taking the backtrace in the caller:
- Backtrace backtrace = simgrid::xbt::backtrace())
-{
- throw WithContext<E>(std::move(exception), throwpoint, std::move(backtrace));
-}
-
-#define XBT_THROW_POINT ::simgrid::xbt::ThrowPoint(__FILE__, __LINE__, __func__)
#define XBT_THROW(e) \
- ::simgrid::xbt::throwWithContext(std::move(e), XBT_THROW_POINT)
+ throw WithContext<E>(std::move(exception), throwpoint, simgrid::xbt::backtrace())
+
+/** Throw a C++ exception with a context and a nexted exception/cause
+ *
+ * @param e Exception to throw
+ * @ingroup XBT_ex
+ */
+#define XBT_THROW_NESTED(e) \
+ std::throw_with_nested(WithContext<E>(std::move(exception), throwpoint, simgrid::xbt::backtrace()))
}
}
/** Display informations about an exception
*
- * We display: the exception type, name, attached backtarces (if any) and
+ * We display: the exception type, name, attached backtraces (if any) and
* the nested exception (if any).
+ *
+ * @ingroup XBT_ex
*/
XBT_PUBLIC(void) logException(
e_xbt_log_priority_t priority,
#endif
-std::string string_vprintf(const char *fmt, va_list ap);
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+*/
std::string string_printf(const char *fmt, ...);
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+*/
+std::string string_vprintf(const char *fmt, va_list ap);
+
}
}
#endif
}
-void xbt_throw(
+void _xbt_throw(
char* message, xbt_errcat_t errcat, int value,
const char* file, int line, const char* func)
{