xo-indentlog xo-arena: improve verify_ok logging workflow
+ scope.retroactively_enable()
This commit is contained in:
parent
cd8d6a2f67
commit
67552d90bd
3 changed files with 105 additions and 25 deletions
|
|
@ -6,12 +6,50 @@
|
|||
#pragma once
|
||||
|
||||
#include "DArenaVector.hpp"
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
|
||||
namespace xo {
|
||||
struct verify_policy {
|
||||
static verify_policy log_only() {
|
||||
return verify_policy{.flags_ = 0x01};
|
||||
}
|
||||
static verify_policy throw_only() {
|
||||
return verify_policy{.flags_ = 0x02};
|
||||
}
|
||||
static verify_policy chatty() {
|
||||
return verify_policy{.flags_ = 0x03};
|
||||
}
|
||||
|
||||
bool is_silent() const noexcept { return flags_ == 0; }
|
||||
bool log_flag() const noexcept { return flags_ & 0x01; }
|
||||
bool throw_flag() const noexcept { return flags_ & 0x02; }
|
||||
|
||||
template<typename... Tn>
|
||||
bool report_error(scope & log, Tn&&... args)
|
||||
{
|
||||
if (!this->is_silent()) {
|
||||
// TODO: consider global arena here for string
|
||||
std::string msg = tostr(std::forward<Tn>(args)...);
|
||||
|
||||
if (this->log_flag()) {
|
||||
log.retroactively_enable();
|
||||
log(msg);
|
||||
}
|
||||
if (this->throw_flag()) {
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * c_self_ = "anonymous";
|
||||
uint8_t flags_;
|
||||
};
|
||||
|
||||
namespace mm {
|
||||
#ifdef NOT_YET
|
||||
enum class insert_error : int32_t {
|
||||
|
|
@ -169,7 +207,7 @@ namespace xo {
|
|||
**/
|
||||
std::pair<value_type *, bool> try_insert(const std::pair<const Key, Value> & kv_pair);
|
||||
|
||||
bool verify_ok(bool /*throw_flag_not_implemented*/ = true) const;
|
||||
bool verify_ok(verify_policy p = verify_policy::throw_only()) const;
|
||||
|
||||
private:
|
||||
/** load group abstraction from control bytes starting at @p ix **/
|
||||
|
|
@ -382,8 +420,23 @@ namespace xo {
|
|||
**/
|
||||
template <typename Key, typename Value, typename Hash, typename Equal>
|
||||
bool
|
||||
DArenaHashMap<Key, Value, Hash, Equal>::verify_ok(bool /*throw_flag_not_implemented*/) const
|
||||
DArenaHashMap<Key, Value, Hash, Equal>::verify_ok(verify_policy policy) const
|
||||
{
|
||||
using xo::scope;
|
||||
using xo::tostr;
|
||||
using xo::xtag;
|
||||
|
||||
constexpr const char * c_self = "DArenaHashMap::verify_ok";
|
||||
scope log(XO_DEBUG(debug_flag_), xtag("size", size_));
|
||||
|
||||
/* SM1.1: size_ <= n_slot_ */
|
||||
if (size_ > n_slot_) {
|
||||
return policy.report_error(log,
|
||||
c_self, ": expect .size < .n_slot",
|
||||
xtag("size", size_),
|
||||
xtag("n_slot", n_slot_));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,9 @@ namespace utest {
|
|||
|
||||
xo::scope log(XO_DEBUG(catch_flag), xtag("lo", lo), xtag("hi", hi), xtag("k", k));
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, p_map->verify_ok(catch_flag));
|
||||
auto policy = xo::verify_policy::chatty();
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, p_map->verify_ok(policy));
|
||||
|
||||
if ((hi <= lo) || (k == 0))
|
||||
return true;
|
||||
|
|
@ -223,7 +225,7 @@ namespace utest {
|
|||
*/
|
||||
auto insert_result = p_map->try_insert(typename HashMap::value_type(x, 10 * x));
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, p_map->verify_ok(catch_flag));
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, p_map->verify_ok(policy));
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, insert_result.second);
|
||||
|
||||
|
|
|
|||
|
|
@ -171,10 +171,27 @@ namespace xo {
|
|||
return true;
|
||||
} /*log*/
|
||||
|
||||
/** re-enable + log (args...).
|
||||
* No-op if scope already enabled.
|
||||
* Useful in verify_ok() methods, to conditionally enable
|
||||
* logging only when a test fails
|
||||
**/
|
||||
template<typename... Tn>
|
||||
void retroactively_enable(Tn&&... args) {
|
||||
if (finalized_) {
|
||||
this->finalized_ = false;
|
||||
this->begin_scope(std::forward<Tn>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
/** Log argument in pack @p args **/
|
||||
template<typename... Tn>
|
||||
bool operator()(Tn&&... args) { return this->log(std::forward<Tn>(args)...); }
|
||||
|
||||
/** If enabled, writes initial banner **/
|
||||
template<typename... Tn>
|
||||
void begin_scope(Tn&&... args);
|
||||
|
||||
/** Optionally, call once to end scope before dtor.
|
||||
* Logs arguments in pack @p args
|
||||
**/
|
||||
|
|
@ -231,27 +248,7 @@ namespace xo {
|
|||
line_{setup.line_},
|
||||
finalized_{!(setup.is_enabled())}
|
||||
{
|
||||
if(setup.is_enabled()) {
|
||||
state_impl_type * logstate = basic_scope::require_thread_local_state();
|
||||
std::ostream & os = logstate2stream(logstate);
|
||||
|
||||
logstate->preamble(this->style_, this->name1_, this->name2_);
|
||||
|
||||
tosn(os, " ", std::forward<Tn>(args)...);
|
||||
|
||||
if (log_config::location_enabled) {
|
||||
/* prints on next call to flush2sbuf */
|
||||
logstate->set_location(this->file_, this->line_);
|
||||
//tosn(os, " [", basename(this->file_), ":", this->line_, "]");
|
||||
}
|
||||
|
||||
logstate->flush2sbuf(std::clog.rdbuf());
|
||||
|
||||
///* next call to scope::log() can reset to beginning of buffer space */
|
||||
//logstate->ss().seekp(0);
|
||||
|
||||
logstate->incr_nesting();
|
||||
}
|
||||
this->begin_scope(std::forward<Tn>(args)...);
|
||||
} /*ctor*/
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
|
|
@ -314,6 +311,34 @@ namespace xo {
|
|||
logstate->flush2sbuf(this->dest_sbuf_);
|
||||
} /*flush2sbuf*/
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
template <typename... Tn>
|
||||
void
|
||||
basic_scope<CharT, Traits>::begin_scope(Tn&&... args)
|
||||
{
|
||||
if(this->enabled()) {
|
||||
state_impl_type * logstate = basic_scope::require_thread_local_state();
|
||||
std::ostream & os = logstate2stream(logstate);
|
||||
|
||||
logstate->preamble(this->style_, this->name1_, this->name2_);
|
||||
|
||||
tosn(os, " ", std::forward<Tn>(args)...);
|
||||
|
||||
if (log_config::location_enabled) {
|
||||
/* prints on next call to flush2sbuf */
|
||||
logstate->set_location(this->file_, this->line_);
|
||||
//tosn(os, " [", basename(this->file_), ":", this->line_, "]");
|
||||
}
|
||||
|
||||
logstate->flush2sbuf(std::clog.rdbuf());
|
||||
|
||||
///* next call to scope::log() can reset to beginning of buffer space */
|
||||
//logstate->ss().seekp(0);
|
||||
|
||||
logstate->incr_nesting();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
template <typename... Tn>
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue