allow octa::concat to work on non-range types that provide range interface

This commit is contained in:
q66 2015-05-31 19:50:00 +01:00
parent 10f5278c98
commit 71f40d9ee4

View file

@ -173,8 +173,16 @@ namespace octa {
typedef StringBase<char> String; typedef StringBase<char> String;
template<typename T>
struct __OctaIsRangeTest {
template<typename U> static char __octa_test(typename U::Category *);
template<typename U> static int __octa_test(...);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == sizeof(char));
};
template<typename R, typename F> template<typename R, typename F>
String concat(R range, String sep, F func) { String __octa_concat(R range, const String &sep, F func,
EnableIf<__OctaIsRangeTest<R>::value, bool> = true) {
String ret; String ret;
if (range.empty()) return move(ret); if (range.empty()) return move(ret);
for (;;) { for (;;) {
@ -186,8 +194,15 @@ namespace octa {
return move(ret); return move(ret);
} }
template<typename T, typename F>
String __octa_concat(const T &v, const String &sep, F func,
EnableIf<!__OctaIsRangeTest<T>::value, bool> = true) {
return __octa_concat(each(v), sep, func);
}
template<typename R> template<typename R>
String concat(R range, String sep = " ") { String __octa_concat(R range, const String &sep,
EnableIf<__OctaIsRangeTest<R>::value, bool> = true) {
String ret; String ret;
if (range.empty()) return move(ret); if (range.empty()) return move(ret);
for (;;) { for (;;) {
@ -199,14 +214,30 @@ namespace octa {
return move(ret); return move(ret);
} }
template<typename T>
String __octa_concat(const T &v, const String &sep,
EnableIf<!__OctaIsRangeTest<T>::value, bool> = true) {
return __octa_concat(each(v), sep);
}
template<typename T, typename F> template<typename T, typename F>
String concat(initializer_list<T> il, String sep, F func) { String concat(const T &v, const String &sep, F func) {
return concat(each(il), sep, func); return __octa_concat(v, sep, func);
} }
template<typename T> template<typename T>
String concat(initializer_list<T> il, String sep = " ") { String concat(const T &v, const String &sep = " ") {
return concat(each(il), sep); return __octa_concat(v, sep);
}
template<typename T, typename F>
String concat(initializer_list<T> v, const String &sep, F func) {
return __octa_concat(each(v), sep, func);
}
template<typename T>
String concat(initializer_list<T> v, const String &sep = " ") {
return __octa_concat(each(v), sep);
} }
template<typename T> template<typename T>