forked from OctaForge/libostd
remove ostd::to_string and ostd::concat (both replaced by more flexible format)
parent
1e1f6d63a2
commit
a23a42da1f
|
@ -869,6 +869,16 @@ inline auto citer(T const &r) -> decltype(ranged_traits<T const>::iter(r)) {
|
||||||
return ranged_traits<T const>::iter(r);
|
return ranged_traits<T const>::iter(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
static std::true_type test_iterable(decltype(ostd::iter(std::declval<T>())) *);
|
||||||
|
template<typename>
|
||||||
|
static std::false_type test_iterable(...);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool iterable_test = decltype(test_iterable<T>(0))::value;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct half_range: input_range<half_range<T>> {
|
struct half_range: input_range<half_range<T>> {
|
||||||
using range_category = range_category_t <typename T::range>;
|
using range_category = range_category_t <typename T::range>;
|
||||||
|
|
247
ostd/string.hh
247
ostd/string.hh
|
@ -431,253 +431,6 @@ inline namespace string_literals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: redesign this */
|
|
||||||
template<typename R, typename T, typename F>
|
|
||||||
R &&concat(R &&sink, T const &v, string_range sep, F func) {
|
|
||||||
auto range = ostd::iter(v);
|
|
||||||
if (range.empty()) {
|
|
||||||
return std::forward<R>(sink);
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
using VT = decltype(func(range.front()));
|
|
||||||
static_assert(
|
|
||||||
std::is_convertible_v<VT, string_range> ||
|
|
||||||
std::is_convertible_v<VT, char>,
|
|
||||||
"range value must be convertible to string range or char"
|
|
||||||
);
|
|
||||||
if constexpr(std::is_convertible_v<VT, string_range>) {
|
|
||||||
range_put_all(sink, string_range{func(range.front())});
|
|
||||||
} else {
|
|
||||||
sink.put(func(range.front()));
|
|
||||||
}
|
|
||||||
range.pop_front();
|
|
||||||
if (range.empty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
range_put_all(sink, sep);
|
|
||||||
}
|
|
||||||
return std::forward<R>(sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T>
|
|
||||||
R &&concat(R &&sink, T const &v, string_range sep = " ") {
|
|
||||||
auto range = ostd::iter(v);
|
|
||||||
if (range.empty()) {
|
|
||||||
return std::forward<R>(sink);
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
string_range ret = range.front();
|
|
||||||
range_put_all(sink, ret);
|
|
||||||
range.pop_front();
|
|
||||||
if (range.empty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
range_put_all(sink, sep);
|
|
||||||
}
|
|
||||||
return std::forward<R>(sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T, typename F>
|
|
||||||
R &&concat(R &&sink, std::initializer_list<T> v, string_range sep, F func) {
|
|
||||||
return concat(sink, ostd::iter(v), sep, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T>
|
|
||||||
R &&concat(R &&sink, std::initializer_list<T> v, string_range sep = " ") {
|
|
||||||
return concat(sink, ostd::iter(v), sep);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<typename T, typename R>
|
|
||||||
static std::true_type test_stringify(
|
|
||||||
decltype(std::declval<T const &>().to_string(std::declval<R &>())) *
|
|
||||||
);
|
|
||||||
|
|
||||||
template<typename, typename>
|
|
||||||
static std::false_type test_stringify(...);
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
constexpr bool stringify_test = decltype(test_stringify<T, R>(0))::value;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static std::true_type test_iterable(decltype(ostd::iter(std::declval<T>())) *);
|
|
||||||
template<typename>
|
|
||||||
static std::false_type test_iterable(...);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool iterable_test = decltype(test_iterable<T>(0))::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename = void>
|
|
||||||
struct to_string;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct to_string<T, std::enable_if_t<detail::iterable_test<T>>> {
|
|
||||||
std::string operator()(T const &v) const {
|
|
||||||
std::string ret("{");
|
|
||||||
auto x = appender_range<std::string>{};
|
|
||||||
concat(x, ostd::iter(v), ", ", to_string<
|
|
||||||
std::remove_const_t<std::remove_reference_t<
|
|
||||||
range_reference_t<decltype(ostd::iter(v))>
|
|
||||||
>>
|
|
||||||
>());
|
|
||||||
ret += x.get();
|
|
||||||
ret += "}";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct to_string<T, std::enable_if_t<
|
|
||||||
detail::stringify_test<T, appender_range<std::string>>
|
|
||||||
>> {
|
|
||||||
std::string operator()(T const &v) const {
|
|
||||||
auto app = appender<std::string>();
|
|
||||||
if (!v.to_string(app)) {
|
|
||||||
return std::string{};
|
|
||||||
}
|
|
||||||
return std::move(app.get());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<bool> {
|
|
||||||
std::string operator()(bool b) {
|
|
||||||
return b ? "true" : "false";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<char> {
|
|
||||||
std::string operator()(char c) {
|
|
||||||
std::string ret;
|
|
||||||
ret += c;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OSTD_TOSTR_NUM(T) \
|
|
||||||
template<> \
|
|
||||||
struct to_string<T> { \
|
|
||||||
std::string operator()(T v) { \
|
|
||||||
return std::to_string(v); \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
OSTD_TOSTR_NUM(sbyte)
|
|
||||||
OSTD_TOSTR_NUM(short)
|
|
||||||
OSTD_TOSTR_NUM(int)
|
|
||||||
OSTD_TOSTR_NUM(long)
|
|
||||||
OSTD_TOSTR_NUM(float)
|
|
||||||
OSTD_TOSTR_NUM(double)
|
|
||||||
|
|
||||||
OSTD_TOSTR_NUM(byte)
|
|
||||||
OSTD_TOSTR_NUM(ushort)
|
|
||||||
OSTD_TOSTR_NUM(uint)
|
|
||||||
OSTD_TOSTR_NUM(ulong)
|
|
||||||
OSTD_TOSTR_NUM(llong)
|
|
||||||
OSTD_TOSTR_NUM(ullong)
|
|
||||||
OSTD_TOSTR_NUM(ldouble)
|
|
||||||
|
|
||||||
#undef OSTD_TOSTR_NUM
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct to_string<T *> {
|
|
||||||
std::string operator()(T *v) {
|
|
||||||
char buf[16];
|
|
||||||
sprintf(buf, "%p", v);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<char const *> {
|
|
||||||
std::string operator()(char const *s) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<char *> {
|
|
||||||
std::string operator()(char *s) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<std::string> {
|
|
||||||
std::string operator()(std::string const &s) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<char_range> {
|
|
||||||
std::string operator()(char_range const &s) {
|
|
||||||
return std::string{s};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct to_string<string_range> {
|
|
||||||
std::string operator()(string_range const &s) {
|
|
||||||
return std::string{s};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename U>
|
|
||||||
struct to_string<std::pair<T, U>> {
|
|
||||||
std::string operator()(std::pair<T, U> const &v) {
|
|
||||||
std::string ret{"{"};
|
|
||||||
ret += to_string<std::remove_cv_t<std::remove_reference_t<T>>>()(v.first);
|
|
||||||
ret += ", ";
|
|
||||||
ret += to_string<std::remove_cv_t<std::remove_reference_t<U>>>()(v.second);
|
|
||||||
ret += "}";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<size_t I, size_t N>
|
|
||||||
struct tuple_to_str {
|
|
||||||
template<typename T>
|
|
||||||
static void append(std::string &ret, T const &tup) {
|
|
||||||
ret += ", ";
|
|
||||||
ret += to_string<std::remove_cv_t<std::remove_reference_t<
|
|
||||||
decltype(std::get<I>(tup))
|
|
||||||
>>>()(std::get<I>(tup));
|
|
||||||
tuple_to_str<I + 1, N>::append(ret, tup);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t N>
|
|
||||||
struct tuple_to_str<N, N> {
|
|
||||||
template<typename T>
|
|
||||||
static void append(std::string &, T const &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t N>
|
|
||||||
struct tuple_to_str<0, N> {
|
|
||||||
template<typename T>
|
|
||||||
static void append(std::string &ret, T const &tup) {
|
|
||||||
ret += to_string<std::remove_cv_t<std::remove_reference_t<
|
|
||||||
decltype(std::get<0>(tup))
|
|
||||||
>>>()(std::get<0>(tup));
|
|
||||||
tuple_to_str<1, N>::append(ret, tup);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...T>
|
|
||||||
struct to_string<std::tuple<T...>> {
|
|
||||||
std::string operator()(std::tuple<T...> const &v) {
|
|
||||||
std::string ret("{");
|
|
||||||
detail::tuple_to_str<0, sizeof...(T)>::append(ret, v);
|
|
||||||
ret += "}";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
struct temp_c_string {
|
struct temp_c_string {
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue