Created
September 29, 2017 14:21
-
-
Save elbeno/e091904904331fcdcd0389f51152ad82 to your computer and use it in GitHub Desktop.
Herb Sutter's SCM Challenge at CppCon 2017 - my winning code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <iostream> | |
#include <type_traits> | |
class CIString { | |
std::string s; | |
public: | |
CIString(std::string _s): s(_s) {}; | |
// functions want to be free! | |
friend inline bool operator==(const CIString& x, const CIString& y); | |
friend inline bool operator==(const char* x, const CIString& y); | |
friend inline bool operator==(const CIString& x, const char* y); | |
friend inline bool operator<(const CIString& x, const CIString& y); | |
friend inline bool operator<(const char* x, const CIString& y); | |
friend inline bool operator<(const CIString& x, const char* y); | |
}; | |
// case insensitive comparison function objects... | |
// insert arbitrary complexity here | |
struct ci_compare_equal | |
{ | |
bool operator()(char x, char y) const | |
{ | |
return std::toupper(x) == std::toupper(y); | |
} | |
}; | |
struct ci_compare_less | |
{ | |
bool operator()(char x, char y) const | |
{ | |
return std::toupper(x) < std::toupper(y); | |
} | |
}; | |
// operator== and operator< | |
inline bool operator==(const CIString& x, const CIString& y) | |
{ | |
return std::equal(x.s.cbegin(), x.s.cend(), | |
y.s.cbegin(), y.s.cend(), ci_compare_equal{}); | |
} | |
inline bool operator<(const CIString& x, const CIString& y) | |
{ | |
return std::lexicographical_compare(x.s.cbegin(), x.s.cend(), | |
y.s.cbegin(), y.s.cend(), ci_compare_less{}); | |
} | |
// other comparison operators in terms of operator== and operator< | |
// (or use std::rel_ops?) | |
inline bool operator!=(const CIString& x, const CIString& y) | |
{ | |
return !(x == y); | |
} | |
inline bool operator>(const CIString& x, const CIString& y) | |
{ | |
return y < x; | |
} | |
inline bool operator<=(const CIString& x, const CIString& y) | |
{ | |
return !(y < x); | |
} | |
inline bool operator>=(const CIString& x, const CIString& y) | |
{ | |
return !(x < y); | |
} | |
// now the same for comparing one way around... | |
inline bool operator==(const char* x, const CIString& y) | |
{ | |
const auto s = std::string_view(x); | |
return std::equal(s.cbegin(), s.cend(), | |
y.s.cbegin(), y.s.cend(), ci_compare_equal{}); | |
} | |
inline bool operator<(const char* x, const CIString& y) | |
{ | |
const auto s = std::string_view(x); | |
return std::lexicographical_compare(s.cbegin(), s.cend(), | |
y.s.cbegin(), y.s.cend(), ci_compare_less{}); | |
} | |
inline bool operator!=(const char* x, const CIString& y) | |
{ | |
return !(x == y); | |
} | |
inline bool operator>(const char* x, const CIString& y) | |
{ | |
return y < x; | |
} | |
inline bool operator<=(const char* x, const CIString& y) | |
{ | |
return !(y < x); | |
} | |
inline bool operator>=(const char* x, const CIString& y) | |
{ | |
return !(x < y); | |
} | |
// ...and the other way around | |
inline bool operator==(const CIString& x, const char* y) | |
{ | |
const auto s = std::string_view(y); | |
return std::equal(x.s.cbegin(), x.s.cend(), | |
s.cbegin(), s.cend(), ci_compare_equal{}); | |
} | |
inline bool operator<(const CIString& x, const char* y) | |
{ | |
const auto s = std::string_view(y); | |
return std::lexicographical_compare(x.s.cbegin(), x.s.cend(), | |
s.cbegin(), s.cend(), ci_compare_less{}); | |
} | |
inline bool operator!=(const CIString& x, const char* y) | |
{ | |
return !(x == y); | |
} | |
inline bool operator>(const CIString& x, const char* y) | |
{ | |
return y < x; | |
} | |
inline bool operator<=(const CIString& x, const char* y) | |
{ | |
return !(y < x); | |
} | |
inline bool operator>=(const CIString& x, const char* y) | |
{ | |
return !(x < y); | |
} | |
// I'm sure Herb will replace this all with half a dozen lines of spaceship operators :) | |
// You can use this function to write any tests you may want. | |
void tests() { | |
}; | |
int main() { | |
tests(); | |
// Added in the background | |
graderTests(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment