1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
#include <algorithm>
#include <cctype>
#include <ciso646>
#include <iterator>
#include <string>
// Here's our Case Insensitive type...
struct ci
{
const std::locale& loc;
const std::string& s;
ci( const std::string& s, const std::locale& loc = std::locale() ): loc(loc), s(s) { }
// ...and the core comparison functions...
struct lt { const std::locale &aloc, &bloc; bool operator () ( char a, char b ) const { return std::tolower( a, aloc ) < std::tolower( b, bloc ); } };
struct eq { const std::locale &aloc, &bloc; bool operator () ( char a, char b ) const { return std::tolower( a, aloc ) == std::tolower( b, bloc ); } };
struct gt { const std::locale &aloc, &bloc; bool operator () ( char a, char b ) const { return std::tolower( a, aloc ) > std::tolower( b, bloc ); } };
template <typename Predicate1, typename Predicate2>
static bool compare(
const std::string& a, const std::locale& aloc,
const std::string& b, const std::locale& bloc,
Predicate1 p1, Predicate2 p2 )
{
auto n = std::min( a.size(), b.size() );
auto m = std::mismatch( a.begin(), std::next( a.begin(), n ), b.begin(), ci::eq{ aloc, bloc } );
return (m.first == a.end()) ? p1( a.size(), b.size() ) : p2( *m.first, *m.second );
}
};
// ...and comparison operators
bool operator == ( const ci& a, const ci& b ) { return a.compare( a.s, a.loc, b.s, b.loc, []( auto a, auto b ) { return a == b; }, ci::eq{ a.loc, b.loc } ); }
bool operator < ( const ci& a, const ci& b ) { return a.compare( a.s, a.loc, b.s, b.loc, []( auto a, auto b ) { return a < b; }, ci::lt{ a.loc, b.loc } ); }
bool operator > ( const ci& a, const ci& b ) { return a.compare( a.s, a.loc, b.s, b.loc, []( auto a, auto b ) { return a > b; }, ci::gt{ a.loc, b.loc } ); }
bool operator != ( const ci& a, const ci& b ) { return !(a == b); }
bool operator <= ( const ci& a, const ci& b ) { return !(a > b); }
bool operator >= ( const ci& a, const ci& b ) { return !(a < b); }
bool operator == ( const std::string& a, const ci& b ) { return ci(a) == b; }
bool operator < ( const std::string& a, const ci& b ) { return ci(a) < b; }
bool operator > ( const std::string& a, const ci& b ) { return ci(a) > b; }
bool operator != ( const std::string& a, const ci& b ) { return ci(a) != b; }
bool operator <= ( const std::string& a, const ci& b ) { return ci(a) <= b; }
bool operator >= ( const std::string& a, const ci& b ) { return ci(a) >= b; }
bool operator == ( const ci& a, const std::string& b ) { return a == ci(b); }
bool operator < ( const ci& a, const std::string& b ) { return a < ci(b); }
bool operator > ( const ci& a, const std::string& b ) { return a > ci(b); }
bool operator != ( const ci& a, const std::string& b ) { return a != ci(b); }
bool operator <= ( const ci& a, const std::string& b ) { return a <= ci(b); }
bool operator >= ( const ci& a, const std::string& b ) { return a >= ci(b); }
|