11#if defined(_MSC_VER) && !defined(__clang__)
13# if C4_MSVC_VERSION != C4_MSVC_VERSION_2017
14# pragma warning(disable: 4800)
16# pragma warning(disable: 4996)
17#elif defined(__clang__)
18# pragma clang diagnostic push
19#elif defined(__GNUC__)
20# pragma GCC diagnostic push
21# pragma GCC diagnostic ignored "-Wuseless-cast"
268 static_assert(std::is_integral<T>::value,
"range checking only for integral types");
289 ->
typename std::enable_if<std::is_signed<T>::value,
size_t>::type
297 ->
typename std::enable_if<std::is_signed<T>::value,
size_t>::type
306 ->
typename std::enable_if<std::is_unsigned<T>::value,
size_t>::type
314 ->
typename std::enable_if<std::is_unsigned<T>::value,
size_t>::type
398 C4_ALWAYS_INLINE
raw_wrapper_(blob_<T> data,
size_t alignment_) noexcept
517 return left_<T>(val, width, padchar);
570 if(ret >= buf.
len || ret >= align.
width)
581 if(ret >= buf.
len || ret >= align.
width)
583 size_t rem = align.
width - ret;
585 memmove(buf.
str + rem, buf.
str, ret);
595 if(ret >= buf.
len || ret >= align.
width)
597 size_t first = (align.
width - ret) / 2u;
599 memmove(buf.
str + first, buf.
str, ret);
648template<
class Arg,
class... Args>
649size_t cat(
substr buf, Arg
const& C4_RESTRICT a, Args
const& C4_RESTRICT ...more)
653 num +=
cat(buf, more...);
658template<
class... Args>
661 size_t sz =
cat(buf, args...);
662 C4_CHECK(sz <= buf.
len);
663 return {buf.
str, sz <= buf.
len ? sz : buf.
len};
689template<
class Arg,
class... Args>
690size_t uncat(
csubstr buf, Arg & C4_RESTRICT a, Args & C4_RESTRICT ...more)
696 size_t num =
uncat(buf, more...);
717C4_ALWAYS_INLINE
size_t catsep_more(substr , Sep
const& C4_RESTRICT )
722template<
class Sep,
class Arg,
class... Args>
723size_t catsep_more(substr buf, Sep
const& C4_RESTRICT sep, Arg
const& C4_RESTRICT a, Args
const& C4_RESTRICT ...more)
727 buf = buf.len >= ret ? buf.sub(ret) :
substr{};
730 buf = buf.len >= ret ? buf.sub(ret) :
substr{};
731 ret = catsep_more(buf, sep, more...);
773template<
class Sep,
class Arg,
class... Args>
774size_t catsep(
substr buf, Sep
const& C4_RESTRICT sep, Arg
const& C4_RESTRICT a, Args
const& C4_RESTRICT ...more)
778 num += detail::catsep_more(buf, sep, more...);
785template<
class... Args>
788 size_t sz =
catsep(buf, std::forward<Args>(args)...);
789 C4_CHECK(sz <= buf.
len);
790 return {buf.
str, sz <= buf.
len ? sz : buf.
len};
818template<
class Arg,
class... Args>
821 if(C4_LIKELY(sep.
len > 0))
823 size_t pos = buf.
find(sep);
935template<
class Arg,
class... Args>
938 size_t pos =
fmt.find(
"{}");
947 num =
format(buf,
fmt.sub(pos + 2), more...);
955template<
class... Args>
959 C4_CHECK(sz <= buf.
len);
960 return {buf.
str, sz <= buf.
len ? sz : buf.
len};
986template<
class Arg,
class... Args>
989 const size_t pos =
fmt.find(
"{}");
1039template<
class CharOwningContainer,
class... Args>
1040inline void catrs(CharOwningContainer * C4_RESTRICT cont, Args
const& C4_RESTRICT ...args)
1042 cont->resize(cont->capacity());
1045 size_t ret =
cat(buf, args...);
1074template<
class CharOwningContainer,
class... Args>
1075inline CharOwningContainer
catrs(Args
const& C4_RESTRICT ...args)
1077 CharOwningContainer cont;
1078 catrs(&cont, args...);
1108template<
class CharOwningContainer,
class... Args>
1111 const size_t pos = cont->
size();
1112 cont->resize(cont->capacity());
1115 size_t ret =
cat(buf, args...);
1116 cont->resize(pos + ret);
1151template<
class CharOwningContainer,
class Sep,
class... Args>
1152inline void catseprs(CharOwningContainer * C4_RESTRICT cont, Sep
const& C4_RESTRICT sep, Args
const& C4_RESTRICT ...args)
1154 cont->resize(cont->capacity());
1157 size_t ret =
catsep(buf, sep, args...);
1186template<
class CharOwningContainer,
class Sep,
class... Args>
1187inline CharOwningContainer
catseprs(Sep
const& C4_RESTRICT sep, Args
const& C4_RESTRICT ...args)
1189 CharOwningContainer cont;
1219template<
class CharOwningContainer,
class Sep,
class... Args>
1220inline csubstr catseprs_append(CharOwningContainer * C4_RESTRICT cont, Sep
const& C4_RESTRICT sep, Args
const& C4_RESTRICT ...args)
1222 const size_t pos = cont->
size();
1223 cont->resize(cont->capacity());
1226 size_t ret =
catsep(buf, sep, args...);
1227 cont->resize(pos + ret);
1262template<
class CharOwningContainer,
class... Args>
1263inline void formatrs(CharOwningContainer * C4_RESTRICT cont,
csubstr fmt, Args
const& C4_RESTRICT ...args)
1265 cont->resize(cont->capacity());
1297template<
class CharOwningContainer,
class... Args>
1300 CharOwningContainer cont;
1329template<
class CharOwningContainer,
class... Args>
1332 const size_t pos = cont->
size();
1333 C4_SUPPRESS_WARNING_GCC_WITH_PUSH(
"-Warray-bounds")
1334 cont->resize(cont->capacity());
1335 C4_SUPPRESS_WARNING_GCC_POP
1339 cont->resize(pos + ret);
1351# pragma warning(pop)
1352#elif defined(__clang__)
1353# pragma clang diagnostic pop
1354#elif defined(__GNUC__)
1355# pragma GCC diagnostic pop
Lightweight generic type-safe wrappers for converting individual values to/from strings.
right_< T > right(T val, size_t width, char padchar=' ')
tag function to mark an argument to be aligned right
center_< T > center(T val, size_t width, char padchar=' ')
tag function to mark an argument to be aligned center
left_< T > left(T val, size_t width, char padchar=' ')
tag type to mark an argument to be aligned left.
bool atox(csubstr s, uint8_t *v) noexcept
boolalpha_ boolalpha(T const &val=false)
tag function to mark a variable to be written as an alphabetic boolean, ie as either true or false
csubstr catrs_append(CharOwningContainer *cont, Args const &...args)
cat+resize+append: like c4::cat(), but receives a container, and appends to it instead of overwriting...
size_t cat(substr buf, Arg const &a, Args const &...more)
serialize the arguments, concatenating them to the given fixed-size buffer.
void catrs(CharOwningContainer *cont, Args const &...args)
cat+resize: like c4::cat(), but receives a container, and resizes it as needed to contain the result.
substr cat_sub(substr buf, Args const &...args)
like c4::cat() but return a substr instead of a size
csubstr catseprs_append(CharOwningContainer *cont, Sep const &sep, Args const &...args)
catsep+resize+append: like c4::catsep(), but receives a container, and appends the arguments,...
void catseprs(CharOwningContainer *cont, Sep const &sep, Args const &...args)
catsep+resize: like c4::catsep(), but receives a container, and resizes it as needed to contain the r...
size_t catsep(substr buf, Sep const &sep, Arg const &a, Args const &...more)
serialize the arguments, concatenating them to the given fixed-size buffer, using a separator between...
substr catsep_sub(substr buf, Args &&...args)
like c4::catsep() but return a substr instead of a size
@ FTOA_FLOAT
print the real number in floating point format (like f)
size_t dtoa(substr str, double v, int precision=-1, RealFormat_e formatting=FTOA_FLEX) noexcept
Convert a double-precision real number to string.
size_t from_chars_first(csubstr buf, uint8_t *v) noexcept
bool from_chars(csubstr buf, uint8_t *v) noexcept
size_t ftoa(substr str, float v, int precision=-1, RealFormat_e formatting=FTOA_FLEX) noexcept
Convert a single-precision real number to string.
integral_< intptr_t > hex(std::nullptr_t)
format null as an hexadecimal value
integral_< intptr_t > oct(std::nullptr_t)
format null as an octal value
integral_< T > integral(T val, T radix=10)
format an integral type with a custom radix
integral_< intptr_t > bin(std::nullptr_t)
format null as a binary 0-1 value
size_t itoa(substr buf, T v) noexcept
convert an integral signed decimal to a string.
overflow_checked_< T > overflow_checked(T &val)
auto overflows(csubstr str) noexcept -> typename std::enable_if< std::is_unsigned< T >::value, bool >::type
Test if the following string would overflow when converted to associated integral types; this functio...
const_raw_wrapper raw(cblob data, size_t alignment=alignof(max_align_t))
mark a variable to be written in raw binary format, using memcpy
raw_wrapper_< cbyte > const_raw_wrapper
raw_wrapper_< byte > raw_wrapper
const_raw_wrapper craw(cblob data, size_t alignment=alignof(max_align_t))
mark a variable to be written in raw binary format, using memcpy
real_< T > real(T val, int precision, RealFormat_e fmt=FTOA_FLOAT)
size_t to_chars(ryml::substr buf, vec2< T > v)
substr to_substr(char(&s)[N]) noexcept
csubstr to_csubstr(const char(&s)[N]) noexcept
basic_substring< char > substr
a mutable string view
basic_substring< const char > csubstr
an immutable string view
size_t to_chars(substr buf, uint8_t v) noexcept
size_t uncat(csubstr buf, Arg &a, Args &...more)
deserialize the arguments from the given buffer.
size_t uncatsep(csubstr buf, csubstr sep, Arg &a, Args &...more)
deserialize the arguments from the given buffer, using a separator.
size_t utoa(substr buf, T v) noexcept
convert an integral unsigned decimal to a string.
integral_padded_< T > zpad(T val, size_t num_digits)
pad the argument with zeroes on the left, with decimal radix
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
basic_substring range(size_t first, size_t last=npos) const noexcept
return [first,last[.
auto fill(C val) -> typename std::enable_if< !std::is_const< U >::value, void >::type
fill the entire contents with the given val
size_t len
the length of the substring
size_t find(const C c, size_t start_pos=0) const
size_t size() const noexcept
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
basic_substring sub(size_t first) const noexcept
return [first,len[
C * str
a restricted pointer to the first character of the substring
center_(T v, size_t w, char c) noexcept
format an integral type with a custom radix
C4_STATIC_ASSERT(std::is_integral< T >::value)
integral_(T val_, T radix_)
format an integral type with a custom radix, and pad with zeroes on the left
integral_padded_(T val_, T radix_, size_t nd)
C4_STATIC_ASSERT(std::is_integral< T >::value)
left_(T v, size_t w, char c) noexcept
overflow_checked_(T &val_)
raw_wrapper_(blob_< T > data, size_t alignment_) noexcept
real_(T v, int prec=-1, RealFormat_e f=FTOA_FLOAT)
right_(T v, size_t w, char c) noexcept