8
8
#define BOOST_LOCALE_COLLATOR_HPP_INCLUDED
9
9
10
10
#include < boost/locale/config.hpp>
11
+ #include < boost/locale/detail/facet_id.hpp>
11
12
#include < locale>
12
13
13
14
#ifdef BOOST_MSVC
@@ -43,17 +44,16 @@ namespace boost { namespace locale {
43
44
44
45
// / \brief Collation facet.
45
46
// /
46
- // / It reimplements standard C++ std::collate,
47
- // / allowing usage of std::locale for direct string comparison
47
+ // / It reimplements standard C++ std::collate with support for collation levels
48
48
template <typename CharType>
49
- class collator : public std ::collate< CharType> {
49
+ class BOOST_SYMBOL_VISIBLE collator : public std::locale::facet, public detail::facet_id<collator< CharType> > {
50
50
public:
51
51
// / Type of the underlying character
52
52
typedef CharType char_type;
53
53
// / Type of string used with this facet
54
54
typedef std::basic_string<CharType> string_type;
55
55
56
- // / Compare two strings in rage [b1,e1), [b2,e2) according using a collation level \a level. Calls do_compare
56
+ // / Compare two strings in range [b1,e1), [b2,e2) according to collation level \a level. Calls do_compare
57
57
// /
58
58
// / Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if
59
59
// / they considered equal.
@@ -66,6 +66,13 @@ namespace boost { namespace locale {
66
66
return do_compare (level, b1, e1 , b2, e2 );
67
67
}
68
68
69
+ // / Default compare function as-in std::collate that does not take collation level into account.
70
+ // / Uses identical level
71
+ int compare (const char_type* b1, const char_type* e1 , const char_type* b2, const char_type* e2 ) const
72
+ {
73
+ return compare (collate_level::identical, b1, e1 , b2, e2 );
74
+ }
75
+
69
76
// / Create a binary string that can be compared to other in order to get collation order. The string is created
70
77
// / for text in range [b,e). It is useful for collation of multiple strings for text.
71
78
// /
@@ -80,13 +87,24 @@ namespace boost { namespace locale {
80
87
return do_transform (level, b, e);
81
88
}
82
89
90
+ // / Default transform function as-in std::collate that does not take collation level into account.
91
+ // / Uses identical level
92
+ string_type transform (const char_type* b, const char_type* e) const
93
+ {
94
+ return transform (collate_level::identical, b, e);
95
+ }
96
+
83
97
// / Calculate a hash of a text in range [b,e). The value can be used for collation sensitive string comparison.
84
98
// /
85
99
// / If compare(level,b1,e1,b2,e2) == 0 then hash(level,b1,e1) == hash(level,b2,e2)
86
100
// /
87
101
// / Calls do_hash
88
102
long hash (collate_level level, const char_type* b, const char_type* e) const { return do_hash (level, b, e); }
89
103
104
+ // / Default hash function as-in std::collate that does not take collation level into account.
105
+ // / Uses identical level
106
+ long hash (const char_type* b, const char_type* e) const { return hash (collate_level::identical, b, e); }
107
+
90
108
// / Compare two strings \a l and \a r using collation level \a level
91
109
// /
92
110
// / Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if
@@ -107,7 +125,7 @@ namespace boost { namespace locale {
107
125
// / Create a binary string from string \a s, that can be compared to other, useful for collation of multiple
108
126
// / strings.
109
127
// /
110
- // / The transformation follows these rules :
128
+ // / The transformation follows this rule :
111
129
// / \code
112
130
// / compare(level,s1,s2) == sign( transform(level,s1).compare(transform(level,s2)) );
113
131
// / \endcode
@@ -118,29 +136,7 @@ namespace boost { namespace locale {
118
136
119
137
protected:
120
138
// / constructor of the collator object
121
- collator (size_t refs = 0 ) : std::collate<CharType>(refs) {}
122
-
123
- // / This function is used to override default collation function that does not take in account collation level.
124
- // / Uses primary level
125
- int
126
- do_compare (const char_type* b1, const char_type* e1 , const char_type* b2, const char_type* e2 ) const override
127
- {
128
- return do_compare (collate_level::identical, b1, e1 , b2, e2 );
129
- }
130
-
131
- // / This function is used to override default collation function that does not take in account collation level.
132
- // / Uses primary level
133
- string_type do_transform (const char_type* b, const char_type* e) const override
134
- {
135
- return do_transform (collate_level::identical, b, e);
136
- }
137
-
138
- // / This function is used to override default collation function that does not take in account collation level.
139
- // / Uses primary level
140
- long do_hash (const char_type* b, const char_type* e) const override
141
- {
142
- return do_hash (collate_level::identical, b, e);
143
- }
139
+ collator (size_t refs = 0 ) : std::locale::facet(refs) {}
144
140
145
141
// / Actual function that performs comparison between the strings. For details see compare member function. Can
146
142
// / be overridden.
@@ -157,7 +153,7 @@ namespace boost { namespace locale {
157
153
};
158
154
159
155
// / \brief This class can be used in STL algorithms and containers for comparison of strings
160
- // / with a level other than primary
156
+ // / with a level other than identical
161
157
// /
162
158
// / For example:
163
159
// /
@@ -169,21 +165,22 @@ namespace boost { namespace locale {
169
165
template <typename CharType, collate_level default_level = collate_level::identical>
170
166
struct comparator {
171
167
public:
172
- // / Create a comparator class for locale \a l and with collation leval \a level
168
+ // / Create a comparator class for locale \a l and with collation level \a level
173
169
// /
174
170
// / \throws std::bad_cast: \a l does not have \ref collator facet installed
175
171
comparator (const std::locale& l = std::locale(), collate_level level = default_level) :
176
- locale_ (l), level_(level)
172
+ locale_ (l), collator_(std::use_facet<collator<CharType>>(locale_)), level_(level)
177
173
{}
178
174
179
175
// / Compare two strings -- equivalent to return left < right according to collation rules
180
176
bool operator ()(const std::basic_string<CharType>& left, const std::basic_string<CharType>& right) const
181
177
{
182
- return std::use_facet<collator<CharType>>(locale_) .compare (level_, left, right) < 0 ;
178
+ return collator_ .compare (level_, left, right) < 0 ;
183
179
}
184
180
185
181
private:
186
182
std::locale locale_;
183
+ const collator<CharType>& collator_;
187
184
collate_level level_;
188
185
};
189
186
0 commit comments