Skip to content

Commit c8eb3b5

Browse files
committed
Add xtd::string_comparer properties and methods
1 parent 1d957c1 commit c8eb3b5

File tree

2 files changed

+160
-6
lines changed

2 files changed

+160
-6
lines changed

src/xtd.core/include/xtd/string_comparer.hpp

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,51 @@ namespace xtd {
2424
/// xtd
2525
/// @par Library
2626
/// xtd.core
27-
/// @ingroup xtd_core
27+
/// @ingroup xtd_core system
2828
class string_comparer : public xtd::object, public xtd::collections::generic::icomparer<xtd::string>, public xtd::collections::generic::iequality_comparer<xtd::string> {
2929
public:
3030
/// @name Public Static Properties
3131

3232
/// @{
33+
/// @brief Gets a xtd::string_comparer object that performs a case-sensitive string comparison using the word comparison rules of the current culture.
34+
/// @return A xtd::string_comparer object.
35+
/// @remarks The xtd::string_comparer returned by the xtd::string_comparer::current_culture property can be used when strings are linguistically relevant. For example, if strings are displayed to the user, or if strings are the result of user interaction, culture-sensitive string comparison should be used to order the string data.
36+
/// @remarks The current culture is the xtd::globalization::culture_info object associated with the current thread.
37+
/// @remarks The xtd::::string_comparer::current_culture property actually returns an instance of an anonymous class derived from the ::string_comparer class.
38+
/// @remarks Each call to the ::string_comparer::current_culture property get accessor returns a new ::string_comparer object, as the following code shows.
39+
/// ```
40+
/// void compare_current_culture_string_comparer() {
41+
/// string_comparer string_comparer1 = string_comparer::current_culture;
42+
/// string_comparer string_comparer2 = string_comparer::current_culture;
43+
/// // Displays false
44+
/// console::write_line(string_comparer::reference_equals(string_comparer1, string_comparer2));
45+
/// }
46+
/// ```
47+
/// @remarks To improve performance, you can store the xtd::string_comparer object in a local variable rather than retrieve the value of the xtd::string_comparer::current_culture property multiple times.
48+
static string_comparer current_culture();
49+
50+
/// @brief Gets a xtd::string_comparer object that performs case-insensitive string comparisons using the word comparison rules of the current culture.
51+
/// @return A xtd::string_comparer object.
52+
/// @remarks The current culture is the xtd::globalization::culture_info object associated with the current thread; it is returned by the xtd::globalization::culture_info::current_culture property.
53+
/// @remarks The xtd::string_comparer returned by the xtd::string_comparer::current_culture_ignore_case property can be used when strings are linguistically relevant but their case is not. For example, if strings are displayed to the user but case is unimportant, culture-sensitive, case-insensitive string comparison should be used to order the string data.
54+
/// @note xtd running on Linux and macOS systems only: The collation behavior for the C and Posix cultures is always case-sensitive because these cultures do not use the expected Unicode collation order. We recommend that you use a culture other than C or Posix for performing culture-sensitive, case-insensitive sorting operations.
55+
/// @remarks The xtd::string_comparer::current_culture_ignore_case property actually returns an instance of an anonymous class derived from the xtd::string_comparer class.
56+
/// @remarks Each call to the xtd::string_comparer::current_culture_ignore_case property get accessor returns a new xtd::string_comparer object, as the following code shows.
57+
/// ```
58+
/// void compare_current_culture_string_comparer() {
59+
/// string_comparer string_comparer1 = string_comparer::current_culture_ignore_case;
60+
/// string_comparer string_comparer2 = string_comparer::current_culture_ignore_case;
61+
/// // Displays false
62+
/// console::write_line(string_comparer::reference_equals(string_comparer1, string_comparer2));
63+
/// }
64+
/// ```
65+
/// @remarks To improve performance, you can store the xtd::string_comparer object in a local variable rather than retrieve the value of the xtd::string_comparer::current_culture_ignore_case property multiple times.
66+
static string_comparer current_culture_ignore_case();
67+
68+
static string_comparer invariant_culture();
69+
70+
static string_comparer invariant_culture_ignore_case();
71+
3372
/// @brief Gets a xtd::string_comparer object that performs a case-sensitive ordinal string comparison.
3473
/// @return A xtd::string_comparer object.
3574
/// @remarks The xtd::string_comparer returned by the xtd::string_comparer::ordinal property performs a simple byte comparison that is independent of language. This is most appropriate when comparing strings that are generated programmatically or when comparing case-sensitive resources such as passwords.
@@ -84,7 +123,14 @@ namespace xtd {
84123
/// @remarks The xtd::string_comparer::compare(const string&, const string&) method is slightly more efficient than the xtd::string_comparer::compare(const object_t&, consy object_t&) method because no conversion of the `x` and `y` arguments is needed to perform the comparison.
85124
int32 compare(const xtd::string& x, const xtd::string& y) const noexcept override;
86125

87-
using xtd::object::equals;
126+
/// @brief Determines whether the specified object is equal to the current object.
127+
/// @param obj The object to compare with the current object.
128+
/// @return true if the specified object is equal to the current object. otherwise, false.
129+
/// @par Examples
130+
/// The following code example compares the current instance with another object.
131+
/// @include object_equals.cpp
132+
bool equals(const object& obj) const noexcept override;
133+
88134
/// @brief When overridden in a derived class, indicates whether two objects are equal.
89135
/// @param x An object to compare to `y`.
90136
/// @param y An object to compare to `x`.
@@ -111,7 +157,7 @@ namespace xtd {
111157
/// @return `true` if `x` and `y` refer to the same object, or `x` and `y` are both the same type of object and those objects are equal; otherwise, `false`.
112158
/// @remarks The xtd::string_comparer::equals(const string&, const string&) method is slightly more efficient than the xtd::string_comparer::equals(const object_t&, consy object_t&) method because no conversion of the `x` and `y` arguments is needed to perform the comparison.
113159
bool equals(const xtd::string& x, const xtd::string& y) const noexcept override;
114-
160+
115161
using xtd::object::get_hash_code;
116162
/// @brief When overridden in a derived class, gets the hash code for the specified object.
117163
/// @param obj An object.
@@ -133,17 +179,48 @@ namespace xtd {
133179
xtd::size get_hash_code(const xtd::string& obj) const noexcept override;
134180
/// @}
135181

182+
/// @name Public Static Methods
183+
184+
/// @{
185+
/// @brief Converts the specified xtd::string_comparison instance to a StringComparer instance.
186+
/// @param comparison A string comparer instance to convert.
187+
/// @return A xtd::string_comparer instance representing the equivalent value of the specified xtd::string_comparison instance.
188+
/// @exception xtd::argument_exception The specified string comparison is not supported.
189+
static string_comparer from_comparison(xtd::string_comparison comparison);
190+
/// @}
191+
136192
protected:
137193
/// @name Protected Constructors
138194

139195
/// @{
196+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
197+
/*
198+
/// @brief Creates a xtd::string_comparer object that compares strings according to the rules of a specified culture.
199+
/// @param culture A culture whose linguistic rules are used to perform a string comparison.
200+
/// @param ignore_case `true` to specify that comparison operations be case-insensitive; `false` to specify that comparison operations be case-sensitive.
201+
/// @return A new xtd::string_comparer object that performs string comparisons according to the comparison rules used by the `culture` parameter and the case rule specified by the `ignore_case` parameter.
202+
string_comparer create(const xtd::globalization::culture_info& culture, bool ignore_case);
203+
204+
/// @brief Creates a xtd::string_comparer object that compares strings according to the rules of a specified culture and string options.
205+
/// @param culture A culture whose linguistic rules are used to perform a string comparison.
206+
/// @param options A bitwise combination of the xtd::globalization::compare_options values.
207+
/// @exception xtd::argument_exception `options` has invalid flags.
208+
string_comparer create(const xtd::globalization::culture_info& culture, xtd::globalization::compare_options options);
209+
*/
210+
140211
/// @brief Initializes a new instance of the xtd::string_comparer class.
141212
string_comparer() = default;
142213
/// @}
143214

144215

145216
private:
146-
explicit string_comparer(xtd::string_comparison comparison) : comparison_ {comparison} {}
217+
explicit string_comparer(xtd::string_comparison comparison);
218+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
219+
/*
220+
string_comparer(const xtd::globalization::culture_info& culture, xtd::globalization::compare_options options);
221+
xtd::globalization::culture_info culture_ = xtd::globalization::culture_info::empty;
222+
xtd::globalization::compare_options options_ = xtd::globalization::compare_options::none;
223+
*/
147224
xtd::string_comparison comparison_ = xtd::string_comparison::ordinal;
148225
};
149226
}
Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,114 @@
11
#include "../../include/xtd/argument_exception.hpp"
22
#include "../../include/xtd/is.hpp"
33
#include "../../include/xtd/string_comparer.hpp"
4+
#include "../../include/xtd/not_implemented_exception.hpp"
45

56
using namespace xtd;
7+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
8+
//using namespace xtd::globalization;
9+
10+
string_comparer string_comparer::current_culture() {
11+
throw not_implemented_exception {};
12+
//return create(culture_info::current_culture);
13+
}
14+
15+
string_comparer string_comparer::current_culture_ignore_case() {
16+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
17+
throw not_implemented_exception {};
18+
//return create(culture_info::current_culture, true);
19+
}
20+
21+
string_comparer string_comparer::invariant_culture() {
22+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
23+
throw not_implemented_exception {};
24+
//return create(culture_info::invariant_culture);
25+
}
26+
27+
string_comparer string_comparer::invariant_culture_ignore_case() {
28+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
29+
throw not_implemented_exception {};
30+
//return create(culture_info::invariant_culture, true);
31+
}
632

733
const string_comparer& string_comparer::ordinal() {
8-
static auto result = string_comparer(string_comparison::ordinal);
34+
static auto result = from_comparison(string_comparison::ordinal);
935
return result;
1036
}
1137

1238
const string_comparer& string_comparer::ordinal_ignore_case() {
13-
static auto result = string_comparer(string_comparison::ordinal_ignore_case);
39+
static auto result = from_comparison(string_comparison::ordinal_ignore_case);
1440
return result;
1541
}
1642

1743
int32 string_comparer::compare(const xtd::string& x, const xtd::string& y) const noexcept {
44+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
1845
switch (comparison_) {
46+
case string_comparison::current_culture:
47+
case string_comparison::invariant_culture:
1948
case string_comparison::ordinal: return x.compare_to(y);
49+
case string_comparison::current_culture_ignore_case:
50+
case string_comparison::invariant_culture_ignore_case:
2051
case string_comparison::ordinal_ignore_case: return x.to_lower().compare_to(y.to_lower());
2152
}
2253
}
2354

2455
bool string_comparer::equals(const string& x, const string& y) const noexcept {
2556
if (&x == &y) return true;
57+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
2658
switch (comparison_) {
59+
case string_comparison::current_culture:
60+
case string_comparison::invariant_culture:
2761
case string_comparison::ordinal: return x.equals(y);
62+
case string_comparison::current_culture_ignore_case:
63+
case string_comparison::invariant_culture_ignore_case:
2864
case string_comparison::ordinal_ignore_case: return x.to_lower().equals(y.to_lower());
2965
}
3066
}
3167

68+
bool string_comparer::equals(const object& obj) const noexcept {
69+
return is<string_comparer>(obj) && reinterpret_cast<const string_comparer&>(obj).comparison_ == comparison_;
70+
}
71+
3272
xtd::size string_comparer::get_hash_code(const string& obj) const noexcept {
73+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
3374
switch (comparison_) {
75+
case string_comparison::current_culture:
76+
case string_comparison::invariant_culture:
3477
case string_comparison::ordinal: return obj.get_hash_code();
78+
case string_comparison::current_culture_ignore_case:
79+
case string_comparison::invariant_culture_ignore_case:
3580
case string_comparison::ordinal_ignore_case: return obj.to_lower().get_hash_code();
3681
}
3782
}
83+
84+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
85+
/*
86+
string_comparer string_comparer::create(const culture_info& culture, bool ignore_case) {
87+
return create {culture, compare_options::ignore_case};
88+
}
89+
90+
string_comparer string_comparer::create(const culture_info& culture, compare_options options) {
91+
return string_comparer {culture, options};
92+
}*/
93+
94+
string_comparer string_comparer::from_comparison(xtd::string_comparison comparison) {
95+
return string_comparer {comparison};
96+
}
97+
98+
string_comparer::string_comparer(string_comparison comparison) : comparison_ {comparison} {
99+
/// @todo Remove following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
100+
if (comparison == string_comparison::current_culture) throw not_implemented_exception {};
101+
if (comparison == string_comparison::current_culture_ignore_case) throw not_implemented_exception {};
102+
if (comparison == string_comparison::invariant_culture) throw not_implemented_exception {};
103+
if (comparison == string_comparison::invariant_culture_ignore_case) throw not_implemented_exception {};
104+
105+
if (!enum_object<>::is_defined(comparison)) throw argument_exception {};
106+
}
107+
108+
/// @todo Uncomment following lines when xtd::globalization::culture_info and xtd::globalization::compare_options are developped.
109+
/*
110+
string_comparer::string_comparer(const culture_info& culture, compare_options options) {
111+
culture_ = culture;
112+
options_ = options;
113+
}
114+
*/

0 commit comments

Comments
 (0)