repr 0.1
Reconstructable string representations and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
repr.h
Go to the documentation of this file.
#pragma once
#include <cstddef>
#include <string>
#include <string_view>
#include <type_traits>
namespace librepr {
class ReprVisitor {
private:
bool separate = false;
std::size_t level = 0;
Options options = {};
void print_indent() {
if (options.indent != 0) {
result << "\n";
result << std::string(options.indent * level, ' ');
}
}
void print_separator() {
if (separate) {
result << ", ";
} else {
separate = true;
}
print_indent();
}
public:
explicit ReprVisitor(Options const& options_) : options(options_) {}
void nesting(bool increase) {
if (increase) {
separate = false;
result << '{';
++level;
}
else {
--level;
print_indent();
result << '}';
separate = true;
}
}
print_separator();
result << '.'<< name << '=';
separate = false;
}
template <typename T>
void type() {
print_separator();
if constexpr (!librepr::is_literal_v<T>) {
if (options.should_print_type(level)) {
}
}
}
template <typename T>
void value(T const& obj) {
}
template <typename T>
void value(T const& obj) {
if constexpr (!librepr::is_literal_v<T>) {
nesting(true);
}
result << obj.repr();
if constexpr (!librepr::is_literal_v<T>) {
nesting(false);
}
}
// special case string literals
void value(char const* obj) {
// TODO template this for wide string literals
// don't print a type, only print the separator if needed
print_separator();
result << REPR_FORMAT("\"{}\"", obj);
}
template <typename T>
requires std::is_pointer_v<T>
void value(T const& obj) {
// don't print a type, only print the separator if needed
print_separator();
using underlying_type = std::remove_pointer_t<T>;
if constexpr (!std::is_same_v<underlying_type, void> && !std::is_pointer_v<underlying_type>) {
// try to reflect whatever the pointer is pointing to
// disabled for void* and pointer-to-pointer T
if (obj) { // don't attempt to dereference nullptr
nesting(true);
nesting(false);
return;
}
}
result << '(' << librepr::get_name<T>() << ')' << librepr::repr(static_cast<const void*>(obj));
}
template <typename T>
void operator()(T info){
if constexpr (category::has_name<T>){
member_name(info.name());
}
value(info.value());
}
template <typename T>
void operator()(T info){
if constexpr (category::has_name<T>){
member_name(info.name());
}
nesting(true);
info.visit(*this);
nesting(false);
}
};
//static_assert(Visitor::Hierarchical<ReprVisitor>, "Formatter isn't a valid hierarchical visitor.");
} // namespace librepr