大文字小文字を区別しない文字列比較

概要:
strcmpi(string compare ignore case)
大文字小文字を区別しない文字列比較

インターフェース

1
2
3
4
5
6
7
8
// 大文字小文字を区別しない文字列比較(std::locale)
bool string_compare_ignore_case(const std::string& X_, const std::string& Y_, const std::locale& loc = std::locale::classic());
// 大文字小文字を区別しない文字列比較(std::ctype<char>)
bool string_compare_ignore_case(const std::string& X_, const std::string& Y_, const std::ctype<char>& ct);
// 大文字小文字を区別せずにソートする(less)
void sort_string_ignore_case_less(TRandomAccessIterator F_, TRandomAccessIterator L_);
// 大文字小文字を区別せずにソートする(greater)
void sort_string_ignore_case_greater(TRandomAccessIterator F_, TRandomAccessIterator L_);

実装

 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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// #include <functional> //< std::less, std::greater, std::binary_function
// #include <locale> //< std::locale, std::use_facet, std::ctype
// #include <algorithm> //< std::lexicographical_compare, std::sort
// #include <iterator> //< std::iterator_traits


// 文字比較ファンクター
template<
    class TChar,
    class TBinaryPredicate = std::less< TChar >
>
class char_compare_ignore_case_fun_t : public std::binary_function<TChar, TChar, bool>
{
public:
    explicit char_compare_ignore_case_fun_t(
        const std::ctype<TChar>& c,
        const TBinaryPredicate& p = TBinaryPredicate()
    ) : ct_(c), predicate_(p) {}
    bool operator()(TChar X_, TChar Y_) const
    {
        return predicate_(ct_.toupper(X_), ct_.toupper(Y_));
    }
private:
    const std::ctype<TChar>& ct_;
    const TBinaryPredicate& predicate_;
};
// 文字列比較ファンクター
template<
    class TString,
    class TBinaryPredicate = std::less< typename TString::traits_type::char_type >
>
class string_compare_ignore_case_fun_t : std::binary_function<TString, TString, bool>
{
public:
    typedef typename TString::traits_type::char_type char_type;
    explicit string_compare_ignore_case_fun_t(
        const std::locale& loc = std::locale::classic(),
        const TBinaryPredicate& p = TBinaryPredicate()
    ) : locale_(loc), char_compare_(std::use_facet< std::ctype<char_type> >(locale_), p) {}
    bool operator()(const TString& X_, const TString& Y_) const
    {
        return std::lexicographical_compare(
            X_.begin(), X_.end(),
            Y_.begin(), Y_.end(),
            char_compare_
        );
    }
private:
    std::locale locale_;
    char_compare_ignore_case_fun_t< char_type, TBinaryPredicate > char_compare_;
};
// <string> //< std::string, std::wstring
typedef string_compare_ignore_case_fun_t< std::string, std::less< char > > string_compare_ignore_case_less;
typedef string_compare_ignore_case_fun_t< std::wstring, std::less< wchar_t > > wstring_compare_ignore_case_less;
typedef string_compare_ignore_case_fun_t< std::string, std::greater< char > > string_compare_ignore_case_greater;
typedef string_compare_ignore_case_fun_t< std::wstring, std::greater< wchar_t > > wstring_compare_ignore_case_greater;

// equal
template< class TChar, class TTraits, class TAllocator > inline
bool string_compare_ignore_case(
    const std::basic_string<TChar, TTraits, TAllocator>& X_,
    const std::basic_string<TChar, TTraits, TAllocator>& Y_,
    const std::ctype<TChar>& ct
) {
    typedef typename std::basic_string<TChar, TTraits, TAllocator> string_type;
    return ((X_.size() == Y_.size())
        && (std::equal(X_.begin(), X_.end(), Y_.begin(), char_compare_ignore_case_fun_t< TChar, std::equal_to<TChar> >(ct)))
    );
}
template< class TChar, class TTraits, class TAllocator > inline
bool string_compare_ignore_case(
    const std::basic_string<TChar, TTraits, TAllocator>& X_,
    const std::basic_string<TChar, TTraits, TAllocator>& Y_,
    const std::locale& loc = std::locale::classic()
) {
    typedef typename std::basic_string<TChar, TTraits, TAllocator> string_type;
    if (X_.size() == Y_.size()) {
        const std::ctype<TChar>& ct = std::use_facet< std::ctype<TChar> >(loc);
        return string_compare_ignore_case(X_, Y_, ct);
    }
    return false;
}
// sort
template< class TRandomAccessIterator > inline
void sort_string_ignore_case_less(TRandomAccessIterator F_, TRandomAccessIterator L_)
{
    typedef typename std::iterator_traits<TRandomAccessIterator>::value_type string_type;
    typedef typename string_type::traits_type::char_type char_type;
    std::sort(F_, L_, string_compare_ignore_case_fun_t< string_type, std::less< char_type > >());
}
template< class TRandomAccessIterator > inline
void sort_string_ignore_case_greater(TRandomAccessIterator F_, TRandomAccessIterator L_)
{
    typedef typename std::iterator_traits<TRandomAccessIterator>::value_type string_type;
    typedef typename string_type::traits_type::char_type char_type;
    std::sort(F_, L_, string_compare_ignore_case_fun_t< string_type, std::greater< char_type > >());
}