1 #ifndef CONVERSION_UTILITIES_STRINGBUILDER_H 2 #define CONVERSION_UTILITIES_STRINGBUILDER_H 5 #include "../misc/traits.h" 16 template<
class StringType, Traits::EnableIf<std::is_
class<StringType> >...>
17 std::size_t computeTupleElementSize(
const StringType *str)
22 template<
class StringType, Traits::EnableIf<std::is_
class<StringType> >...>
23 std::size_t computeTupleElementSize(
const StringType &str)
28 template<
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType> >...>
29 std::size_t computeTupleElementSize(
const CharType *str)
31 return std::char_traits<CharType>::length(str);
34 template<
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType> >...>
35 constexpr std::size_t computeTupleElementSize(CharType)
40 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType> >, std::is_
integral<IntegralType>, std::is_
unsigned<IntegralType> >...>
41 std::size_t computeTupleElementSize(IntegralType number,
typename StringType::value_type base = 10)
44 for(
auto n = number; n; n /= base, ++size);
48 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType> >, 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);
56 template<
class StringType, Traits::EnableIf<std::is_
class<StringType> >...>
57 void append(StringType &target,
const StringType *str)
62 template<
class StringType, Traits::EnableIf<std::is_
class<StringType> >...>
63 void append(StringType &target,
const StringType &str)
68 template<
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType> >...>
69 void append(StringType &target,
const CharType *str)
74 template<
class StringType,
class CharType, Traits::EnableIf<std::is_same<
typename StringType::value_type, CharType> >...>
75 void append(StringType &target, CharType c)
80 template <
class StringType,
typename IntegralType, Traits::EnableIf<Traits::Not<std::is_same<
typename StringType::value_type, IntegralType> >, 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> >, std::is_
integral<IntegralType>, std::is_
signed<IntegralType> >...>
91 void append(StringType &target, IntegralType number,
typename StringType::value_type base = 10)
97 const auto start = target.begin() + target.size();
99 target.insert(start, digitToChar<typename StringType::value_type>(number % base));
104 template<
class StringType,
class Tuple, std::
size_t N>
105 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>
119 struct TupleToString<StringType, Tuple, 1> {
120 static std::size_t precomputeSize(
const Tuple &tuple)
122 return computeTupleElementSize<StringType>(std::get<0>(tuple));
125 static void append(
const Tuple &tuple, StringType &str)
127 Helper::append(str, std::get<0>(tuple));
137 template<
class StringType = std::string,
class... Args>
141 res.reserve(Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::precomputeSize(tuple));
142 Helper::TupleToString<StringType, decltype(tuple),
sizeof...(Args)>::append(tuple, res);
146 template<
class StringType = std::string,
class... Args>
155 template<
class Tuple>
156 constexpr
auto operator %(
const Tuple &lhs,
const std::string &rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(&rhs)))
158 return std::tuple_cat(lhs, std::make_tuple(&rhs));
164 template<
class Tuple>
165 constexpr
auto operator %(
const Tuple &lhs,
const char *rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
167 return std::tuple_cat(lhs, std::make_tuple(rhs));
173 template<
class Tuple,
typename IntegralType, Traits::EnableIf<std::is_
integral<IntegralType> >...>
174 constexpr
auto operator %(
const Tuple &lhs, IntegralType rhs) -> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
176 return std::tuple_cat(lhs, std::make_tuple(rhs));
182 constexpr
auto operator %(
const std::string &lhs,
const std::string &rhs) -> decltype(std::make_tuple(&lhs, &rhs))
184 return std::make_tuple(&lhs, &rhs);
190 constexpr
auto operator %(
const char *lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
192 return std::make_tuple(lhs, &rhs);
198 constexpr
auto operator %(
const std::string &lhs,
const char *rhs) -> decltype(std::make_tuple(&lhs, rhs))
200 return std::make_tuple(&lhs, rhs);
206 constexpr
auto operator %(
const std::string &lhs,
char rhs) -> decltype(std::make_tuple(&lhs, rhs))
208 return std::make_tuple(&lhs, rhs);
214 constexpr
auto operator %(
char lhs,
const std::string &rhs) -> decltype(std::make_tuple(lhs, &rhs))
216 return std::make_tuple(lhs, &rhs);
228 template<
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...>
229 inline std::string
operator +(
const Tuple &lhs,
const std::string &rhs)
231 return tupleToString(std::tuple_cat(lhs, std::make_tuple(&rhs)));
243 template<
class Tuple, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple> >...>
244 inline std::string
operator +(
const Tuple &lhs,
const char *rhs)
246 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
258 template<
class Tuple,
typename IntegralType, Traits::EnableIf<Traits::IsSpecializationOf<Tuple, std::tuple>, std::is_
integral<IntegralType> >...>
259 inline std::string
operator +(
const Tuple &lhs, IntegralType rhs)
261 return tupleToString(std::tuple_cat(lhs, std::make_tuple(rhs)));
266 #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.