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 { struct LIBMDBX_API_TYPE geometry {
enum : intptr_t { enum : int64_t {
default_value = -1, default_value = -1,
minimal_value = 0, minimal_value = 0,
maximal_value = INTPTR_MAX, maximal_value = INTPTR_MAX,
KiB = intptr_t(1) << 10, kB = 1000, ///< \f$10^{3}\f$ bytes
MiB = intptr_t(1) << 20, MB = kB * 1000, ///< \f$10^{6}\f$ bytes
/* TODO: enable for 64-bit builds only GB = MB * 1000, ///< \f$10^{9}\f$ bytes
GiB = intptr_t(1) << 30, TB = GB * 1000, ///< \f$10^{12}\f$ bytes
TiB = intptr_t(1) << 40, */ 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_lower{minimal_value};
intptr_t size_now{default_value}; intptr_t size_now{default_value};
intptr_t size_upper{maximal_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 &); LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const ::mdbx::pair &);
template <class ALLOCATOR> template <class ALLOCATOR>
inline ::std::ostream &operator<<(::std::ostream &out, inline ::std::ostream &operator<<(::std::ostream &out,
const ::mdbx::buffer<ALLOCATOR> &) { const ::mdbx::buffer<ALLOCATOR> &it) {
return out << "FIXME: " << __func__ << ", " __FILE__ ":" << __LINE__; 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 &, LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const ::mdbx::env_ref::geometry &); const ::mdbx::env_ref::geometry &);
LIBMDBX_API ::std::ostream & LIBMDBX_API ::std::ostream &
@ -1822,21 +1842,11 @@ LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_log_level_t &); const MDBX_log_level_t &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
const MDBX_debug_flags_t &); 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::error &);
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, inline ::std::ostream &operator<<(::std::ostream &out,
const MDBX_env_flags_t &); const MDBX_error_t &errcode) {
LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, return out << ::mdbx::error(errcode);
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 &);
} // namespace mdbx } // 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_log_level_t &);
LIBMDBX_API string to_string(const ::MDBX_debug_flags_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::error &);
LIBMDBX_API string to_string(const ::MDBX_env_flags_t &); inline string to_string(const ::MDBX_error_t &errcode) {
LIBMDBX_API string to_string(const ::MDBX_txn_flags_t &); return to_string(::mdbx::error(errcode));
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 &);
} // namespace std } // 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) { __cold std::string format_va(const char *fmt, va_list ap) {
va_list ones; va_list ones;
va_copy(ones, ap); va_copy(ones, ap);
@ -210,6 +211,8 @@ __cold bug::~bug() noexcept {}
#define NOT_IMPLEMENTED() \ #define NOT_IMPLEMENTED() \
RAISE_BUG(__LINE__, "not_implemented", __func__, __FILE__); RAISE_BUG(__LINE__, "not_implemented", __func__, __FILE__);
#endif /* Unused*/
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <typename PATH> struct path_to_pchar { 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out, const slice &it) {
NOT_IMPLEMENTED(); 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out, const pair &it) {
NOT_IMPLEMENTED(); return out << "{" << it.key << " => " << it.value << "}";
} }
__cold ::std::ostream &operator<<(::std::ostream &, const env_ref::geometry &) { __cold ::std::ostream &operator<<(::std::ostream &out,
NOT_IMPLEMENTED(); 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 &, __cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::operate_parameters &) { const env_ref::geometry &it) {
NOT_IMPLEMENTED(); 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out,
NOT_IMPLEMENTED(); 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 &, __cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::durability &) { const env_ref::mode &it) {
NOT_IMPLEMENTED(); 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 &, __cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::reclaiming_options &) { const env_ref::durability &it) {
NOT_IMPLEMENTED(); 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 &, __cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::operate_options &) { const env_ref::reclaiming_options &it) {
NOT_IMPLEMENTED(); return out << "{" //
<< "lifo: " << (it.lifo ? "yes" : "no") //
<< ", coalesce: " << (it.coalesce ? "yes" : "no") //
<< "}";
} }
__cold ::std::ostream &operator<<(::std::ostream &, __cold ::std::ostream &operator<<(::std::ostream &out,
const env_ref::create_parameters &) { const env_ref::operate_options &it) {
NOT_IMPLEMENTED(); 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out,
NOT_IMPLEMENTED(); 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 &, __cold ::std::ostream &operator<<(::std::ostream &out,
const MDBX_debug_flags_t &) { const MDBX_log_level_t &it) {
NOT_IMPLEMENTED(); 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out,
NOT_IMPLEMENTED(); 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 &) { __cold ::std::ostream &operator<<(::std::ostream &out,
NOT_IMPLEMENTED(); const ::mdbx::error &err) {
} return out << err.what() << " (" << long(err.code()) << ")";
__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();
} }
} // namespace mdbx } // namespace mdbx
@ -1423,49 +1576,7 @@ __cold string to_string(const MDBX_debug_flags_t &value) {
return out.str(); return out.str();
} }
__cold string to_string(const MDBX_error_t &value) { __cold string to_string(const ::mdbx::error &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) {
ostringstream out; ostringstream out;
out << value; out << value;
return out.str(); return out.str();