song list: get rid of boost::zip_iterator and improve {Const,}SongIterator
[ncmpcpp.git] / src / utility / comparators.cpp
blob81213b3669c23f49f0e500928aea7a63450f3754
1 /***************************************************************************
2 * Copyright (C) 2008-2016 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include <locale>
22 #include "comparators.h"
23 #include "format_impl.h"
24 #include "utility/string.h"
26 namespace {
28 bool hasTheWord(const std::string &s)
30 return s.length() >= 4
31 && (s[0] == 't' || s[0] == 'T')
32 && (s[1] == 'h' || s[1] == 'H')
33 && (s[2] == 'e' || s[2] == 'E')
34 && (s[3] == ' ');
39 int LocaleStringComparison::compare(const char *a, size_t a_len, const char *b, size_t b_len) const
41 size_t ac_off = 0, bc_off = 0;
42 if (m_ignore_the)
44 if (hasTheWord(a))
45 ac_off += 4;
46 if (hasTheWord(b))
47 bc_off += 4;
49 return std::use_facet<std::collate<char>>(m_locale).compare(
50 a+ac_off, a+a_len, b+bc_off, b+b_len
54 bool LocaleBasedItemSorting::operator()(const MPD::Item &a, const MPD::Item &b) const
56 bool result = false;
57 if (a.type() == b.type())
59 switch (m_sort_mode)
61 case SortMode::Name:
62 switch (a.type())
64 case MPD::Item::Type::Directory:
65 result = m_cmp(a.directory().path(), b.directory().path());
66 break;
67 case MPD::Item::Type::Playlist:
68 result = m_cmp(a.playlist().path(), b.playlist().path());
69 break;
70 case MPD::Item::Type::Song:
71 result = m_cmp(a.song(), b.song());
72 break;
74 break;
75 case SortMode::CustomFormat:
76 switch (a.type())
78 case MPD::Item::Type::Directory:
79 result = m_cmp(a.directory().path(), b.directory().path());
80 break;
81 case MPD::Item::Type::Playlist:
82 result = m_cmp(a.playlist().path(), b.playlist().path());
83 break;
84 case MPD::Item::Type::Song:
85 result = m_cmp(Format::stringify<char>(Config.browser_sort_format, &a.song()),
86 Format::stringify<char>(Config.browser_sort_format, &b.song()));
87 break;
89 break;
90 case SortMode::ModificationTime:
91 switch (a.type())
93 case MPD::Item::Type::Directory:
94 result = a.directory().lastModified() > b.directory().lastModified();
95 break;
96 case MPD::Item::Type::Playlist:
97 result = a.playlist().lastModified() > b.playlist().lastModified();
98 break;
99 case MPD::Item::Type::Song:
100 result = a.song().getMTime() > b.song().getMTime();
101 break;
103 break;
104 case SortMode::NoOp:
105 throw std::logic_error("can't sort with NoOp sorting mode");
108 else
109 result = a.type() < b.type();
110 return result;