Kùzu C++ API
Loading...
Searching...
No Matches
string_format.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <string_view>
5#include <type_traits>
6
7#include "internal.h"
8
9namespace kuzu {
10namespace common {
11
12namespace string_format_detail {
13#define MAP_STD_TO_STRING(typ) \
14 inline std::string map(typ v) { \
15 return std::to_string(v); \
16 }
17
19MAP_STD_TO_STRING(unsigned short)
21MAP_STD_TO_STRING(unsigned int)
23MAP_STD_TO_STRING(unsigned long)
24MAP_STD_TO_STRING(long long)
25MAP_STD_TO_STRING(unsigned long long)
28#undef MAP_STD_TO_STRING
29
30#define MAP_SELF(typ) \
31 inline typ map(typ v) { \
32 return v; \
33 }
34MAP_SELF(const char*);
35// Also covers std::string
36MAP_SELF(std::string_view)
37
38// chars are mapped to themselves, but signed char and unsigned char (which are used for int8_t and
39// uint8_t respectively), need to be cast to be properly output as integers. This is consistent with
40// fmt's behaviour.
41MAP_SELF(char)
42inline std::string map(signed char v) {
43 return std::to_string(int(v));
44}
45inline std::string map(unsigned char v) {
46 return std::to_string(unsigned(v));
47}
48#undef MAP_SELF
49
50template<typename... Args>
51inline void stringFormatHelper(std::string& ret, std::string_view format, Args&&... args) {
52 size_t bracket = format.find('{');
53 if (bracket == std::string_view::npos) {
54 ret += format;
55 return;
56 }
57 ret += format.substr(0, bracket);
58 if (format.substr(bracket, 4) == "{{}}") {
59 // Escaped {}.
60 ret += "{}";
61 return stringFormatHelper(ret, format.substr(bracket + 4), std::forward<Args>(args)...);
62 } else if (format.substr(bracket, 2) == "{}") {
63 // Formatted {}.
64 throw InternalException("Not enough values for string_format.");
65 }
66 // Something else.
67 ret.push_back('{');
68 return stringFormatHelper(ret, format.substr(bracket + 1), std::forward<Args>(args)...);
69}
70
71template<typename Arg, typename... Args>
72inline void stringFormatHelper(std::string& ret, std::string_view format, Arg&& arg,
73 Args&&... args) {
74 size_t bracket = format.find('{');
75 if (bracket == std::string_view::npos) {
76 throw InternalException("Too many values for string_format.");
77 }
78 ret += format.substr(0, bracket);
79 if (format.substr(bracket, 4) == "{{}}") {
80 // Escaped {}.
81 ret += "{}";
82 return stringFormatHelper(ret, format.substr(bracket + 4), std::forward<Arg>(arg),
83 std::forward<Args>(args)...);
84 } else if (format.substr(bracket, 2) == "{}") {
85 // Formatted {}.
86 ret += map(arg);
87 return stringFormatHelper(ret, format.substr(bracket + 2), std::forward<Args>(args)...);
88 }
89 // Something else.
90 ret.push_back('{');
91 return stringFormatHelper(ret, format.substr(bracket + 1), std::forward<Arg>(arg),
92 std::forward<Args>(args)...);
93}
94} // namespace string_format_detail
95
98template<typename... Args>
99inline std::string stringFormat(std::string_view format, Args... args) {
100 std::string ret;
101 ret.reserve(32); // Optimistic pre-allocation.
102 string_format_detail::stringFormatHelper(ret, format, std::forward<Args>(args)...);
103 return ret;
104}
105
106} // namespace common
107} // namespace kuzu
Definition internal.h:9
std::string map(signed char v)
Definition string_format.h:42
void stringFormatHelper(std::string &ret, std::string_view format, Args &&... args)
Definition string_format.h:51
std::string stringFormat(std::string_view format, Args... args)
Definition string_format.h:99
Definition array_utils.h:7
#define MAP_STD_TO_STRING(typ)
Definition string_format.h:13
#define MAP_SELF(typ)
Definition string_format.h:30