41template<
typename... Ts>
42[[nodiscard]] std::string
strCat(Ts&& ...ts);
49template<
typename... Ts>
70template<
typename... Ts>
71void strAppend(std::string& result, Ts&& ...ts);
127 [[nodiscard]]
size_t size()
const
132 [[nodiscard]]
char*
copy(
char* dst)
const
135 return dst + s.size();
148struct ConcatToString : ConcatViaString
151 : ConcatViaString(
std::to_string(
t))
163 std::ostringstream os;
181 [[nodiscard]]
size_t size()
const
186 [[nodiscard]]
char*
copy(
char* dst)
const
189 return dst + v.size();
206 [[nodiscard]]
size_t size()
const
211 [[nodiscard]]
char*
copy(
char* dst)
const
231 [[nodiscard]]
size_t size()
const
236 [[nodiscard]]
char*
copy(
char* dst)
const
238 *dst = b ?
'1' :
'0';
265template<std::
unsigned_
integral T>
268template<std::
signed_
integral T>
269[[nodiscard]] FastUnsigned<T>
absHelper(T
t) {
return (
t < 0)? -
t :
t; }
282 static constexpr bool IS_SIGNED = std::numeric_limits<T>::is_signed;
287 auto p = this->end();
291 *--p =
static_cast<char>(
'0' + (a % 10));
296 if (
t < 0) *--p =
'-';
298 this->sz =
static_cast<unsigned char>(this->end() - p);
301 [[nodiscard]]
size_t size()
const
306 [[nodiscard]]
char*
copy(
char* dst)
const
312 [[nodiscard]]
char*
copyTail(
char* dst,
size_t n)
const
319 [[nodiscard]]
operator std::string()
const
321 return std::string(data(), this->
size());
325 [[nodiscard]]
const char* data()
const {
return buf.data() +
BUF_SIZE - sz; }
326 [[nodiscard]]
auto end() {
return buf.end(); }
329 std::array<char, BUF_SIZE> buf;
344 [[nodiscard]]
size_t size()
const
349 [[nodiscard]]
char*
copy(
char* dst)
const
357 *--p = (d < 10) ? static_cast<char>(d +
'0')
358 :
static_cast<char>(d - 10 + A);
380 [[nodiscard]]
size_t size()
const
385 [[nodiscard]]
char*
copy(
char* dst)
const
393 *--p = (d < 10) ? static_cast<char>(d +
'0')
394 :
static_cast<char>(d - 10 + A);
415 [[nodiscard]]
size_t size()
const
420 [[nodiscard]]
char*
copy(
char* dst)
const
426 *--p =
static_cast<char>((u & 1) +
'0');
446 [[nodiscard]]
size_t size()
const
451 [[nodiscard]]
char*
copy(
char* dst)
const
472 [[nodiscard]]
size_t size()
const
477 [[nodiscard]]
char*
copy(
char* dst)
const
479 auto n2 = helper.size();
481 return helper.copyTail(dst, N);
484 auto* p =
spaces.copy(dst);
485 return helper.copy(p);
589 return ConcatToString<float>(f);
594 return ConcatToString<double>(d);
599 return ConcatToString<long double>(d);
603template<HexCase Case, std::
integral T>
609template<
size_t N, HexCase Case, std::
integral T>
615template<
size_t N, std::
integral T>
621template<
size_t N, std::
integral T>
635template<
typename Tuple,
size_t... Is>
638 return (... + std::get<Is>(
t).size());
641template<
typename... Ts>
649template<
typename Tuple,
size_t... Is>
652 auto l = { ((dst = std::get<Is>(
t).copy(dst)) , 0)... };
656template<
typename... Ts>
664[[nodiscard]]
inline std::string
to_string(std::integral
auto x)
673template<
typename... Ts>
674[[nodiscard]] std::string
strCat(Ts&& ...ts)
687 std::string result(size,
' ');
688 char* dst = result.data();
695template<
typename... Ts>
696[[nodiscard]] std::string
strCat(std::string&& first, Ts&& ...ts)
698 strAppend(first, std::forward<Ts>(ts)...);
699 return std::move(first);
712[[nodiscard]]
inline std::string
strCat(
const std::string& x) {
return x; }
713[[nodiscard]]
inline std::string
strCat(std::string&& x) {
return std::move(x); }
714[[nodiscard]]
inline std::string
strCat(
const char* x) {
return {x}; }
715[[nodiscard]]
inline std::string
strCat(
char x) {
return std::string(1, x); }
716[[nodiscard]]
inline std::string
strCat(std::string_view x) {
return {x.data(), x.size()}; }
729[[nodiscard]]
inline std::string
strCat(
const std::string& x,
const std::string& y) {
return x + y; }
730[[nodiscard]]
inline std::string
strCat(
const char* x,
const std::string& y) {
return x + y; }
731[[nodiscard]]
inline std::string
strCat(
char x,
const std::string& y) {
return x + y; }
732[[nodiscard]]
inline std::string
strCat(
const std::string& x,
const char* y) {
return x + y; }
733[[nodiscard]]
inline std::string
strCat(
const std::string& x,
char y) {
return x + y; }
734[[nodiscard]]
inline std::string
strCat(std::string&& x,
const std::string& y) {
return std::move(x) + y; }
735[[nodiscard]]
inline std::string
strCat(
const std::string& x, std::string&& y) {
return x + std::move(y); }
736[[nodiscard]]
inline std::string
strCat(std::string&& x, std::string&& y) {
return std::move(x) + std::move(y); }
737[[nodiscard]]
inline std::string
strCat(
const char* x, std::string&& y) {
return x + std::move(y); }
738[[nodiscard]]
inline std::string
strCat(
char x, std::string&& y) {
return x + std::move(y); }
739[[nodiscard]]
inline std::string
strCat(std::string&& x,
const char* y) {
return std::move(x) + y; }
740[[nodiscard]]
inline std::string
strCat(std::string&& x,
char y) {
return std::move(x) + y; }
751template<
typename... Ts>
759 auto oldSize = result.size();
760 result.append(extraSize,
' ');
761 char* dst = &result[oldSize];
772inline void strAppend(std::string& x,
const std::string& y) { x += y; }
773inline void strAppend(std::string& x,
const char* y) { x += y; }
774inline void strAppend(std::string& x, std::string_view y) { x.append(y.data(), y.size()); }
777template<HexCase Case = HexCase::lower, std::
integral T>
783template<
size_t N, HexCase Case = HexCase::lower, std::
integral T>
789template<
size_t N, std::
integral T>
795template<
size_t N, std::
integral T>
801[[nodiscard]]
inline auto spaces(
size_t n)
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)
constexpr 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)
strCatImpl::ConcatVariableWidthHexIntegral< Case, T > hex_string(Digits n, T t)
TemporaryString tmpStrCat(Ts &&... ts)
void strAppend(std::string &result, Ts &&...ts)
char * copy(char *dst) const
ConcatFixedWidthBinIntegral(T t_)
char * copy(char *dst) const
ConcatFixedWidthDecIntegral(T t)
char * copy(char *dst) const
ConcatFixedWidthHexIntegral(T t_)
char * copy(char *dst) const
static constexpr size_t BUF_SIZE
char * copyTail(char *dst, size_t n) const
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
ConcatVariableWidthHexIntegral(Digits n_, T t_)
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.