39 #ifndef OR_TOOLS_BASE_DUMP_VARS_H_
40 #define OR_TOOLS_BASE_DUMP_VARS_H_
45 #include <type_traits>
49 #include "absl/container/inlined_vector.h"
52 #define DUMP_FOR_EACH_N0(F)
53 #define DUMP_FOR_EACH_N1(F, a) F(a)
54 #define DUMP_FOR_EACH_N2(F, a, ...) F(a) DUMP_FOR_EACH_N1(F, __VA_ARGS__)
55 #define DUMP_FOR_EACH_N3(F, a, ...) F(a) DUMP_FOR_EACH_N2(F, __VA_ARGS__)
56 #define DUMP_FOR_EACH_N4(F, a, ...) F(a) DUMP_FOR_EACH_N3(F, __VA_ARGS__)
57 #define DUMP_FOR_EACH_N5(F, a, ...) F(a) DUMP_FOR_EACH_N4(F, __VA_ARGS__)
58 #define DUMP_FOR_EACH_N6(F, a, ...) F(a) DUMP_FOR_EACH_N5(F, __VA_ARGS__)
59 #define DUMP_FOR_EACH_N7(F, a, ...) F(a) DUMP_FOR_EACH_N6(F, __VA_ARGS__)
60 #define DUMP_FOR_EACH_N8(F, a, ...) F(a) DUMP_FOR_EACH_N7(F, __VA_ARGS__)
62 #define DUMP_CONCATENATE(x, y) x##y
63 #define DUMP_FOR_EACH_(N, F, ...) \
64 DUMP_CONCATENATE(DUMP_FOR_EACH_N, N)(F __VA_OPT__(, __VA_ARGS__))
66 #define DUMP_NARG(...) DUMP_NARG_(__VA_OPT__(__VA_ARGS__, ) DUMP_RSEQ_N())
67 #define DUMP_NARG_(...) DUMP_ARG_N(__VA_ARGS__)
68 #define DUMP_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
69 #define DUMP_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
70 #define DUMP_FOR_EACH(F, ...) \
71 DUMP_FOR_EACH_(DUMP_NARG(__VA_ARGS__), F __VA_OPT__(, __VA_ARGS__))
73 #define DUMP_VARS(...) DUMP_VARS_WITH_BINDINGS((), __VA_ARGS__)
76 #define DUMP_STRINGIZE(a) #a,
77 #define DUMP_STRINGIFY(...) DUMP_FOR_EACH(DUMP_STRINGIZE, __VA_ARGS__)
80 #define DUMP_IDENTITY(...) __VA_ARGS__
82 #define DUMP_RM_PARENS(...) DUMP_IDENTITY __VA_ARGS__
84 #define DUMP_GEN_ONE_BINDING(a) , &a = a
85 #define DUMP_GEN_BINDING(binding) \
86 &DUMP_FOR_EACH(DUMP_GEN_ONE_BINDING, DUMP_RM_PARENS(binding))
88 #define DUMP_VARS_WITH_BINDINGS(binding, ...) \
89 ::operations_research::base::internal_dump_vars::make_dump_vars<>( \
90 ::operations_research::base::internal_dump_vars::DumpNames{ \
91 DUMP_STRINGIFY(__VA_ARGS__)}, \
92 [DUMP_GEN_BINDING(binding)]( \
93 ::std::ostream& os, const ::std::string& field_sep, \
94 const ::std::string& kv_sep, \
95 const ::operations_research::base::internal_dump_vars::DumpNames& \
97 ::operations_research::base::internal_dump_vars::print_fields{ \
99 .field_sep = field_sep, \
106 namespace internal_dump_vars {
109 template <
typename T>
111 const ::absl::InlinedVector<T, 8>& vec) {
113 os << ::std::to_string(it) <<
',';
128 template <
class T1,
class T2,
class... Ts>
129 void operator()(
const T1& t1,
const T2& t2,
const Ts&... ts) {
144 explicit Dump(const ::std::string&& field_sep, const ::std::string&& kv_sep,
146 : field_sep_(::std::move(field_sep)),
147 kv_sep_(::std::move(kv_sep)),
148 names_(::std::move(names)),
149 f_(::std::move(f)) {}
151 ::std::string
str()
const {
152 ::std::ostringstream oss;
157 template <
class... N>
159 return Dump<F>(::std::string{field_sep_}, ::std::string{kv_sep_},
164 field_sep_ = ::std::move(field_sep);
168 Dump&
sep(::std::string&& field_sep, ::std::string&& kv_sep) {
169 field_sep_ = ::std::move(field_sep);
170 kv_sep_ = ::std::move(kv_sep);
175 dump.print_fields_(os);
180 void print_fields_(::std::ostream& os)
const {
181 f_(os, field_sep_, kv_sep_, names_);
184 ::std::string field_sep_;
185 ::std::string kv_sep_;
194 " = ", ::std::move(names), ::std::move(f));
Dump< F > as(N &&... names) const
::std::string str() const
Dump & sep(::std::string &&field_sep, ::std::string &&kv_sep)
Dump(const ::std::string &&field_sep, const ::std::string &&kv_sep, DumpNames &&names, F f)
friend ::std::ostream & operator<<(::std::ostream &os, const Dump &dump)
Dump & sep(::std::string &&field_sep)
Dump< F > make_dump_vars(DumpNames &&names, F f)
::std::vector<::std::string > DumpNames
std::ostream & operator<<(std::ostream &os, const ::absl::InlinedVector< T, 8 > &vec)
const ::std::string & kv_sep
const ::std::string & field_sep
void operator()(const T &t)
void operator()(const T1 &t1, const T2 &t2, const Ts &... ts)