permanent and runtime assert
This commit is contained in:
parent
65b9af05d4
commit
425be0acad
@ -113,21 +113,61 @@ ExternalProject_Add(
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
|
||||
# fmtlib
|
||||
set(fmt_dir "${libs_dir}/fmt")
|
||||
set(fmt_tag "e5e4fb370ccf327bbdcdcd782eb3e53580e11094") # version 3.0.0
|
||||
ExternalProject_Add(
|
||||
fmt
|
||||
GIT_REPOSITORY "https://github.com/fmtlib/fmt.git"
|
||||
GIT_TAG "${fmt_tag}"
|
||||
SOURCE_DIR "${libs_dir}/fmt"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
ExternalProject_Get_Property(fmt source_dir)
|
||||
set(fmt_source_dir ${source_dir})
|
||||
ExternalProject_Get_Property(fmt binary_dir)
|
||||
set(fmt_binary_dir ${binary_dir})
|
||||
set(fmt_static_lib ${fmt_binary_dir}/fmt/libfmt.a)
|
||||
# message(STATUS "Fmt source dir is: ${fmt_source_dir}")
|
||||
# message(STATUS "fmt binary dir is: ${fmt_binary_dir}")
|
||||
# message(STATUS "fmt static lib is: ${fmt_static_lib}")
|
||||
|
||||
# compiler options
|
||||
SET(COMPILE_OPTIONS "-O0 -g3 -Wall -Werror -fmessage-length=0")
|
||||
|
||||
# add all cpp file recursive into sourceFiles varibale
|
||||
FILE(GLOB_RECURSE sourceFiles ${src_dir}/*.cpp)
|
||||
|
||||
# print list of source files
|
||||
# MESSAGE(STATUS "All source files are: ${sourceFiles}")
|
||||
|
||||
# defines
|
||||
option(RUNTIME_ASSERT "Enable runtime assertions" OFF)
|
||||
if(RUNTIME_ASSERT)
|
||||
add_definitions( -DRUNTIME_ASSERT_ON )
|
||||
endif()
|
||||
|
||||
option(THROW_EXCEPTION_ON_ERROR "Throw exception on error" OFF)
|
||||
if(THROW_EXCEPTION_ON_ERROR)
|
||||
add_definitions( -DTHROW_EXCEPTION_ON_ERROR )
|
||||
endif()
|
||||
|
||||
option(NDEBUG "No debug" OFF)
|
||||
if(NDEBUG)
|
||||
add_definitions( -DNDEBUG )
|
||||
endif()
|
||||
|
||||
# includes
|
||||
include_directories(${src_dir})
|
||||
include_directories(${lexertl_dir})
|
||||
include_directories(${fmt_source_dir})
|
||||
include_directories(${build_include_dir})
|
||||
|
||||
# creates build/libcypher_lib.a
|
||||
add_library(cypher_lib STATIC ${CMAKE_BINARY_DIR}/cypher.cpp)
|
||||
|
||||
# tests
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
|
@ -23,7 +23,7 @@ on a 64 bit linux kernel.
|
||||
## build
|
||||
```
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DRUNTIME_ASSERT=OFF -DTHROW_EXCEPTION_ON_ERROR=OFF -DNDEBUG=OFF ..
|
||||
make
|
||||
ctest
|
||||
ctest -V
|
||||
|
38
src/utils/assert.hpp
Normal file
38
src/utils/assert.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "exceptions/basic_exception.hpp"
|
||||
|
||||
// #define THROW_EXCEPTION_ON_ERROR
|
||||
// #define RUNTIME_ASSERT_ON
|
||||
|
||||
// handle assertion error
|
||||
void assert_error_handler(const char *file_name, unsigned line_number,
|
||||
const char *message)
|
||||
{
|
||||
// this is a good place to put your debug breakpoint
|
||||
// and add some other destination for error message
|
||||
#ifdef THROW_EXCEPTION_ON_ERROR
|
||||
throw BasicException(std::string(message));
|
||||
#else
|
||||
std::cerr << message << " in file " << file_name << " #" << line_number
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// parmanant exception will always be executed
|
||||
#define permanent_assert(condition, message) \
|
||||
if (!(condition)) { \
|
||||
std::ostringstream s; \
|
||||
s << message; \
|
||||
assert_error_handler(__FILE__, __LINE__, s.str().c_str()); \
|
||||
}
|
||||
|
||||
// runtime exception
|
||||
#ifdef RUNTIME_ASSERT_ON
|
||||
#define runtime_assert(condition, message) permanent_assert(condition, message)
|
||||
#else
|
||||
#define runtime_assert(condition, message)
|
||||
#endif
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cppformat/format.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "utils/auto_scope.hpp"
|
||||
#include "utils/stacktrace.hpp"
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdexcept>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include <cppformat/format.h>
|
||||
#include <fmt/format.h>
|
||||
#include "utils/auto_scope.hpp"
|
||||
|
||||
class Stacktrace
|
||||
|
@ -41,6 +41,7 @@ foreach(test ${unit_test_names})
|
||||
target_link_libraries(${test_name} stdc++fs)
|
||||
target_link_libraries(${test_name} cypher_lib)
|
||||
target_link_libraries(${test_name} Threads::Threads)
|
||||
target_link_libraries(${test_name} ${fmt_static_lib})
|
||||
add_test(NAME ${test_name} COMMAND ${test_name})
|
||||
set_property(TARGET ${test_name} PROPERTY CXX_STANDARD 14)
|
||||
endforeach()
|
||||
|
@ -1,17 +1,18 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "data_structures/skiplist/skiplist.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using skiplist_t = SkipList<int, int>;
|
||||
|
||||
void print_skiplist(const skiplist_t::Accessor& skiplist)
|
||||
void print_skiplist(const skiplist_t::Accessor &skiplist)
|
||||
{
|
||||
cout << "---- skiplist now has: ";
|
||||
|
||||
for(auto& kv : skiplist)
|
||||
for (auto &kv : skiplist)
|
||||
cout << "(" << kv.first << ", " << kv.second << ") ";
|
||||
|
||||
cout << "----" << endl;
|
||||
@ -23,36 +24,44 @@ int main(void)
|
||||
auto accessor = skiplist.access();
|
||||
|
||||
// insert 10
|
||||
assert(accessor.insert_unique(1, 10).second == true);
|
||||
|
||||
permanent_assert(accessor.insert_unique(1, 10).second == true,
|
||||
"add first element");
|
||||
|
||||
// try insert 10 again (should fail)
|
||||
assert(accessor.insert_unique(1, 10).second == false);
|
||||
permanent_assert(accessor.insert_unique(1, 10).second == false,
|
||||
"add the same element, should fail");
|
||||
|
||||
// insert 20
|
||||
assert(accessor.insert_unique(2, 20).second == true);
|
||||
permanent_assert(accessor.insert_unique(2, 20).second == true,
|
||||
"insert new unique element");
|
||||
|
||||
print_skiplist(accessor);
|
||||
|
||||
|
||||
// value at key 3 shouldn't exist
|
||||
assert((accessor.find(3) == accessor.end()) == true);
|
||||
permanent_assert((accessor.find(3) == accessor.end()) == true,
|
||||
"try to find element which doesn't exist");
|
||||
|
||||
// value at key 2 should exist
|
||||
assert((accessor.find(2) != accessor.end()) == true);
|
||||
permanent_assert((accessor.find(2) != accessor.end()) == true,
|
||||
"find iterator");
|
||||
|
||||
// at key 2 is 20 (true)
|
||||
assert(accessor.find(2)->second == 20);
|
||||
|
||||
permanent_assert(accessor.find(2)->second == 20, "find element");
|
||||
|
||||
// removed existing (1)
|
||||
assert(accessor.remove(1) == true);
|
||||
permanent_assert(accessor.remove(1) == true, "try to remove element");
|
||||
|
||||
// removed non-existing (3)
|
||||
assert(accessor.remove(3) == false);
|
||||
permanent_assert(accessor.remove(3) == false,
|
||||
"try to remove element which doesn't exist");
|
||||
|
||||
// insert (1, 10)
|
||||
assert(accessor.insert_unique(1, 10).second == true);
|
||||
permanent_assert(accessor.insert_unique(1, 10).second == true,
|
||||
"insert unique element");
|
||||
|
||||
// insert (4, 40)
|
||||
assert(accessor.insert_unique(4, 40).second == true);
|
||||
permanent_assert(accessor.insert_unique(4, 40).second == true,
|
||||
"insert unique element");
|
||||
|
||||
print_skiplist(accessor);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user