A simple little design-by-contract library to test out more advanced c++20 features. Looks like clang doesn't do std::source_location right. See https://github.com/llvm/llvm-project/issues/56379

master
Zed A. Shaw 7 months ago
parent 7bec6fe40e
commit c736387063
  1. 59
      PPP3/dbc.h
  2. 51
      PPP3/goc.cpp

@ -0,0 +1,59 @@
#include <string>
#include <source_location>
#include <fmt/core.h>
using namespace std;
namespace dbc {
class Error {
public:
const string message;
Error(string m) : message{m} {}
Error(const char *m) : message{m} {}
};
class CheckError : public Error {};
class SentinelError : public Error {};
class PreCondError : public Error {};
class PostCondError : public Error {};
void log(const string &message, std::source_location loc = std::source_location::current()) {
fmt::print("[{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), message);
}
void sentinel(const string &message, std::source_location loc = std::source_location::current()) {
string err = fmt::format("[SENTINEL! {}:{}:{}:{}] {}\n",
loc.file_name(), loc.function_name(),
loc.line(), loc.column(), message);
throw SentinelError{err};
}
void pre(const string &message, std::function<bool()> tester, std::source_location loc = std::source_location::current()) {
if(!tester()) {
string err = fmt::format("[PRE! {}:{}:{}:{}] {}\n",
loc.file_name(), loc.function_name(),
loc.line(), loc.column(), message);
throw PreCondError{err};
}
}
void post(const string &message, std::function<bool()> tester, std::source_location loc = std::source_location::current()) {
if(!tester()) {
string err = fmt::format("[POST! {}:{}:{}:{}] {}\n",
loc.file_name(), loc.function_name(),
loc.line(), loc.column(), message);
throw PostCondError{err};
}
}
void check(bool test, const string &message, std::source_location loc = std::source_location::current()) {
if(!test) {
string err = fmt::format("[CHECK! {}:{}:{}:{}] {}\n",
loc.file_name(), loc.function_name(),
loc.line(), loc.column(), message);
throw CheckError{err};
}
}
}

@ -5,34 +5,45 @@
#include <string>
#include <iterator>
#include <ctime>
#include "dbc.h"
using namespace std;
using namespace fmt;
int main()
{
regex err_re("(.*?):([0-9]+):([0-9]+):\\s*(.*?):\\s*(.*)");
string line;
smatch err;
ofstream stats_out;
stats_out.open("stats.csv", ios::out | ios::app);
auto t = time(nullptr);
auto tm = *std::gmtime(&t);
try {
regex err_re("(.*?):([0-9]+):([0-9]+):\\s*(.*?):\\s*(.*)");
string line;
smatch err;
ofstream stats_out;
stats_out.open("stats.csv", ios::out | ios::app);
auto t = time(nullptr);
auto tm = *std::gmtime(&t);
while(getline(cin, line)) {
print("{}\n", line);
if(regex_match(line, err, err_re)) {
string file_name = err[1].str();
string line = err[2].str();
string col = err[3].str();
string type = err[4].str();
string message = err[5].str();
dbc::log("TEST 1 of the logging thing");
dbc::check(stats_out.good(), "Error opening stats.csv file.");
dbc::pre("simple test", [&]() { return stats_out.good(); });
stats_out << put_time(&tm, "%FT%TZ");
stats_out << format(",{},{},{},{},{}\n", file_name, line, col, type, message);
while(getline(cin, line)) {
print("{}\n", line);
if(regex_match(line, err, err_re)) {
string file_name = err[1].str();
string line = err[2].str();
string col = err[3].str();
string type = err[4].str();
string message = err[5].str();
stats_out << put_time(&tm, "%FT%TZ");
stats_out << format(",{},{},{},{},{}\n", file_name, line, col, type, message);
}
}
}
stats_out.close();
return 0;
stats_out.close();
dbc::post("a post test", [&]() { return !stats_out.is_open(); });
return 0;
} catch(dbc::Error &err) {
print("ERROR: {}\n", err.message);
return 1;
}
}

Loading…
Cancel
Save