mdbx++: Implements std::ostream << operators.

Change-Id: Iec4b6fc0344e3d3f3ff665ce28e23c2f315d8bdb
This commit is contained in:
Leonid Yuriev 2020-09-01 01:59:21 +03:00
parent 62be36cc9e
commit baeca4109a
2 changed files with 247 additions and 130 deletions

View File

@ -1261,16 +1261,31 @@ public:
//----------------------------------------------------------------------------
struct LIBMDBX_API_TYPE geometry {
enum : intptr_t {
enum : int64_t {
default_value = -1,
minimal_value = 0,
maximal_value = INTPTR_MAX,
KiB = intptr_t(1) << 10,
MiB = intptr_t(1) << 20,
/* TODO: enable for 64-bit builds only
GiB = intptr_t(1) << 30,
TiB = intptr_t(1) << 40, */
kB = 1000, ///< \f$10^{3}\f$ bytes
MB = kB * 1000, ///< \f$10^{6}\f$ bytes
GB = MB * 1000, ///< \f$10^{9}\f$ bytes
TB = GB * 1000, ///< \f$10^{12}\f$ bytes
PB = TB * 1000, ///< \f$10^{15}\f$ bytes
EB = PB * 1000, ///< \f$10^{18}\f$ bytes
KiB = 1024, ///< \f$2^{10}\f$ bytes
MiB = KiB << 10, ///< \f$2^{20}\f$ bytes
GiB = MiB << 10, ///< \f$2^{30}\f$ bytes
TiB = GiB << 10, ///< \f$2^{40}\f$ bytes
PiB = TiB << 10, ///< \f$2^{50}\f$ bytes
EiB = PiB << 10, ///< \f$2^{60}\f$ bytes
};
/// Tagged type for output to std::ostream
struct size {
intptr_t bytes;
constexpr size(intptr_t bytes) noexcept : bytes(bytes) {}
operator intptr_t() const noexcept { return bytes; }
};
intptr_t size_lower{minimal_value};
intptr_t size_now{default_value};
intptr_t size_upper{maximal_value};
@ -1800,9 +1815,14 @@ LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const ::mdbx::slice &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const ::mdbx::pair &);
template <class ALLOCATOR>
inline ::std::ostream &operator<<(::std::ostream &out,
const ::mdbx::buffer<ALLOCATOR> &) {
return out << "FIXME: " << __func__ << ", " __FILE__ ":" << __LINE__;
const ::mdbx::buffer<ALLOCATOR> &it) {
return (it.is_freestanding()
? out << "buf-" << it.headroom() << "." << it.tailroom()
: out << "ref-")
<< it.ref();
}
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const ::mdbx::env_ref::geometry::size &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const ::mdbx::env_ref::geometry &);
LIBMDBX_API ::std::ostream &
@ -1822,21 +1842,11 @@ LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_log_level_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_debug_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const MDBX_error_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_env_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_txn_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_db_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_put_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_copy_flags_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_cursor_op &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_dbi_state_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const ::mdbx::error &);
inline ::std::ostream &operator<<(::std::ostream &out,
const MDBX_error_t &errcode) {
return out << ::mdbx::error(errcode);
}
} // namespace mdbx
@ -1872,14 +1882,10 @@ LIBMDBX_API string to_string(const ::mdbx::env_ref::create_parameters &);
LIBMDBX_API string to_string(const ::MDBX_log_level_t &);
LIBMDBX_API string to_string(const ::MDBX_debug_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_error_t &);
LIBMDBX_API string to_string(const ::MDBX_env_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_txn_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_db_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_put_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_copy_flags_t &);
LIBMDBX_API string to_string(const ::MDBX_cursor_op &);
LIBMDBX_API string to_string(const ::MDBX_dbi_state_t &);
LIBMDBX_API string to_string(const ::mdbx::error &);
inline string to_string(const ::MDBX_error_t &errcode) {
return to_string(::mdbx::error(errcode));
}
} // namespace std

View File

