1 | // |
2 | // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. |
5 | // https://www.boost.org/LICENSE_1_0.txt |
6 | |
7 | #include <boost/locale/collator.hpp> |
8 | #include <boost/locale/generator.hpp> |
9 | #include <boost/locale/localization_backend.hpp> |
10 | #include "boostLocale/test/tools.hpp" |
11 | #include "boostLocale/test/unit_test.hpp" |
12 | #include <iomanip> |
13 | |
14 | template<typename Char> |
15 | void test_comp(const std::locale& l, // LCOV_EXCL_LINE |
16 | const std::basic_string<Char>& left, |
17 | const std::basic_string<Char>& right, |
18 | const boost::locale::collate_level level, |
19 | const int expected) |
20 | { |
21 | typedef std::basic_string<Char> string_type; |
22 | TEST_EQ(boost::locale::comparator<Char>(l, level)(left, right), (expected < 0)); |
23 | if(level == boost::locale::collate_level::identical) { |
24 | const std::collate<Char>& coll = std::use_facet<std::collate<Char>>(l); |
25 | string_type lt = coll.transform(left.c_str(), left.c_str() + left.size()); |
26 | string_type rt = coll.transform(right.c_str(), right.c_str() + right.size()); |
27 | if(expected < 0) |
28 | TEST_LT(lt, rt); |
29 | else if(expected == 0) |
30 | TEST_EQ(lt, rt); |
31 | else |
32 | TEST_GT(lt, rt); |
33 | long lh = coll.hash(left.c_str(), left.c_str() + left.size()); |
34 | long rh = coll.hash(right.c_str(), right.c_str() + right.size()); |
35 | if(expected == 0) |
36 | TEST_EQ(lh, rh); |
37 | else |
38 | TEST_NE(lh, rh); |
39 | } |
40 | const boost::locale::collator<Char>& coll = std::use_facet<boost::locale::collator<Char>>(l); |
41 | string_type lt = coll.transform(level, left.c_str(), left.c_str() + left.size()); |
42 | TEST_EQ(lt, coll.transform(level, left)); |
43 | string_type rt = coll.transform(level, right.c_str(), right.c_str() + right.size()); |
44 | TEST_EQ(rt, coll.transform(level, right)); |
45 | if(expected < 0) |
46 | TEST_LT(lt, rt); |
47 | else if(expected == 0) |
48 | TEST_EQ(lt, rt); |
49 | else |
50 | TEST_GT(lt, rt); |
51 | long lh = coll.hash(level, left.c_str(), left.c_str() + left.size()); |
52 | TEST_EQ(lh, coll.hash(level, left)); |
53 | long rh = coll.hash(level, right.c_str(), right.c_str() + right.size()); |
54 | TEST_EQ(rh, coll.hash(level, right)); |
55 | if(expected == 0) |
56 | TEST_EQ(lh, rh); |
57 | else |
58 | TEST_NE(lh, rh); |
59 | } // LCOV_EXCL_LINE |
60 | |
61 | #define TEST_COMP(c, _l, _r) test_comp<c>(l, _l, _r, level, expected) |
62 | |
63 | void compare(const std::string left, // LCOV_EXCL_LINE |
64 | const std::string right, |
65 | const boost::locale::collate_level level, |
66 | const int expected) |
67 | { |
68 | boost::locale::generator gen; |
69 | std::locale l = gen("en_US.UTF-8" ); |
70 | if(level == boost::locale::collate_level::identical) |
71 | TEST_EQ(l(left, right), (expected < 0)); |
72 | TEST_COMP(char, left, right); |
73 | TEST_COMP(wchar_t, to<wchar_t>(left), to<wchar_t>(right)); |
74 | #ifdef BOOST_LOCALE_ENABLE_CHAR16_T |
75 | TEST_COMP(char16_t, to<char16_t>(left), to<char16_t>(right)); |
76 | #endif |
77 | #ifdef BOOST_LOCALE_ENABLE_CHAR32_T |
78 | TEST_COMP(char32_t, to<char32_t>(left), to<char32_t>(right)); |
79 | #endif |
80 | } // LCOV_EXCL_LINE |
81 | |
82 | void test_collate() // LCOV_EXCL_LINE |
83 | { |
84 | constexpr int le = -1, gt = 1, eq = 0; |
85 | using boost::locale::collate_level; |
86 | |
87 | compare(left: "a" , right: "A" , level: collate_level::primary, expected: eq); |
88 | compare(left: "a" , right: "A" , level: collate_level::secondary, expected: eq); |
89 | compare(left: "A" , right: "a" , level: collate_level::tertiary, expected: gt); |
90 | compare(left: "a" , right: "A" , level: collate_level::tertiary, expected: le); |
91 | compare(left: "a" , right: "A" , level: collate_level::quaternary, expected: le); |
92 | compare(left: "A" , right: "a" , level: collate_level::quaternary, expected: gt); |
93 | compare(left: "a" , right: "A" , level: collate_level::identical, expected: le); |
94 | compare(left: "A" , right: "a" , level: collate_level::identical, expected: gt); |
95 | compare(left: "a" , right: "ä" , level: collate_level::primary, expected: eq); |
96 | compare(left: "a" , right: "ä" , level: collate_level::secondary, expected: le); |
97 | compare(left: "ä" , right: "a" , level: collate_level::secondary, expected: gt); |
98 | compare(left: "a" , right: "ä" , level: collate_level::quaternary, expected: le); |
99 | compare(left: "ä" , right: "a" , level: collate_level::quaternary, expected: gt); |
100 | compare(left: "a" , right: "ä" , level: collate_level::identical, expected: le); |
101 | compare(left: "ä" , right: "a" , level: collate_level::identical, expected: gt); |
102 | compare(left: "a" , right: "a" , level: collate_level::identical, expected: eq); |
103 | compare(left: "ä" , right: "ä" , level: collate_level::identical, expected: eq); |
104 | } // LCOV_EXCL_LINE |
105 | |
106 | BOOST_LOCALE_DISABLE_UNREACHABLE_CODE_WARNING |
107 | void test_main(int /*argc*/, char** /*argv*/) |
108 | { |
109 | #ifdef BOOST_LOCALE_NO_WINAPI_BACKEND |
110 | std::cout << "WinAPI Backend is not build... Skipping\n" ; |
111 | return; |
112 | #endif |
113 | boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global(); |
114 | mgr.select(backend_name: "winapi" ); |
115 | boost::locale::localization_backend_manager::global(mgr); |
116 | |
117 | test_collate(); |
118 | } |
119 | |
120 | // boostinspect:noascii |
121 | |