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>> * =
nullptr> std::size_t computeTupleElementSize(
const StringType *str)
20 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>> * =
nullptr> std::size_t computeTupleElementSize(
const StringType &str)
25 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>> * =
nullptr>
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>> * =
nullptr>
32 constexpr std::size_t computeTupleElementSize(CharType)
37 template <
class StringType,
typename IntegralType,
39 std::is_unsigned<IntegralType>> * =
nullptr>
40 std::size_t computeTupleElementSize(IntegralType number,
typename StringType::value_type base = 10)
43 for (
auto n = number; n; n /= base, ++size)
48 template <
class StringType,
typename IntegralType,
50 std::is_signed<IntegralType>> * =
nullptr>
51 std::size_t computeTupleElementSize(IntegralType number,
typename StringType::value_type base = 10)
53 std::size_t size = number < 0 ? 1 : 0;
54 for (
auto n = number; n; n /= base, ++size)
59 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>> * =
nullptr>
void append(StringType &target,
const StringType *str)
64 template <
class StringType, Traits::EnableIf<std::is_
class<StringType>> * =
nullptr>
void append(StringType &target,
const StringType &str)
69 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>> * =
nullptr>
70 void append(StringType &target,
const CharType *str)
75 template <
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType>> * =
nullptr>
76 void append(StringType &target, CharType c)
81 template <
class StringType,
typename IntegralType,
83 std::is_unsigned<IntegralType>> * =
nullptr>
84 void append(StringType &target, IntegralType number,
typename StringType::value_type base = 10)
86 const auto start = target.begin() + target.size();
88 target.insert(start, digitToChar<typename StringType::value_type>(number % base));
93 template <
class StringType,
typename IntegralType,
95 std::is_signed<IntegralType>> * =
nullptr>
96 void append(StringType &target, IntegralType number,
typename StringType::value_type base = 10)
102 const auto start = target.begin() + target.size();
104 target.insert(start, digitToChar<typename StringType::value_type>(number % base));
109 template <
class StringType,
class Tuple, std::
size_t N>
struct TupleToString {
110 static std::size_t precomputeSize(
const Tuple &tuple)
112 return TupleToString<StringType, Tuple, N - 1>::precomputeSize(tuple) + computeTupleElementSize<StringType>(std::get<N - 1>(tuple));
115 static void append(
const Tuple &tuple, StringType &str)
117 TupleToString<StringType, Tuple, N - 1>::append(tuple, str);
118 Helper::append(str, std::get<N - 1>(tuple));
122 template <
class StringType,
class Tuple>
struct TupleToString<StringType, Tuple, 1> {
123 static std::size_t precomputeSize(
const Tuple &tuple)
125 return computeTupleElementSize<StringType>(std::get<0>(tuple));
128 static void append(
const Tuple &tuple, StringType &str)
130 Helper::append(str, std::get<0>(tuple));
139 template <
class StringType = std::string,
class... Args> StringType
tupleToString(
const std::tuple<Args...> &tuple)
142 res.reserve(Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::precomputeSize(tuple));
143 Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::append(tuple, res);
147 template <
class StringType = std::string,
class... Args> constexpr StringType
argsToString(Args &&... args)
155 template <
class Tuple> constexpr
auto operator%(
const Tuple &lhs,
const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
157 return std::tuple_cat(lhs, std::make_tuple(&rhs));
163 template <
class Tuple> constexpr
auto operator%(
const Tuple &lhs,
const char *rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
165 return std::tuple_cat(lhs, std::make_tuple(rhs));
171 template <
class Tuple,
typename IntegralType, Traits::EnableIf<std::is_
integral<IntegralType>> * =
nullptr>
172 constexpr
auto operator%(
const Tuple &lhs, IntegralType rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
174 return std::tuple_cat(lhs, std::make_tuple(rhs));
180 constexpr
auto operator%(
const std::string &lhs,
const std::string &rhs) -> decltype(std::make_tuple(&lhs, &rhs))
182 return std::make_tuple(&lhs, &rhs);
188 constexpr
auto operator%(
const char *lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
190 return std::make_tuple(lhs, &rhs);
196 constexpr
auto operator%(
const std::string &lhs,
const char *rhs) -> decltype(std::make_tuple(&lhs, rhs))
198 return std::make_tuple(&lhs, rhs);
204 constexpr
auto operator%(
const std::string &lhs,
char rhs) -> decltype(std::make_tuple(&lhs, rhs))
206 return std::make_tuple(&lhs, rhs);
212 constexpr
auto operator%(
char lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
214 return std::make_tuple(lhs, &rhs);
226 template <
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>> * =
nullptr>
227 inline std::string
operator+(
const Tuple &lhs,
const std::string &rhs)
229 return tupleToString(std::tuple_cat(lhs, std::make_tuple(&rhs)));
241 template <
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>> * =
nullptr>
242 inline std::string
operator+(
const Tuple &lhs,
const char *rhs)
244 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
256 template <
class Tuple,
typename IntegralType,
258 inline std::string
operator+(
const Tuple &lhs, IntegralType rhs)
260 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
264 #endif // CONVERSION_UTILITIES_STRINGBUILDER_H
constexpr StringType argsToString(Args &&... args)
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
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.