@ -140,6 +140,7 @@ public:
//------------------------------------------------------------------------------
#if 0 /* Unused for now */
__cold std::string format_va(const char *fmt, va_list ap) {
va_list ones;
va_copy(ones, ap);
@ -210,6 +211,8 @@ __cold bug::~bug() noexcept {}
#define NOT_IMPLEMENTED() \
RAISE_BUG(__LINE__, "not_implemented", __func__, __FILE__);
#endif /* Unused*/
//------------------------------------------------------------------------------
template <typename PATH> struct path_to_pchar {
@ -1269,86 +1272,236 @@ cursor::~cursor() noexcept { ::mdbx_cursor_close(handle_); }
//------------------------------------------------------------------------------
__cold ::std::ostream &operator<<(::std::ostream &, const slice &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out, const slice &it) {
out << "{";
if (!it.is_valid())
out << "INVALID." << it.length();
else if (it.is_null())
out << "NULL";
else if (it.empty())
out << "EMPTY->" << it.data();
else {
const slice root(it.head(std::min(it.length(), size_t(64))));
out << it.length() << "->"
<< (root.is_printable() ? root.string() : root.base58_encode())
<< ((root == it) ? "" : "...");
}
return out << "}";
}
__cold ::std::ostream &operator<<(::std::ostream &, const pair &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out, const pair &it) {
return out << "{" << it.key << " => " << it.value << "}";
}
__cold ::std::ostream &operator<<(::std::ostream &, const env_ref::geometry &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const ::mdbx::env_ref::geometry::size &it) {
switch (it.bytes) {
case ::mdbx::env_ref::geometry::default_value:
return out << "default";
case ::mdbx::env_ref::geometry::minimal_value:
return out << "minimal";
case ::mdbx::env_ref::geometry::maximal_value:
return out << "maximal";
}
const auto bytes = (it.bytes < 0) ? out << "-",
size_t(-it.bytes) : size_t(it.bytes);
struct {
size_t one;
const char *suffix;
} static const scales[] = {
#if MDBX_WORDBITS > 32
{env::geometry::EiB, "EiB"},
{env::geometry::EB, "EB"},
{env::geometry::PiB, "PiB"},
{env::geometry::PB, "PB"},
{env::geometry::TiB, "TiB"},
{env::geometry::TB, "TB"},
#endif
{env::geometry::GiB, "GiB"},
{env::geometry::GB, "GB"},
{env::geometry::MiB, "MiB"},
{env::geometry::MB, "MB"},
{env::geometry::KiB, "KiB"},
{env::geometry::kB, "kB"},
{1, " bytes"}
};
for (const auto i : scales)
if (bytes % i.one == 0)
return out << bytes / i.one << i.suffix;
assert(false);
__unreachable();
return out;
}
__cold ::std::ostream &operator<<(::std::ostream &,
const env_ref::operate_parameters &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::geometry &it) {
return //
out << "\tlower " << env_ref::geometry::size(it.size_lower) //
<< ",\n\tnow " << env_ref::geometry::size(it.size_now) //
<< ",\n\tupper " << env_ref::geometry::size(it.size_upper) //
<< ",\n\tgrowth " << env_ref::geometry::size(it.growth_step) //
<< ",\n\tshrink " << env_ref::geometry::size(it.shrink_threshold) //
<< ",\n\tpagesize " << env_ref::geometry::size(it.pagesize) << "\n";
}
__cold ::std::ostream &operator<<(::std::ostream &, const env_ref::mode &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::operate_parameters &it) {
return out << "{\n" //
<< "\tmax_maps " << it.max_maps //
<< ",\n\tmax_readers " << it.max_readers //
<< ",\n\tmode " << it.mode //
<< ",\n\tdurability " << it.durability //
<< ",\n\treclaiming " << it.reclaiming //
<< ",\n\toptions " << it.options //
<< "\n}";
}
__cold ::std::ostream &operator<<(::std::ostream &,
const env_ref::durability &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::mode &it) {
switch (it) {
case env_ref::mode::readonly:
return out << "readonly";
case env_ref::mode::write_file_io:
return out << "write_file_io";
case env_ref::mode::write_mapped_io:
return out << "write_mapped_io";
default:
return out << "mdbx::env::mode::invalid";
}
}
__cold ::std::ostream &operator<<(::std::ostream &,
const env_ref::reclaiming_options &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::durability &it) {
switch (it) {
case env_ref::durability::robust_synchronous:
return out << "robust_synchronous";
case env_ref::durability::half_synchronous_weak_last:
return out << "half_synchronous_weak_last";
case env_ref::durability::lazy_weak_tail:
return out << "lazy_weak_tail";
case env_ref::durability::whole_fragile:
return out << "whole_fragile";
default:
return out << "mdbx::env::durability::invalid";
}
}
__cold ::std::ostream &operator<<(::std::ostream &,
const env_ref::operate_options &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::reclaiming_options &it) {
return out << "{" //
<< "lifo: " << (it.lifo ? "yes" : "no") //
<< ", coalesce: " << (it.coalesce ? "yes" : "no") //
<< "}";
}
__cold ::std::ostream &operator<<(::std::ostream &,
const env_ref::create_parameters &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::operate_options &it) {
static const char comma[] = ", ";
const char *delimiter = "";
out << "{";
if (it.orphan_read_transactions) {
out << delimiter << "orphan_read_transactions";
delimiter = comma;
}
if (it.nested_write_transactions) {
out << delimiter << "nested_write_transactions";
delimiter = comma;
}
if (it.exclusive) {
out << delimiter << "exclusive";
delimiter = comma;
}
if (it.disable_readahead) {
out << delimiter << "disable_readahead";
delimiter = comma;
}
if (it.disable_clear_memory) {
out << delimiter << "disable_clear_memory";
delimiter = comma;
}
if (delimiter != comma)
out << "default";
return out << "}";
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_log_level_t &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::create_parameters &it) {
return out << "{\n" //
<< "\tfile_mode " << std::oct << it.file_mode_bits << std::dec //
<< ",\n\tsubdirectory " << (it.use_subdirectory ? "yes" : "no") //
<< ",\n"
<< it.geometry << "}";
}
__cold ::std::ostream &operator<<(::std::ostream &,
const MDBX_debug_flags_t &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const MDBX_log_level_t &it) {
switch (it) {
case MDBX_LOG_FATAL:
return out << "LOG_FATAL";
case MDBX_LOG_ERROR:
return out << "LOG_ERROR";
case MDBX_LOG_WARN:
return out << "LOG_WARN";
case MDBX_LOG_NOTICE:
return out << "LOG_NOTICE";
case MDBX_LOG_VERBOSE:
return out << "LOG_VERBOSE";
case MDBX_LOG_DEBUG:
return out << "LOG_DEBUG";
case MDBX_LOG_TRACE:
return out << "LOG_TRACE";
case MDBX_LOG_EXTRA:
return out << "LOG_EXTRA";
case MDBX_LOG_DONTCHANGE:
return out << "LOG_DONTCHANGE";
default:
return out << "mdbx::log_level::invalid";
}
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_error_t &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const MDBX_debug_flags_t &it) {
if (it == MDBX_DBG_DONTCHANGE)
return out << "DBG_DONTCHANGE";
static const char comma[] = "|";
const char *delimiter = "";
out << "{";
if (it & MDBX_DBG_ASSERT) {
out << delimiter << "DBG_ASSERT";
delimiter = comma;
}
if (it & MDBX_DBG_AUDIT) {
out << delimiter << "DBG_AUDIT";
delimiter = comma;
}
if (it & MDBX_DBG_JITTER) {
out << delimiter << "DBG_JITTER";
delimiter = comma;
}
if (it & MDBX_DBG_DUMP) {
out << delimiter << "DBG_DUMP";
delimiter = comma;
}
if (it & MDBX_DBG_LEGACY_MULTIOPEN) {
out << delimiter << "DBG_LEGACY_MULTIOPEN";
delimiter = comma;
}
if (it & MDBX_DBG_LEGACY_OVERLAP) {
out << delimiter << "DBG_LEGACY_OVERLAP";
delimiter = comma;
}
if (delimiter != comma)
out << "DBG_NONE";
return out << "}";
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_env_flags_t &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_txn_flags_t &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_db_flags_t &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_put_flags_t &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_copy_flags_t &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_cursor_op &) {
NOT_IMPLEMENTED();
}
__cold ::std::ostream &operator<<(::std::ostream &, const MDBX_dbi_state_t &) {
NOT_IMPLEMENTED();
__cold ::std::ostream &operator<<(::std::ostream &out,
const ::mdbx::error &err) {
return out << err.what() << " (" << long(err.code()) << ")";
}
} // namespace mdbx
@ -1423,49 +1576,7 @@ __cold string to_string(const MDBX_debug_flags_t &value) {
return out.str();
}
__cold string to_string(const MDBX_error_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_env_flags_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_txn_flags_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_db_flags_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_put_flags_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_copy_flags_t &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_cursor_op &value) {
ostringstream out;
out << value;
return out.str();
}
__cold string to_string(const MDBX_dbi_state_t &value) {
__cold string to_string(const ::mdbx::error &value) {
ostringstream out;
out << value;
return out.str();