make use of std::locale based strings comparison

This commit is contained in:
Andrzej Rybczak
2012-09-08 03:35:52 +02:00
parent a26b1f62f9
commit 057922d2a6
5 changed files with 63 additions and 68 deletions

View File

@@ -18,33 +18,37 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <locale>
#include "comparators.h"
#include "settings.h"
bool CaseInsensitiveStringComparison::hasTheWord(const char *s) const
bool LocaleStringComparison::hasTheWord(const std::string &s) const
{
return (s[0] == 't' || s[0] == 'T')
return s.length() >= 4
&& (s[0] == 't' || s[0] == 'T')
&& (s[1] == 'h' || s[1] == 'H')
&& (s[2] == 'e' || s[2] == 'E')
&& (s[3] == ' ');
}
int CaseInsensitiveStringComparison::operator()(const char *a, const char *b) const
int LocaleStringComparison::operator()(const std::string &a, const std::string &b) const
{
const char *ac = a.c_str();
const char *bc = b.c_str();
size_t ac_off = 0, bc_off = 0;
if (m_ignore_the)
{
if (hasTheWord(a))
a += 4;
ac_off += 4;
if (hasTheWord(b))
b += 4;
bc_off += 4;
}
int dist;
while (!(dist = tolower(*a)-tolower(*b)) && *b)
++a, ++b;
return dist;
return std::use_facet< std::collate<char> >(m_locale).compare(
ac+ac_off, ac+a.length(), bc+bc_off, bc+b.length()
);
}
CaseInsensitiveSorting::CaseInsensitiveSorting(): cmp(Config.ignore_leading_the) { }
CaseInsensitiveSorting::CaseInsensitiveSorting(): cmp(std::locale(""), Config.ignore_leading_the) { }
bool CaseInsensitiveSorting::operator()(const MPD::Item &a, const MPD::Item &b) const
{

View File

@@ -24,31 +24,23 @@
#include <string>
#include "mpdpp.h"
class CaseInsensitiveStringComparison
class LocaleStringComparison
{
std::locale m_locale;
bool m_ignore_the;
bool hasTheWord(const char *s) const;
bool hasTheWord(const std::string &s) const;
public:
CaseInsensitiveStringComparison(bool ignore_the) : m_ignore_the(ignore_the) { }
LocaleStringComparison(const std::locale &loc, bool ignore_the)
: m_locale(loc), m_ignore_the(ignore_the) { }
int operator()(const char *a, const char *b) const;
int operator()(const char *a, const std::string &b) const {
return (*this)(a, b.c_str());
}
int operator()(const std::string &a, const char *b) const {
return (*this)(a.c_str(), b);
}
int operator()(const std::string &a, const std::string &b) const {
return (*this)(a.c_str(), b.c_str());
}
int operator()(const std::string &a, const std::string &b) const;
};
class CaseInsensitiveSorting
{
CaseInsensitiveStringComparison cmp;
LocaleStringComparison cmp;
public:
CaseInsensitiveSorting();