Here is the code:
template <typename L, typename R> bool eq (const L& lhs, const R& rhs) { return lhs == rhs; }
template<int N> bool eq(char* lhs, const char(&rhs)[N]) { return String(lhs).compare(rhs) == 0; }
template<int N> bool eq(const char(&lhs)[N], char* rhs) { return String(lhs).compare(rhs) == 0; }
inline bool eq(char* lhs, char* rhs) { return String(lhs).compare(rhs) == 0; }
inline bool eq(const char* lhs, const char* rhs) { return String(lhs).compare(rhs) == 0; }
inline bool eq(char* lhs, const char* rhs) { return String(lhs).compare(rhs) == 0; }
inline bool eq(const char* lhs, char* rhs) { return String(lhs).compare(rhs) == 0; }
I have to do this for neq/lt/gt/lte/gte and not just for equality. Maybe I've already missed something.
Is there a way to not list all the possible combinations of C string types?
Also C++98.
EDIT: >> here << is an online demo with the problem
Decay an array type to pointer:
template<class T>
struct decay_array { typedef T type; };
template<class T, size_t N>
struct decay_array<T[N]> { typedef T* type; };
template<class T>
struct decay_array<T[]> { typedef T* type; };
Check that a type is not a pointer to (possibly const
) char
:
template<class T>
struct not_char_pointer { enum { value = true }; };
template<>
struct not_char_pointer<char*> { enum { value = false }; };
template<>
struct not_char_pointer<const char*> { enum { value = false }; };
Now check that a type is not a pointer to or array of (possibly const
) char
:
template<class T>
struct can_use_op : not_char_pointer<typename decay_array<T>::type> {};
Reimplement std::enable_if
:
template<bool, class = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
and use it to constrain your template:
template <typename L, typename R>
typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
eq (const L& lhs, const R& rhs) { return lhs == rhs; }
Then just one overload is enough:
inline bool eq(const char* lhs, const char* rhs) { return String(lhs).compare(rhs) == 0; }