13 #ifndef vtkPVStringFormatter_h 14 #define vtkPVStringFormatter_h 16 #include "vtkLogger.h" 27 #include VTK_FMT(fmt/args.h) 28 #include VTK_FMT(fmt/chrono.h) 29 #include VTK_FMT(fmt/core.h) 30 #include VTK_FMT(fmt/ranges.h) 47 template <
typename... Args>
53 template <
typename... Args>
66 template <
typename... Args>
69 std::shared_ptr<vtkArgumentScope> newScope;
71 if (vtkPVStringFormatter::ScopeStack.empty())
73 newScope = std::make_shared<vtkArgumentScope>();
77 newScope = std::make_shared<vtkArgumentScope>(*vtkPVStringFormatter::ScopeStack.top());
79 vtkPVStringFormatter::Push(*newScope, args...);
80 vtkPVStringFormatter::ScopeStack.push(newScope);
93 template <
typename... Args>
94 static void PushScope(
const char* scopeName, Args&&... args)
96 std::shared_ptr<vtkArgumentScope> newScope;
98 if (vtkPVStringFormatter::ScopeStack.empty())
100 newScope = std::make_shared<vtkArgumentScope>();
104 newScope = std::make_shared<vtkArgumentScope>(*vtkPVStringFormatter::ScopeStack.top());
106 vtkPVStringFormatter::Push(*newScope, scopeName, args...);
107 vtkPVStringFormatter::ScopeStack.push(newScope);
113 static void PopScope();
119 static std::string Format(
const std::string& formattableString);
129 using char_type = fmt::format_context::char_type;
134 struct vtkNamedArgument
169 std::chrono::time_point<std::chrono::system_clock>
TimePoint;
176 : Type(ValueType::
NONE)
181 : Type(ValueType::INT)
187 : Type(ValueType::UNSIGNED)
193 : Type(ValueType::LONG_LONG)
199 : Type(ValueType::UNSIGNED_LONG_LONG)
200 , UnsignedLongLong(value)
205 : Type(ValueType::BOOL)
211 : Type(ValueType::CHAR)
217 : Type(ValueType::
FLOAT)
223 : Type(ValueType::DOUBLE)
229 : Type(ValueType::LONG_DOUBLE)
235 : Type(ValueType::STRING)
240 Value(
const std::basic_string<char_type>& value)
241 : Type(ValueType::STRING)
246 Value(
const std::chrono::time_point<std::chrono::system_clock>& value)
247 : Type(ValueType::TIME_POINT)
252 Value(
const std::vector<double>& values)
253 : Type(ValueType::DOUBLE_VECTOR)
254 , DoubleVector(values)
260 this->Type = value.
Type;
264 this->Int = value.
Int;
266 case ValueType::UNSIGNED:
269 case ValueType::LONG_LONG:
272 case ValueType::UNSIGNED_LONG_LONG:
275 case ValueType::BOOL:
276 this->Bool = value.
Bool;
278 case ValueType::CHAR:
279 this->Char = value.
Char;
282 this->Float = value.
Float;
284 case ValueType::DOUBLE:
285 this->Double = value.
Double;
287 case ValueType::LONG_DOUBLE:
290 case ValueType::STRING:
291 new (&this->String) std::basic_string<char_type>(value.
String);
293 case ValueType::TIME_POINT:
296 case ValueType::DOUBLE_VECTOR:
297 new (&this->DoubleVector) std::vector<double>(value.
DoubleVector);
308 case ValueType::STRING:
309 this->String.~basic_string();
311 case ValueType::DOUBLE_VECTOR:
312 this->DoubleVector.~vector();
320 std::basic_string<char_type> Name;
323 vtkNamedArgument() =
default;
325 template <
typename DataType>
326 vtkNamedArgument(
const std::basic_string<char_type>&
name,
const DataType&
value)
332 ~vtkNamedArgument() =
default;
338 class vtkArgumentScope
341 std::vector<vtkNamedArgument> Arguments;
344 vtkArgumentScope() =
default;
346 vtkArgumentScope(
const vtkArgumentScope& other)
348 this->Arguments.reserve(other.Arguments.size());
349 for (
const auto& arg : other.Arguments)
351 this->Arguments.emplace_back(arg);
359 template <
typename T>
360 void AddArg(
const fmt::detail::named_arg<char_type, T>& fmtArg)
362 bool argNotFound = std::find_if(this->Arguments.begin(), this->Arguments.end(),
363 [&fmtArg](
const vtkNamedArgument& arg) {
364 return arg.Name == fmtArg.name;
365 }) == this->Arguments.end();
369 vtkNamedArgument newArg(fmtArg.name, fmtArg.value);
370 this->Arguments.push_back(newArg);
374 vtkLogF(WARNING,
"Argument %s already exists. Try to add another one.", fmtArg.name);
381 std::basic_string<char_type> GetArgInfo()
const 383 std::basic_stringstream<char_type> argInfo;
384 for (
const auto& arg : this->Arguments)
386 argInfo <<
"\tName: " << arg.Name;
387 argInfo <<
"\tType: ";
388 switch (arg.Value.Type)
390 case vtkNamedArgument::ValueType::INT:
393 case vtkNamedArgument::ValueType::UNSIGNED:
394 argInfo <<
"unsigned";
396 case vtkNamedArgument::ValueType::LONG_LONG:
397 argInfo <<
"long long";
399 case vtkNamedArgument::ValueType::UNSIGNED_LONG_LONG:
400 argInfo <<
"unsigned long long";
402 case vtkNamedArgument::ValueType::BOOL:
405 case vtkNamedArgument::ValueType::CHAR:
411 case vtkNamedArgument::ValueType::DOUBLE:
414 case vtkNamedArgument::ValueType::LONG_DOUBLE:
415 argInfo <<
"long double";
417 case vtkNamedArgument::ValueType::STRING:
418 argInfo <<
"std::string";
420 case vtkNamedArgument::ValueType::TIME_POINT:
421 argInfo <<
"std::chrono::time_point<std::chrono::system_clock>";
423 case vtkNamedArgument::ValueType::DOUBLE_VECTOR:
424 argInfo <<
"std::vector<double>";
427 argInfo <<
"unknown";
432 return argInfo.str();
438 fmt::dynamic_format_arg_store<fmt::format_context> GetArgs()
const 440 fmt::dynamic_format_arg_store<fmt::format_context> args;
441 for (
const auto& arg : this->Arguments)
443 switch (arg.Value.Type)
445 case vtkNamedArgument::ValueType::INT:
446 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Int));
448 case vtkNamedArgument::ValueType::UNSIGNED:
449 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Unsigned));
451 case vtkNamedArgument::ValueType::LONG_LONG:
452 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.LongLong));
454 case vtkNamedArgument::ValueType::UNSIGNED_LONG_LONG:
455 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.UnsignedLongLong));
457 case vtkNamedArgument::ValueType::BOOL:
458 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Bool));
460 case vtkNamedArgument::ValueType::CHAR:
461 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Char));
464 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Float));
466 case vtkNamedArgument::ValueType::DOUBLE:
467 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.Double));
469 case vtkNamedArgument::ValueType::LONG_DOUBLE:
470 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.LongDouble));
472 case vtkNamedArgument::ValueType::STRING:
473 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.String));
475 case vtkNamedArgument::ValueType::TIME_POINT:
476 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.TimePoint));
478 case vtkNamedArgument::ValueType::DOUBLE_VECTOR:
479 args.push_back(fmt::arg(arg.Name.c_str(), arg.Value.DoubleVector));
491 void clear() { this->Arguments.clear(); }
497 static std::string GetArgInfo();
502 static void Push(vtkArgumentScope& vtkNotUsed(scope)) {}
507 template <
typename T0,
typename... TArgs>
508 static void Push(vtkArgumentScope& scope, T0& arg0, TArgs&... args)
511 vtkPVStringFormatter::Push(scope, args...);
517 static void Push(vtkArgumentScope& vtkNotUsed(scope),
const char* vtkNotUsed(scopeName)) {}
522 template <
typename T0,
typename... TArgs>
523 static void Push(vtkArgumentScope& scope,
const char* scopeName, T0& arg0, TArgs&... args)
525 auto scopeBasedArgName = std::string(scopeName) +
"_" + arg0.name;
526 scope.AddArg(fmt::arg(scopeBasedArgName.c_str(), arg0.value));
528 vtkPVStringFormatter::Push(scope, scopeName, args...);
531 static std::stack<std::shared_ptr<vtkArgumentScope>> ScopeStack;
534 #define PV_STRING_FORMATTER_SCOPE_0(x, y) x##y 535 #define PV_STRING_FORMATTER_SCOPE_1(x, y) PV_STRING_FORMATTER_SCOPE_0(x, y) 536 #define PV_STRING_FORMATTER_SCOPE(...) \ 537 vtkPVStringFormatter::TraceScope PV_STRING_FORMATTER_SCOPE_1(_trace_item, __LINE__)(__VA_ARGS__) 538 #define PV_STRING_FORMATTER_NAMED_SCOPE(NAME, ...) \ 539 vtkPVStringFormatter::TraceScope PV_STRING_FORMATTER_SCOPE_1(_trace_item, __LINE__)( \
#define VTKPVVTKEXTENSIONSCORE_EXPORT
void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE