1 #ifndef CONVERSION_UTILITIES_STRINGBUILDER_H 2 #define CONVERSION_UTILITIES_STRINGBUILDER_H 4 #include "../misc/traits.h" 15 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>>...> std::size_t computeTupleElementSize(
const StringType *str)
20 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>>...> std::size_t computeTupleElementSize(
const StringType &str)
25 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>>...>
26 std::size_t computeTupleElementSize(
const CharType *str)
28 return std::char_traits<CharType>::length(str);
31 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>>...>
32 constexpr std::size_t computeTupleElementSize(CharType)
37 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType>>,
38 std::is_
integral<IntegralType>, std::is_
unsigned<IntegralType>>...>
39 std::size_t computeTupleElementSize(IntegralType number,
typename StringType::value_type base = 10)
42 for (
auto n = number; n; n /= base, ++size)
47 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType>>,
48 std::is_
integral<IntegralType>, std::is_
signed<IntegralType>>...>
49 std::size_t computeTupleElementSize(IntegralType number,
typename StringType::value_type base = 10)
51 std::size_t size = number < 0 ? 1 : 0;
52 for (
auto n = number; n; n /= base, ++size)
57 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>>...>
void append(StringType &target,
const StringType *str)
62 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>>...>
void append(StringType &target,
const StringType &str)
67 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>>...>
68 void append(StringType &target,
const CharType *str)
73 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>>...>
74 void append(StringType &target, CharType c)
79 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType>>,
80 std::is_
integral<IntegralType>, std::is_
unsigned<IntegralType>>...>
81 void append(StringType &target, IntegralType number,
typename StringType::value_type base = 10)
83 const auto start = target.begin() + target.size();
85 target.insert(start, digitToChar<typename StringType::value_type>(number % base));
90 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType>>,
91 std::is_
integral<IntegralType>, std::is_
signed<IntegralType>>...>
92 void append(StringType &target, IntegralType number,
typename StringType::value_type base = 10)
98 const auto start = target.begin() + target.size();
100 target.insert(start, digitToChar<typename StringType::value_type>(number % base));
105 template <
class StringType,
class Tuple, std::
size_t N>
struct TupleToString {
106 static std::size_t precomputeSize(
const Tuple &tuple)
108 return TupleToString<StringType, Tuple, N - 1>::precomputeSize(tuple) + computeTupleElementSize<StringType>(std::get<N - 1>(tuple));
111 static void append(
const Tuple &tuple, StringType &str)
113 TupleToString<StringType, Tuple, N - 1>::append(tuple, str);
114 Helper::append(str, std::get<N - 1>(tuple));
118 template <
class StringType,
class Tuple>
struct TupleToString<StringType, Tuple, 1> {
119 static std::size_t precomputeSize(
const Tuple &tuple)
121 return computeTupleElementSize<StringType>(std::get<0>(tuple));
124 static void append(
const Tuple &tuple, StringType &str)
126 Helper::append(str, std::get<0>(tuple));
135 template <
class StringType = std::string,
class... Args> StringType
tupleToString(
const std::tuple<Args...> &tuple)
138 res.reserve(Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::precomputeSize(tuple));
139 Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::append(tuple, res);
143 template <
class StringType = std::string,
class... Args> constexpr StringType
argsToString(Args &&... args)
151 template <
class Tuple> constexpr
auto operator%(
const Tuple &lhs,
const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
153 return std::tuple_cat(lhs, std::make_tuple(&rhs));
159 template <
class Tuple> constexpr
auto operator%(
const Tuple &lhs,
const char *rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
161 return std::tuple_cat(lhs, std::make_tuple(rhs));
167 template <
class Tuple,
typename IntegralType, Traits::EnableIf<std::is_
integral<IntegralType>>...>
168 constexpr
auto operator%(
const Tuple &lhs, IntegralType rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
170 return std::tuple_cat(lhs, std::make_tuple(rhs));
176 constexpr
auto operator%(
const std::string &lhs,
const std::string &rhs) -> decltype(std::make_tuple(&lhs, &rhs))
178 return std::make_tuple(&lhs, &rhs);
184 constexpr
auto operator%(
const char *lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
186 return std::make_tuple(lhs, &rhs);
192 constexpr
auto operator%(
const std::string &lhs,
const char *rhs) -> decltype(std::make_tuple(&lhs, rhs))
194 return std::make_tuple(&lhs, rhs);
200 constexpr
auto operator%(
const std::string &lhs,
char rhs) -> decltype(std::make_tuple(&lhs, rhs))
202 return std::make_tuple(&lhs, rhs);
208 constexpr
auto operator%(
char lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
210 return std::make_tuple(lhs, &rhs);
222 template <
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>>...>
223 inline std::string
operator+(
const Tuple &lhs,
const std::string &rhs)
225 return tupleToString(std::tuple_cat(lhs, std::make_tuple(&rhs)));
237 template <
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>>...>
238 inline std::string
operator+(
const Tuple &lhs,
const char *rhs)
240 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
252 template <
class Tuple,
typename IntegralType, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>, std::is_
integral<IntegralType>>...>
253 inline std::string
operator+(
const Tuple &lhs, IntegralType rhs)
255 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
259 #endif // CONVERSION_UTILITIES_STRINGBUILDER_H
constexpr StringType argsToString(Args &&... args)
Contains several functions providing conversions between different data types.
constexpr auto operator%(const Tuple &lhs, const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
Allows construction of string-tuples via %-operator, eg.
std::string operator+(const Tuple &lhs, const std::string &rhs)
Allows construction of final string from previously constructed string-tuple and trailing string via ...
StringType tupleToString(const std::tuple< Args... > &tuple)
Concatenates all strings hold by the specified tuple.