remove ostd::to_string and ostd::concat (both replaced by more flexible format)

master
Daniel Kolesa 2017-02-20 20:43:38 +01:00
parent 1e1f6d63a2
commit a23a42da1f
2 changed files with 10 additions and 247 deletions

View File

@ -869,6 +869,16 @@ inline auto citer(T const &r) -> decltype(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>
struct half_range: input_range<half_range<T>> {
using range_category = range_category_t <typename T::range>;

View File

@ -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>
struct temp_c_string {
private: