Add indented_writer_base<T> to library (#305)

This commit is contained in:
Jonitis 2019-07-15 15:32:45 +03:00 коммит произвёл Kenny Kerr
Родитель 8d849c1045
Коммит 055f888143
3 изменённых файлов: 102 добавлений и 170 удалений

Просмотреть файл

@ -11,29 +11,11 @@ using namespace xlang::cmd;
template <typename...T> struct overloaded : T... { using T::operator()...; };
template <typename...T> overloaded(T...)->overloaded<T...>;
struct writer : writer_base<writer>
struct writer : indented_writer_base<writer>
{
using writer_base<writer>::write;
struct indent_guard
{
explicit indent_guard(writer& w, int32_t offset = 1) noexcept : _writer(w), _offset(offset)
{
_writer.indent += _offset;
}
~indent_guard()
{
_writer.indent -= _offset;
}
private:
writer& _writer;
int32_t _offset;
};
using indented_writer_base<writer>::write;
std::string_view current;
int32_t indent{};
std::vector<std::pair<GenericParam, GenericParam>> generic_param_stack;
@ -66,76 +48,6 @@ struct writer : writer_base<writer>
return generic_param_guard{ this };
}
void write_indent()
{
for (int32_t i = 0; i < indent; i++)
{
writer_base::write_impl(" ");
}
}
void write_impl(std::string_view const& value)
{
std::string_view::size_type current_pos{ 0 };
auto on_new_line = back() == '\n';
while (true)
{
const auto pos = value.find('\n', current_pos);
if (pos == std::string_view::npos)
{
if (current_pos < value.size())
{
if (on_new_line)
{
write_indent();
}
writer_base::write_impl(value.substr(current_pos));
}
return;
}
auto current_line = value.substr(current_pos, pos - current_pos + 1);
auto empty_line = current_line[0] == '\n';
if (on_new_line && !empty_line)
{
write_indent();
}
writer_base::write_impl(current_line);
on_new_line = true;
current_pos = pos + 1;
}
}
void write_impl(char const value)
{
if (back() == '\n' && value != '\n')
{
write_indent();
}
writer_base::write_impl(value);
}
template <typename... Args>
std::string write_temp(std::string_view const& value, Args const& ... args)
{
auto restore_indent = indent;
indent = 0;
auto result = writer_base::write_temp(value, args...);
indent = restore_indent;
return result;
}
void write_value(bool value)
{
write(value ? "TRUE"sv : "FALSE"sv);

Просмотреть файл

@ -132,7 +132,7 @@ namespace xlang::text
F(*static_cast<T*>(this), item, args...);
}
}
void swap() noexcept
{
std::swap(m_second, m_first);
@ -290,6 +290,102 @@ namespace xlang::text
std::vector<char> m_first;
};
template <typename T>
struct indented_writer_base : writer_base<T>
{
struct indent_guard
{
indent_guard(indented_writer_base<T>& w, int32_t offset = 1) noexcept : m_writer(w), m_offset(offset)
{
m_writer.m_indent += m_offset;
}
~indent_guard() noexcept
{
m_writer.m_indent -= m_offset;
}
private:
indented_writer_base<T>& m_writer;
int32_t m_offset{};
};
void write_indent()
{
for (int32_t i = 0; i < m_indent; i++)
{
writer_base<T>::write_impl(" ");
}
}
void write_impl(std::string_view const& value)
{
std::string_view::size_type current_pos{ 0 };
auto on_new_line = writer_base<T>::back() == '\n';
while (true)
{
const auto pos = value.find('\n', current_pos);
if (pos == std::string_view::npos)
{
if (current_pos < value.size())
{
if (on_new_line)
{
write_indent();
}
writer_base<T>::write_impl(value.substr(current_pos));
}
return;
}
auto current_line = value.substr(current_pos, pos - current_pos + 1);
auto empty_line = current_line[0] == '\n';
if (on_new_line && !empty_line)
{
write_indent();
}
writer_base<T>::write_impl(current_line);
on_new_line = true;
current_pos = pos + 1;
}
}
void write_impl(char const value)
{
if (writer_base<T>::back() == '\n' && value != '\n')
{
write_indent();
}
writer_base<T>::write_impl(value);
}
template <typename... Args>
std::string write_temp(std::string_view const& value, Args const& ... args)
{
auto restore_indent = m_indent;
m_indent = 0;
auto result = writer_base<T>::write_temp(value, args...);
m_indent = restore_indent;
return result;
}
int32_t m_indent{};
};
template <auto F, typename... Args>
auto bind(Args&&... args)
{

Просмотреть файл

@ -26,9 +26,9 @@ namespace pywinrt
return result;
}
struct writer : writer_base<writer>
struct writer : indented_writer_base<writer>
{
using writer_base<writer>::write;
using indented_writer_base<writer>::write;
std::string_view current_namespace{};
std::set<std::string> needed_namespaces{};
@ -118,82 +118,6 @@ namespace pywinrt
#pragma endregion
int32_t indent{ 0 };
struct indent_guard
{
explicit indent_guard(writer& w) noexcept : _writer(w)
{
_writer.indent++;
}
~indent_guard()
{
_writer.indent--;
}
private:
writer & _writer;
};
void write_indent()
{
for (int32_t i = 0; i < indent; i++)
{
writer_base::write_impl(" ");
}
}
void write_impl(std::string_view const& value)
{
if (back() == '\n')
{
write_indent();
}
std::string_view::size_type current_pos{ 0 };
auto pos = value.find('\n', current_pos);
while(pos != std::string_view::npos)
{
writer_base::write_impl(value.substr(current_pos, pos + 1 - current_pos));
if (pos != value.size() - 1)
{
write_indent();
}
current_pos = pos + 1;
pos = value.find('\n', current_pos);
}
if (pos == std::string_view::npos)
{
writer_base::write_impl(value.substr(current_pos));
}
}
void write_impl(char const value)
{
if (back() == '\n')
{
write_indent();
}
writer_base::write_impl(value);
}
template <typename... Args>
std::string write_temp(std::string_view const& value, Args const&... args)
{
auto restore_indent = indent;
indent = 0;
auto result = writer_base::write_temp(value, args...);
indent = restore_indent;
return result;
}
void write_value(bool value)
{
write(value ? "TRUE"sv : "FALSE"sv);
@ -382,7 +306,7 @@ namespace pywinrt
break;
}
}
void register_type_namespace(TypeSig const& type)
{
call(type.Type(),