41template<
typename... Ts>
42[[nodiscard]] std::string
strCat(Ts&& ...ts);
49template<
typename... Ts>
70template<
typename... Ts>
71void strAppend(std::string& result, Ts&& ...ts);
121 [[nodiscard]]
size_t size()
const
126 [[nodiscard]]
char*
copy(
char* dst)
const
129 return dst + s.size();
142struct ConcatToString : ConcatViaString
157 std::ostringstream os;
175 [[nodiscard]]
size_t size()
const
180 [[nodiscard]]
char*
copy(
char* dst)
const
183 return dst + v.size();
200 [[nodiscard]]
size_t size()
const
205 [[nodiscard]]
char*
copy(
char* dst)
const
225 [[nodiscard]]
size_t size()
const
230 [[nodiscard]]
char*
copy(
char* dst)
const
232 *dst = b ?
'1' :
'0';
259template<std::
unsigned_
integral T>
262template<std::
signed_
integral T>
263[[nodiscard]] FastUnsigned<T>
absHelper(T
t) {
return (
t < 0)? -
t :
t; }
276 static constexpr bool IS_SIGNED = std::numeric_limits<T>::is_signed;
281 auto p = this->end();
285 *--p =
static_cast<char>(
'0' + (a % 10));
290 if (
t < 0) *--p =
'-';
292 this->sz =
static_cast<unsigned char>(this->end() - p);
295 [[nodiscard]]
size_t size()
const
300 [[nodiscard]]
char*
copy(
char* dst)
const
306 [[nodiscard]]
operator std::string()
const
308 return std::string(data(), this->
size());
312 [[nodiscard]]
const char* data()
const {
return buf.data() +
BUF_SIZE - sz; }
313 [[nodiscard]]
auto end() {
return buf.end(); }
316 std::array<char, BUF_SIZE> buf;
331 [[nodiscard]]
size_t size()
const
336 [[nodiscard]]
char*
copy(
char* dst)
const
343 *--p = (d < 10) ? static_cast<char>(d +
'0')
344 :
static_cast<char>(d - 10 +
'a');
364 [[nodiscard]]
size_t size()
const
369 [[nodiscard]]
char*
copy(
char* dst)
const
475 return ConcatToString<float>(f);
480 return ConcatToString<double>(d);
485 return ConcatToString<long double>(d);
489template<
size_t N, std::
integral T>
503template<
typename Tuple,
size_t... Is>
506 return (... + std::get<Is>(
t).
size());
509template<
typename... Ts>
517template<
typename Tuple,
size_t... Is>
520 auto l = { ((dst = std::get<Is>(
t).copy(dst)) , 0)... };
524template<
typename... Ts>
532[[nodiscard]]
inline std::string
to_string(std::integral
auto x)
541template<
typename... Ts>
542[[nodiscard]] std::string
strCat(Ts&& ...ts)
555 std::string result(
size,
' ');
556 char* dst = result.data();
563template<
typename... Ts>
564[[nodiscard]] std::string
strCat(std::string&& first, Ts&& ...ts)
566 strAppend(first, std::forward<Ts>(ts)...);
567 return std::move(first);
580[[nodiscard]]
inline std::string
strCat(
const std::string& x) {
return x; }
581[[nodiscard]]
inline std::string
strCat(std::string&& x) {
return std::move(x); }
582[[nodiscard]]
inline std::string
strCat(
const char* x) {
return {x}; }
583[[nodiscard]]
inline std::string
strCat(
char x) {
return std::string(1, x); }
584[[nodiscard]]
inline std::string
strCat(std::string_view x) {
return {x.data(), x.size()}; }
597[[nodiscard]]
inline std::string
strCat(
const std::string& x,
const std::string& y) {
return x + y; }
598[[nodiscard]]
inline std::string
strCat(
const char* x,
const std::string& y) {
return x + y; }
599[[nodiscard]]
inline std::string
strCat(
char x,
const std::string& y) {
return x + y; }
600[[nodiscard]]
inline std::string
strCat(
const std::string& x,
const char* y) {
return x + y; }
601[[nodiscard]]
inline std::string
strCat(
const std::string& x,
char y) {
return x + y; }
602[[nodiscard]]
inline std::string
strCat(std::string&& x,
const std::string& y) {
return x + y; }
603[[nodiscard]]
inline std::string
strCat(
const std::string& x, std::string&& y) {
return x + y; }
604[[nodiscard]]
inline std::string
strCat(std::string&& x, std::string&& y) {
return x + y; }
605[[nodiscard]]
inline std::string
strCat(
const char* x, std::string&& y) {
return x + y; }
606[[nodiscard]]
inline std::string
strCat(
char x, std::string&& y) {
return x + y; }
607[[nodiscard]]
inline std::string
strCat(std::string&& x,
const char* y) {
return x + y; }
608[[nodiscard]]
inline std::string
strCat(std::string&& x,
char y) {
return x + y; }
619template<
typename... Ts>
627 auto oldSize = result.size();
628 result.append(extraSize,
' ');
629 char* dst = &result[oldSize];
640inline void strAppend(std::string& x,
const std::string& y) { x += y; }
641inline void strAppend(std::string& x,
const char* y) { x += y; }
642inline void strAppend(std::string& x, std::string_view y) { x.append(y.data(), y.size()); }
645template<
size_t N, std::
integral T>
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr void fill(ForwardRange &&range, const T &value)
auto copy(InputRange &&range, OutputIter out)
FastUnsigned< T > absHelper(T t)
auto makeConcatUnit(const T &t)
void copyUnits(char *dst, const std::tuple< Ts... > &t)
void copyUnitsHelper(char *dst, const Tuple &t, std::index_sequence< Is... >)
typename FastUnsignedImpl< T >::type FastUnsigned
size_t calcTotalSizeHelper(const Tuple &t, std::index_sequence< Is... >)
size_t calcTotalSize(const std::tuple< Ts... > &t)
std::string to_string(std::integral auto x)
size_t size(std::string_view utf8)
strCatImpl::ConcatFixedWidthHexIntegral< N, T > hex_string(T t)
strCatImpl::ConcatSpaces spaces(size_t n)
TemporaryString tmpStrCat(Ts &&... ts)
std::string strCat(Ts &&...ts)
void strAppend(std::string &result, Ts &&...ts)
ConcatFixedWidthHexIntegral(T t_)
char * copy(char *dst) const
char * copy(char *dst) const
static constexpr size_t BUF_SIZE
static constexpr bool IS_SIGNED
char * copy(char *dst) const
char * copy(char *dst) const
char * copy(char *dst) const
ConcatUnit(const std::string_view v_)
char * copy(char *dst) const
char * copy(char *dst) const
ConcatViaString(std::string s_)
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.