tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
format_to.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch
3
4#ifndef TETL_FORMAT_FORMAT_TO_HPP
5#define TETL_FORMAT_FORMAT_TO_HPP
6
7#include <etl/_format/argument.hpp>
8#include <etl/_format/basic_format_context.hpp>
9#include <etl/_type_traits/remove_cvref.hpp>
10#include <etl/_vector/static_vector.hpp>
11
12namespace etl {
13template <typename Iter>
14using diff_t = typename etl::iterator_traits<etl::remove_cvref_t<Iter>>::difference_type;
15
16/// \brief Format args according to the format string fmt, and write the result
17/// to the output iterator out.
18///
19/// https://en.cppreference.com/w/cpp/utility/format/format_to
20template <typename OutputIt, typename... Args>
21auto format_to(OutputIt out, etl::string_view fmt, Args const&... args) -> OutputIt
22{
23 auto ctx = format_context{out};
24
25 // Format leading text before the first argument.
26 auto const slices = detail::split_at_next_argument(fmt);
27 detail::format_escaped_sequences(slices.first, ctx);
28
29 // Save rest of format string. Supress warning if format_to was called
30 // without arguments.
31 auto rest = slices.second;
33
34 ([&] {
35 // Format argument
36 detail::format_argument(args, ctx);
37
38 // Split format text at next argument
39 auto const restSlices = detail::split_at_next_argument(rest);
40 detail::format_escaped_sequences(restSlices.first, ctx);
41
42 // Save rest of format string for the next arguments
43 rest = restSlices.second;
44 }(), ...);
45
46 // Anything left over after the last argument.
47 if (auto const trailing = detail::split_at_next_argument(rest); !trailing.first.empty()) {
48 detail::format_escaped_sequences(trailing.first, ctx);
49 TETL_ASSERT(trailing.second.empty());
50 }
51
52 return ctx.out();
53}
54
55/// \brief etl::format_to_n_result has no base classes, or members other than
56/// out, size and implicitly declared special member functions.
57///
58/// https://en.cppreference.com/w/cpp/utility/format/format_to_n
59template <typename Out>
61 Out out;
62 diff_t<Out> size;
63};
64
65/// \brief Format args according to the format string fmt, and write the result
66/// to the output iterator out. At most n characters are written.
67///
68/// https://en.cppreference.com/w/cpp/utility/format/format_to_n
69template <typename OutputIter, typename... Args>
70auto format_to_n(OutputIter out, diff_t<OutputIter> n, etl::string_view fmt, Args const&... args)
71 -> format_to_n_result<OutputIter>
72{
73 etl::ignore_unused(n);
74
75 auto indices = etl::static_vector<etl::size_t, sizeof...(args)>{};
76 auto result = format_to_n_result<OutputIter>{out, {}};
77
78 auto writeChar = [&result](auto ch) {
79 *result.out++ = ch;
80 result.size++;
81 };
82
83 auto varStart = etl::size_t{};
84 for (decltype(fmt)::size_type i{}; i < fmt.size(); ++i) {
85 auto ch = fmt[i];
86 if (ch == '{') {
87 if ((fmt.size() > i + 1) && (fmt[i + 1] == '{')) {
88 ++i;
89 writeChar('{');
90 continue;
91 }
92
93 varStart = i;
94 continue;
95 }
96
97 if (ch == '}') {
98 if ((fmt.size() > i + 1) && (fmt[i + 1] == '}')) {
99 ++i;
100 writeChar('}');
101 continue;
102 }
103
104 indices.push_back(varStart);
105 writeChar('0');
106 continue;
107 }
108
109 writeChar(ch);
110 }
111
112 if (indices.size() > 0) {
113 [[maybe_unused]] auto replaceCharAt = [n](auto output, auto pos, char val) {
114 etl::ignore_unused(n);
115 // TETL_ASSERT((long)pos < n);
116 output[pos] = val;
117 };
118
119 [[maybe_unused]] typename decltype(indices)::size_type i{};
120 (replaceCharAt(out, indices[i++], args), ...);
121 }
122
123 return result;
124}
125} // namespace etl
126
127#endif // TETL_FORMAT_FORMAT_TO_HPP
Definition adjacent_find.hpp:9
auto format_to(OutputIt out, etl::string_view fmt, Args const &... args) -> OutputIt
Format args according to the format string fmt, and write the result to the output iterator out.
Definition format_to.hpp:21
constexpr auto ignore_unused(Types &&...) -> void
Explicitly ignore arguments or variables.
Definition ignore_unused.hpp:18
auto format_to_n(OutputIter out, diff_t< OutputIter > n, etl::string_view fmt, Args const &... args) -> format_to_n_result< OutputIter >
Format args according to the format string fmt, and write the result to the output iterator out....
Definition format_to.hpp:70
constexpr auto out() noexcept -> iterator
Returns the iterator to the output buffer.
Definition basic_format_context.hpp:35
constexpr auto operator=(basic_string_view const &view) noexcept -> basic_string_view &=default
Replaces the view with that of view.
constexpr auto empty() const noexcept -> bool
Checks if the view has no characters, i.e. whether size() == 0.
Definition basic_string_view.hpp:215
constexpr auto operator[](size_type pos) const -> const_reference
Returns a const reference to the character at specified location pos.
Definition basic_string_view.hpp:165
constexpr auto size() const noexcept -> size_type
Returns the number of Char elements in the view, i.e. etl::distance(begin(), end()).
Definition basic_string_view.hpp:196
etl::format_to_n_result has no base classes, or members other than out, size and implicitly declared ...
Definition format_to.hpp:60
Out out
Definition format_to.hpp:61
diff_t< Out > size
Definition format_to.hpp:62
iterator_traits is the type trait class that provides uniform interface to the properties of LegacyIt...
Definition iterator_traits.hpp:48
Dynamically-resizable fixed-capacity vector.
Definition static_vector.hpp:401