Program Listing for File generalArrayViewToString.hpp#
↰ Return to documentation for file (librapid/include/librapid/array/generalArrayViewToString.hpp)
#ifndef LIBRAPID_ARRAY_ARRAY_VIEW_STRING_HPP
#define LIBRAPID_ARRAY_ARRAY_VIEW_STRING_HPP
namespace librapid {
namespace detail {
template<size_t N, typename Val>
std::pair<int64_t, int64_t> alignment(const char (&formatString)[N], const Val &value) {
std::string tmpFormat = fmt::format("{{:{}}}", formatString);
std::string formatted = fmt::vformat(tmpFormat, fmt::make_format_args(value));
if constexpr (std::is_integral_v<std::decay_t<Val>>) {
return std::make_pair(formatted.length(), 0);
} else if constexpr (std::is_floating_point_v<std::decay_t<Val>>) {
auto point = formatted.find('.');
if (point == std::string::npos) {
return std::make_pair(formatted.length(), 0);
} else {
return std::make_pair(point, formatted.length() - point);
}
}
return std::make_pair(0, 0);
}
template<typename ArrayViewType, typename ArrayViewShapeType, size_t N>
void generalArrayViewToStringColWidthFinder(
const array::GeneralArrayView<ArrayViewType, ArrayViewShapeType> &view,
const char (&formatString)[N], std::vector<std::pair<int64_t, int64_t>> &alignments) {
if (view.ndim() == 1) {
for (int64_t i = 0; i < static_cast<int64_t>(view.shape()[0]); i++) {
auto alignmentPair = alignment(formatString, view.scalar(i));
if (i >= static_cast<int64_t>(alignments.size())) {
alignments.push_back(alignmentPair);
} else {
alignments[i].first =
::librapid::max(alignments[i].first, alignmentPair.first);
alignments[i].second =
::librapid::max(alignments[i].second, alignmentPair.second);
}
}
} else if (view.ndim() > 1) {
for (int64_t i = 0; i < static_cast<int64_t>(view.shape()[0]); i++) {
generalArrayViewToStringColWidthFinder(view[i], formatString, alignments);
}
}
}
template<typename ArrayViewType, typename ArrayViewShapeType, typename T, typename Char,
size_t N, typename Ctx>
void generalArrayViewToStringImpl(
const array::GeneralArrayView<ArrayViewType, ArrayViewShapeType> &view,
const fmt::formatter<T, Char> &formatter, char bracket, char separator,
const char (&formatString)[N], int64_t indent, Ctx &ctx,
const std::vector<std::pair<int64_t, int64_t>> &alignments) {
char bracketCharOpen, bracketCharClose;
switch (bracket) {
case 'r':
bracketCharOpen = '(';
bracketCharClose = ')';
break;
case 's':
bracketCharOpen = '[';
bracketCharClose = ']';
break;
case 'c':
bracketCharOpen = '{';
bracketCharClose = '}';
break;
case 'a':
bracketCharOpen = '<';
bracketCharClose = '>';
break;
case 'p':
bracketCharOpen = '|';
bracketCharClose = '|';
break;
default:
bracketCharOpen = '[';
bracketCharClose = ']';
break;
}
// Separator char is already the correct character
if (view.ndim() == 0) {
formatter.format(view.scalar(0), ctx);
} else if (view.ndim() == 1) {
fmt::format_to(ctx.out(), "{}", bracketCharOpen);
for (int64_t i = 0; i < static_cast<int64_t>(view.shape()[0]); i++) {
auto columnAlignment = alignments[i];
auto valueSize = alignment(formatString, view.scalar(i));
int64_t pre = max(columnAlignment.first - valueSize.first, 0),
post = max(columnAlignment.second - valueSize.second, 0);
fmt::format_to(ctx.out(), "{}", std::string(pre, ' '));
formatter.format(view.scalar(i), ctx);
fmt::format_to(ctx.out(), "{}", std::string(post, ' '));
if (i != view.shape()[0] - 1) {
if (separator == ' ') {
fmt::format_to(ctx.out(), " ");
} else {
fmt::format_to(ctx.out(), "{} ", separator);
}
}
}
fmt::format_to(ctx.out(), "{}", bracketCharClose);
} else {
fmt::format_to(ctx.out(), "{}", bracketCharOpen);
for (int64_t i = 0; i < static_cast<int64_t>(view.shape()[0]); i++) {
if (i > 0) fmt::format_to(ctx.out(), "{}", std::string(indent + 1, ' '));
generalArrayViewToStringImpl(view[i],
formatter,
bracket,
separator,
formatString,
indent + 1,
ctx,
alignments);
if (i != view.shape()[0] - 1) {
if (separator == ' ') {
fmt::format_to(ctx.out(), "\n");
} else {
fmt::format_to(ctx.out(), "{}\n", separator);
}
if (view.ndim() > 2) { fmt::format_to(ctx.out(), "\n"); }
}
}
fmt::format_to(ctx.out(), "{}", bracketCharClose);
}
}
template<typename ArrayViewType, typename ArrayViewShapeType, typename T, typename Char,
size_t N, typename Ctx>
void generalArrayViewToString(
const array::GeneralArrayView<ArrayViewType, ArrayViewShapeType> &view,
const fmt::formatter<T, Char> &formatter, char bracket, char separator,
const char (&formatString)[N], int64_t indent, Ctx &ctx) {
std::vector<std::pair<int64_t, int64_t>> alignments;
generalArrayViewToStringColWidthFinder(view, formatString, alignments);
generalArrayViewToStringImpl(
view, formatter, bracket, separator, formatString, indent, ctx, alignments);
}
} // namespace detail
namespace array {
template<typename ArrayViewType, typename ArrayViewShapeType>
template<typename T, typename Char, size_t N, typename Ctx>
void GeneralArrayView<ArrayViewType, ArrayViewShapeType>::str(
const fmt::formatter<T, Char> &format, char bracket, char separator,
const char (&formatString)[N], Ctx &ctx) const {
detail::generalArrayViewToString(
*this, format, bracket, separator, formatString, 0, ctx);
}
} // namespace array
} // namespace librapid
#endif // LIBRAPID_ARRAY_ARRAY_VIEW_STRING_HPP