Create a gist now

Instantly share code, notes, and snippets.

@nutbread /Assert.cpp Secret
Last active Aug 29, 2015

Embed
What would you like to do?
Improved, modifiable C++11 assertions with message capability
#include <iostream>
#include "Assert.hpp"
namespace assertions {
void
Assertion :: assert_internal(
flags_int flags,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line,
ArgsFunction fn
) {
Stream& stream = ::std::cerr;
stream << "Assertion failed:\n";
stream << " " << condition_string << "\n";
if (fn) {
stream << " message: ";
fn(stream);
stream << "\n";
}
stream << " file: " << file << "\n";
stream << " base_file: " << base_file << "\n";
stream << " function: " << function << "\n";
stream << " line: " << line << "\n";
stream << "-------------------------------\n";
// Breakpoint
exit(0xBAD);
}
void
Assertion :: assert_wrapper(
flags_int flags,
bool condition,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line
) {
if (condition) return;
assert_internal(flags, condition_string, file, base_file, function, line, nullptr);
}
}
#ifndef ___H_ASSERT
#define ___H_ASSERT
#include <functional>
#include <iostream>
#ifndef ASSERTIONS_ENABLED
#ifdef NDEBUG
#define ASSERTIONS_ENABLED 0
#else
#define ASSERTIONS_ENABLED 1
#endif
#endif
#if ASSERTIONS_ENABLED
#define ASSERTIONS_ENABLED 1
#define assert(condition, ...) \
::assertions::Assertion::assert_wrapper(0x0, condition, #condition, __FILE__, __BASE_FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define ASSERTIONS_ENABLED 0
#define assert(condition, ...)
#endif
namespace assertions {
class Assertion {
public:
typedef unsigned int flags_int;
typedef int line_int;
private:
typedef unsigned int argument_int;
typedef ::std::ostream Stream;
typedef ::std::function<void(Stream&)> ArgsFunction;
Assertion() = delete;
~Assertion() = delete;
template <typename Type1>
static void
args_loop(
Stream& stream,
argument_int argument_number,
Type1 arg1
);
template <typename Type1, typename... Types>
static void
args_loop(
Stream& stream,
argument_int argument_number,
Type1 arg1,
Types... args
);
static void
assert_internal(
flags_int flags,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line,
ArgsFunction fn
);
public:
static void
assert_wrapper(
flags_int flags,
bool condition,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line
);
template <typename... Types>
static void
assert_wrapper(
flags_int flags,
bool condition,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line,
Types... args
);
};
}
#include "Assert.t.hpp"
#endif // ___H_ASSERT
namespace assertions {
template <typename Type1>
void
Assertion :: args_loop(
Stream& stream,
argument_int argument_number,
Type1 arg1
) {
stream << arg1;
}
template <typename Type1, typename... Types>
void
Assertion :: args_loop(
Stream& stream,
argument_int argument_number,
Type1 arg1,
Types... args
) {
args_loop(stream, argument_number, arg1);
args_loop(stream, argument_number + 1, args...);
}
template <typename... Types>
void
Assertion :: assert_wrapper(
flags_int flags,
bool condition,
const char* condition_string,
const char* file,
const char* base_file,
const char* function,
line_int line,
Types... args
) {
if (condition) return;
auto fn = [&args...](Stream& stream){
args_loop(stream, 0, args...);
};
assert_internal(flags, condition_string, file, base_file, function, line, fn);
}
}
// cls && g++ -std=c++11 -o Assert.test.exe Assert.test.cpp Assert.cpp && Assert.test.exe 2
#include "Assert.hpp"
int main(int argc, char** argv) {
if (argc <= 1) {
assert(false == true);
}
else {
assert(false == true, 1, 1, " ", "ASDF");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment