Skip to content

Commit

Permalink
added formatter indentation flags (closes #120)
Browse files Browse the repository at this point in the history
also:
- minor refactoring (esp. GNU attributes)
- added documentation about formatters being free to ignore flags where necessary
  • Loading branch information
marzer committed Oct 27, 2021
1 parent bd9944a commit 18dfcf2
Show file tree
Hide file tree
Showing 18 changed files with 569 additions and 303 deletions.
4 changes: 4 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,16 @@ StatementMacros:
- TOML_ALWAYS_INLINE
- TOML_API
- TOML_ATTR
- TOML_CONST_GETTER
- TOML_CONST_INLINE_GETTER
- TOML_EXTERNAL_LINKAGE
- TOML_INTERNAL_LINKAGE
- TOML_MEMBER_ATTR
- TOML_NEVER_INLINE
- TOML_NODISCARD
- TOML_NODISCARD_CTOR
- TOML_PURE_GETTER
- TOML_PURE_INLINE_GETTER
- TOML_RETURNS_BY_THROWING
TabWidth: 4
TypenameMacros:
Expand Down
38 changes: 21 additions & 17 deletions cpp.hint
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
#define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true)
#define TOML_ABI_NAMESPACE_END static_assert(true)
#define TOML_ABSTRACT_BASE
#define TOML_ALWAYS_INLINE inline
#define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ANON_NAMESPACE_START namespace
#define TOML_API
#define TOML_ATTR(...)
#define TOML_ALWAYS_INLINE inline
#define TOML_NEVER_INLINE
#define TOML_TRIVIAL_ABI
#define TOML_ABSTRACT_BASE
#define TOML_EMPTY_BASES
#define TOML_CONST_GETTER
#define TOML_CONST_INLINE_GETTER inline
#define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__>
#define TOML_LIKELY(...) (__VA_ARGS__)
#define TOML_UNLIKELY(...) (__VA_ARGS__)
#define TOML_NODISCARD
#define TOML_NODISCARD_CTOR
#define TOML_RETURNS_BY_THROWING
#define TOML_EMPTY_BASES
#define TOML_EXTERN_NOEXCEPT(...)
#define TOML_EXTERNAL_LINKAGE
#define TOML_IMPL_NAMESPACE_END static_assert(true)
#define TOML_IMPL_NAMESPACE_START namespace toml::impl
#define TOML_INTERNAL_LINKAGE static
#define TOML_ANON_NAMESPACE_START namespace
#define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true)
#define TOML_ABI_NAMESPACE_END static_assert(true)
#define TOML_NAMESPACE_START namespace toml
#define TOML_LIKELY(...) (__VA_ARGS__)
#define TOML_NAMESPACE_END static_assert(true)
#define TOML_IMPL_NAMESPACE_START namespace toml::impl
#define TOML_IMPL_NAMESPACE_END static_assert(true)
#define TOML_NAMESPACE_START namespace toml
#define TOML_NEVER_INLINE
#define TOML_NODISCARD
#define TOML_NODISCARD_CTOR
#define TOML_PURE_GETTER
#define TOML_PURE_INLINE_GETTER inline
#define TOML_RETURNS_BY_THROWING
#define TOML_TRIVIAL_ABI
#define TOML_UNLIKELY(...) (__VA_ARGS__)
14 changes: 9 additions & 5 deletions include/toml++/impl/default_formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,25 @@ TOML_NAMESPACE_START
TOML_API
void print();

static constexpr format_flags mandatory_flags = format_flags::none;
static constexpr format_flags ignored_flags = format_flags::none;

/// \endcond

public:
/// \brief The default flags for a default_formatter.
static constexpr format_flags default_flags = format_flags::allow_literal_strings
| format_flags::allow_multi_line_strings
| format_flags::allow_value_format_flags;
static constexpr format_flags default_flags = format_flags::allow_literal_strings //
| format_flags::allow_multi_line_strings //
| format_flags::allow_value_format_flags //
| format_flags::indentation;

/// \brief Constructs a default formatter and binds it to a TOML object.
///
/// \param source The source TOML object.
/// \param flags Format option flags.
TOML_NODISCARD_CTOR
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags }
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
{}

#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
Expand Down Expand Up @@ -124,7 +128,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags.
TOML_NODISCARD_CTOR
explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags }
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
{}

#endif
Expand Down
14 changes: 9 additions & 5 deletions include/toml++/impl/default_formatter.inl
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ TOML_NAMESPACE_START
{
if (original_indent < 0)
base::indent(0);
base::increase_indent();
if (base::indent_array_elements())
base::increase_indent();
}
else
impl::print_to_stream(base::stream(), ' ');
Expand Down Expand Up @@ -380,7 +381,8 @@ TOML_NAMESPACE_START
if (!skip_self)
{
print_pending_table_separator();
base::increase_indent();
if (base::indent_sub_tables())
base::increase_indent();
base::print_indent();
impl::print_to_stream(base::stream(), "["sv);
print_key_path();
Expand All @@ -391,7 +393,7 @@ TOML_NAMESPACE_START
print(child_tbl);

key_path_.pop_back();
if (!skip_self)
if (!skip_self && base::indent_sub_tables())
base::decrease_indent();
}

Expand All @@ -402,7 +404,8 @@ TOML_NAMESPACE_START
continue;
auto& arr = *reinterpret_cast<const array*>(&v);

base::increase_indent();
if (base::indent_sub_tables())
base::increase_indent();
key_path_.push_back(make_key_segment(k));

for (size_t i = 0; i < arr.size(); i++)
Expand All @@ -417,7 +420,8 @@ TOML_NAMESPACE_START
}

key_path_.pop_back();
base::decrease_indent();
if (base::indent_sub_tables())
base::decrease_indent();
}
}

Expand Down
42 changes: 26 additions & 16 deletions include/toml++/impl/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,30 @@ TOML_IMPL_NAMESPACE_START
private:
const toml::node* source_;
std::ostream* stream_ = {};
format_flags flags_;
int indent_;
bool naked_newline_;
format_flags flags_; //
int indent_; // these are set in attach()
bool naked_newline_; //
#if TOML_PARSER && !TOML_EXCEPTIONS
const parse_result* result_ = {};
#endif

protected:
TOML_NODISCARD
TOML_ALWAYS_INLINE
static constexpr size_t indent_columns = 4;
static constexpr std::string_view indent_string = " "sv;

TOML_PURE_INLINE_GETTER
const toml::node& source() const noexcept
{
return *source_;
}

TOML_NODISCARD
TOML_ALWAYS_INLINE
TOML_PURE_INLINE_GETTER
std::ostream& stream() const noexcept
{
return *stream_;
}

static constexpr size_t indent_columns = 4;
static constexpr std::string_view indent_string = " "sv;

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
int indent() const noexcept
{
return indent_;
Expand All @@ -62,31 +60,43 @@ TOML_IMPL_NAMESPACE_START
indent_--;
}

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
bool indent_array_elements() const noexcept
{
return !!(flags_ & format_flags::indent_array_elements);
}

TOML_PURE_INLINE_GETTER
bool indent_sub_tables() const noexcept
{
return !!(flags_ & format_flags::indent_sub_tables);
}

TOML_PURE_INLINE_GETTER
bool quote_dates_and_times() const noexcept
{
return !!(flags_ & format_flags::quote_dates_and_times);
}

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
bool literal_strings_allowed() const noexcept
{
return !!(flags_ & format_flags::allow_literal_strings);
}

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
bool multi_line_strings_allowed() const noexcept
{
return !!(flags_ & format_flags::allow_multi_line_strings);
}

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
bool value_format_flags_allowed() const noexcept
{
return !!(flags_ & format_flags::allow_value_format_flags);
}

TOML_NODISCARD
TOML_PURE_INLINE_GETTER
bool naked_newline() const noexcept
{
return naked_newline_;
Expand Down
17 changes: 14 additions & 3 deletions include/toml++/impl/formatter.inl
Original file line number Diff line number Diff line change
Expand Up @@ -213,18 +213,29 @@ TOML_IMPL_NAMESPACE_START
}
}

#if TOML_PARSER && !TOML_EXCEPTIONS

TOML_EXTERNAL_LINKAGE
bool formatter::dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS)
bool formatter::dump_failed_parse_result() noexcept(false)
{
#if TOML_PARSER && !TOML_EXCEPTIONS
if (result_ && !(*result_))
{
stream() << result_->error();
return true;
}
#endif
return false;
}

#else

TOML_EXTERNAL_LINKAGE
TOML_ATTR(const)
bool formatter::dump_failed_parse_result() noexcept(true)
{
return false;
}

#endif
}
TOML_IMPL_NAMESPACE_END;

Expand Down
16 changes: 14 additions & 2 deletions include/toml++/impl/forward_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ TOML_NAMESPACE_START // abi namespace
}

/// \brief Metadata associated with TOML values.
enum class value_flags : uint8_t
enum class value_flags : uint16_t
{
/// \brief None.
none,
Expand All @@ -284,7 +284,10 @@ TOML_NAMESPACE_START // abi namespace
TOML_MAKE_FLAGS(value_flags);

/// \brief Format flags for modifying how TOML data is printed to streams.
enum class format_flags : uint8_t
///
/// \note Formatters may disregard/override any of these flags according to the requirements of their
/// output target (e.g. #toml::json_formatter JSON always apply quotes to dates and times).
enum class format_flags : uint64_t
{
/// \brief None.
none,
Expand All @@ -300,6 +303,15 @@ TOML_NAMESPACE_START // abi namespace

/// \brief Values with special format flags will be formatted accordingly.
allow_value_format_flags = 8,

/// \brief Apply indentation to tables nested within other tables/arrays.
indent_sub_tables = 16,

/// \brief Apply indentation to array elements when the array is forced to wrap over multiple lines.
indent_array_elements = 32,

/// \brief Combination mask of all indentation-enabling flags.
indentation = indent_sub_tables | indent_array_elements,
};
TOML_MAKE_FLAGS(format_flags);

Expand Down
11 changes: 8 additions & 3 deletions include/toml++/impl/json_formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,24 @@ TOML_NAMESPACE_START
TOML_API
void print();

static constexpr format_flags mandatory_flags = format_flags::quote_dates_and_times;
static constexpr format_flags ignored_flags =
format_flags::allow_literal_strings | format_flags::allow_multi_line_strings;

/// \endcond

public:
/// \brief The default flags for a json_formatter.
static constexpr format_flags default_flags = format_flags::quote_dates_and_times;
static constexpr format_flags default_flags = format_flags::quote_dates_and_times //
| format_flags::indentation;

/// \brief Constructs a JSON formatter and binds it to a TOML object.
///
/// \param source The source TOML object.
/// \param flags Format option flags.
TOML_NODISCARD_CTOR
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags }
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
{}

#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
Expand Down Expand Up @@ -98,7 +103,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags.
TOML_NODISCARD_CTOR
explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags }
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
{}

#endif
Expand Down
12 changes: 8 additions & 4 deletions include/toml++/impl/json_formatter.inl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ TOML_NAMESPACE_START
else
{
impl::print_to_stream(base::stream(), '{');
base::increase_indent();
if (base::indent_sub_tables())
base::increase_indent();
bool first = false;
for (auto&& [k, v] : tbl)
{
Expand All @@ -49,7 +50,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type);
}
}
base::decrease_indent();
if (base::indent_sub_tables())
base::decrease_indent();
base::print_newline(true);
base::print_indent();
impl::print_to_stream(base::stream(), '}');
Expand All @@ -65,7 +67,8 @@ TOML_NAMESPACE_START
else
{
impl::print_to_stream(base::stream(), '[');
base::increase_indent();
if (base::indent_array_elements())
base::increase_indent();
for (size_t i = 0; i < arr.size(); i++)
{
if (i > 0u)
Expand All @@ -83,7 +86,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type);
}
}
base::decrease_indent();
if (base::indent_array_elements())
base::decrease_indent();
base::print_newline(true);
base::print_indent();
impl::print_to_stream(base::stream(), ']');
Expand Down
Loading

0 comments on commit 18dfcf2

Please sign in to comment.