tinyopt 700
Tinyopt, a lightweight, header only optimization library
Loading...
Searching...
No Matches
formatters.h
1// Copyright 2026 Julien Michot.
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include <format>
7#include <sstream>
8
9#include <tinyopt/math.h>
10
11#ifdef TINYOPT_FORMAT_NS
12
13#include <tinyopt/traits.h>
14
15#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
16
17template <typename T>
18struct TINYOPT_FORMAT_NS::formatter<
19 T, std::enable_if_t<std::is_base_of_v<tinyopt::DenseBase<T>, T>, char>> {
20 template <typename ParseContext>
21 constexpr auto parse(ParseContext& ctx) {
22 return m_underlying.parse(ctx);
23 }
24 template <typename FormatContext>
25 auto format(const T& m, FormatContext& ctx) const {
26 std::ostringstream os;
27 if (m.cols() == 1) // print vectors as a row
28 os << m.transpose();
29 else
30 os << m;
31 auto out = ctx.out();
32 out = TINYOPT_FORMAT_NS::format_to(ctx.out(), "{}", os.str());
33 return out;
34 }
35
36 private:
37 TINYOPT_FORMAT_NS::formatter<typename T::Scalar, char> m_underlying;
38};
39
40template <typename T>
41struct TINYOPT_FORMAT_NS::formatter<
42 T, std::enable_if_t<tinyopt::traits::is_sparse_matrix_v<T>, char>> {
43 template <typename ParseContext>
44 constexpr auto parse(ParseContext& ctx) {
45 return m_underlying.parse(ctx);
46 }
47 template <typename FormatContext>
48 auto format(const T& m, FormatContext& ctx) const {
49 std::ostringstream os;
50 os << m;
51 auto out = ctx.out();
52 out = TINYOPT_FORMAT_NS::format_to(ctx.out(), "{}", os.str());
53 return out;
54 }
55
56 private:
57 TINYOPT_FORMAT_NS::formatter<typename T::Scalar, char> m_underlying;
58};
59
60#endif
61
62#if !(__cplusplus >= 202302L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202302L))
63
64// std::array
65template <typename T, size_t N>
66std::ostream& operator<<(std::ostream& os, const std::array<T, N>& v) {
67 for (std::size_t i = 0; i < v.size(); ++i) {
68 os << v[i];
69 if (i + 1 < v.size()) os << " ";
70 }
71 return os;
72}
73
74// std::vector
75template <typename T>
76std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
77 for (std::size_t i = 0; i < v.size(); ++i) {
78 os << v[i];
79 if (i + 1 < v.size()) os << " ";
80 }
81 return os;
82}
83
84#endif // c++23
85
86#endif