Add assert check for uninitialised delegate call

This commit is contained in:
John Wellbelove 2019-11-04 12:27:16 +00:00
parent 8340d28b37
commit c0ca7c9d87
9 changed files with 57 additions and 5 deletions

View File

@ -49,13 +49,44 @@ Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibl
#define ETL_DELEGATE_INCLUDED
#include "platform.h"
#include "error_handler.h"
#include "exception.h"
#if ETL_CPP11_SUPPORTED == 0
#error NOT SUPPORTED FOR C++03 OR BELOW
#endif
#undef ETL_FILE
#define ETL_FILE "51"
namespace etl
{
//***************************************************************************
/// The base class for delegate exceptions.
//***************************************************************************
class delegate_exception : public exception
{
public:
delegate_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
/// The exception thrown when the delegate is uninitialised.
//***************************************************************************
class delegate_uninitialised : public delegate_exception
{
public:
delegate_uninitialised(string_type file_name_, numeric_type line_number_)
: delegate_exception(ETL_ERROR_TEXT("delegate:uninitialised", ETL_FILE"A"), file_name_, line_number_)
{
}
};
template <typename T> class delegate;
template <typename TReturn, typename... TParams>
@ -166,6 +197,8 @@ namespace etl
//*************************************************************************
TReturn operator()(TParams... args) const
{
ETL_ASSERT(invocation.stub != nullptr, ETL_ERROR(delegate_uninitialised));
return (*invocation.stub)(invocation.object, args...);
}
@ -353,4 +386,6 @@ namespace etl
};
}
#undef ETL_FILE
#endif

View File

@ -122,24 +122,31 @@ namespace etl
//***************************************************************************
#if defined(ETL_NO_CHECKS)
#define ETL_ASSERT(b, e) // Does nothing.
#define ETL_ALWAYS_ASSERT(e) // Does nothing.
#elif defined(ETL_THROW_EXCEPTIONS)
#if defined(ETL_LOG_ERRORS)
#define ETL_ASSERT(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
#else
#define ETL_ASSERT(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
#define ETL_ALWAYS_ASSERT(e) {throw((e));} // Throws an exception.
#endif
#else
#if defined(ETL_LOG_ERRORS)
#if defined(NDEBUG)
#define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));}} // If the condition fails, calls the error handler
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e));} // Calls the error handler
#else
#define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));} assert((b));} // If the condition fails, calls the error handler then asserts.
#define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e)); assert((b));}} // If the condition fails, calls the error handler then asserts.
#define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e)); assert(true);} // Calls the error handler then asserts.
#endif
#else
#if defined(NDEBUG)
#define ETL_ASSERT(b, e) // Does nothing.
#define ETL_ALWAYS_ASSERT(e) // Does nothing.
#else
#define ETL_ASSERT(b, e) assert((b)) // If the condition fails, asserts.
#define ETL_ALWAYS_ASSERT(e) assert(true) // Asserts.
#endif
#endif
#endif

View File

@ -47,4 +47,5 @@
47 queue_spsc_atomic
48 queue_mpmc_mutex
49 type_select
50 binary
50 binary
51 delegate

View File

@ -39,7 +39,7 @@ SOFTWARE.
#define ETL_VERSION_MAJOR 14
#define ETL_VERSION_MINOR 35
#define ETL_VERSION_PATCH 2
#define ETL_VERSION_PATCH 3
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH)

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library",
"version": "14.35.2",
"version": "14.35.3",
"authors": {
"name": "John Wellbelove",
"email": "<john.wellbelove@etlcpp.com>"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=14.35.2
version=14.35.3
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -1,3 +1,7 @@
===============================================================================
14.35.3
Added assert when calling uninitialised delegate.
===============================================================================
14.35.2
Fixed incorrect result when rounding up to integral part.

View File

@ -27,6 +27,7 @@ SOFTWARE.
******************************************************************************/
#include "UnitTest++.h"
#include "ExtraCheckMacros.h"
#include "etl/delegate.h"
@ -167,6 +168,8 @@ namespace
CHECK(!d.is_valid());
CHECK(!d);
CHECK_THROW(d(), etl::delegate_uninitialised);
}
//*************************************************************************
@ -176,6 +179,7 @@ namespace
CHECK(d.is_valid());
CHECK(d);
CHECK_NO_THROW(d());
}
//*************************************************************************

View File

@ -0,0 +1 @@
*.idb