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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#include <glibmm.h>
#include <iostream>
// Helper class to check for non-existing overload
template<typename T>
struct Convertible
{
Convertible(const T&){};
};
static bool expect_missing_overload = false;
void
operator==(Convertible<std::string> const&, Glib::ustring const&)
{
g_assert_true(expect_missing_overload);
expect_missing_overload = false;
}
int
main(int, char**)
{
// allocating
static_assert(std::is_convertible<const char*, Glib::ustring>::value, "");
// non-allocating
static_assert(std::is_convertible<const char*, Glib::UStringView>::value, "");
static_assert(std::is_convertible<Glib::ustring, Glib::UStringView>::value, "");
// deliberately omitted
static_assert(!std::is_convertible<Glib::UStringView, Glib::ustring>::value, "");
static_assert(!std::is_convertible<Glib::UStringView, const char *>::value, "");
const char *cstr1 = "Hello";
const char *cstr2 = "World";
const char *cstr12 = "HelloWorld";
const char *cstr12_25 = "lloWo"; // cstr12[2:2 + 5]
Glib::ustring ustr1 = cstr1;
Glib::ustring ustr2 = cstr2;
Glib::ustring ustr12 = cstr12;
Glib::ustring ustr12_25 = cstr12_25;
Glib::UStringView vstr1 = cstr1;
Glib::UStringView vstr2 = cstr2;
Glib::UStringView vstr12_25 = cstr12_25;
g_assert_true(ustr1.compare(ustr1) == 0);
g_assert_true(ustr1.compare(cstr1) == 0);
g_assert_true(ustr1.compare(vstr1) == 0);
g_assert_true(ustr1.compare(ustr2) < 0);
g_assert_true(ustr1.compare(cstr2) < 0);
g_assert_true(ustr1.compare(vstr2) < 0);
g_assert_true(ustr12.compare(2, 5, ustr12_25) == 0);
g_assert_true(ustr12.compare(2, 5, cstr12_25) == 0);
g_assert_true(ustr12.compare(2, 5, vstr12_25) == 0);
g_assert_true(ustr1 == ustr1);
g_assert_true(ustr1 == cstr1);
g_assert_true(ustr1 == vstr1);
g_assert_true(cstr1 == ustr1);
g_assert_true(vstr1 == ustr1);
g_assert_true(ustr2 != ustr1);
g_assert_true(ustr2 != cstr1);
g_assert_true(ustr2 != vstr1);
g_assert_true(cstr2 != ustr1);
g_assert_true(vstr2 != ustr1);
g_assert_true(ustr2 > ustr1);
g_assert_true(ustr2 > cstr1);
g_assert_true(ustr2 > vstr1);
g_assert_true(cstr2 > ustr1);
g_assert_true(vstr2 > ustr1);
g_assert_false(ustr2 < ustr1);
g_assert_false(ustr2 < cstr1);
g_assert_false(ustr2 < vstr1);
g_assert_false(cstr2 < ustr1);
g_assert_false(vstr2 < ustr1);
g_assert_true(ustr2 >= ustr1);
g_assert_true(ustr2 >= cstr1);
g_assert_true(ustr2 >= vstr1);
g_assert_true(cstr2 >= ustr1);
g_assert_true(vstr2 >= ustr1);
g_assert_false(ustr2 <= ustr1);
g_assert_false(ustr2 <= cstr1);
g_assert_false(ustr2 <= vstr1);
g_assert_false(cstr2 <= ustr1);
g_assert_false(vstr2 <= ustr1);
// no conversions between std::string and UStringView and no comparison between
// std::string and ustring/UStringView
static_assert(!std::is_convertible<std::string, Glib::UStringView>::value, "");
static_assert(!std::is_convertible<Glib::UStringView, std::string>::value, "");
std::string sstr1 = cstr1;
// Would not compile without the helper overload
expect_missing_overload = true;
sstr1 == ustr1;
g_assert_false(expect_missing_overload);
// Doesn't compile because of missing Glib::ustring::compare overload (expected), but
// unfortunately not testable like the other way round.
#if 0
ustr1 == sstr1;
#endif
return EXIT_SUCCESS;
}
|