sassc 2.0.1 → 2.1.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -0,0 +1,909 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "ast.hpp"
6
+ #include "context.hpp"
7
+ #include "node.hpp"
8
+ #include "eval.hpp"
9
+ #include "extend.hpp"
10
+ #include "emitter.hpp"
11
+ #include "color_maps.hpp"
12
+ #include "ast_fwd_decl.hpp"
13
+ #include <set>
14
+ #include <iomanip>
15
+ #include <iostream>
16
+ #include <algorithm>
17
+ #include <functional>
18
+ #include <cctype>
19
+ #include <locale>
20
+
21
+ #include "ast_selectors.hpp"
22
+
23
+ namespace Sass {
24
+
25
+ /*#########################################################################*/
26
+ /*#########################################################################*/
27
+
28
+ bool Selector_List::operator== (const Selector& rhs) const
29
+ {
30
+ if (auto sl = Cast<Selector_List>(&rhs)) { return *this == *sl; }
31
+ else if (auto ss = Cast<Simple_Selector>(&rhs)) { return *this == *ss; }
32
+ else if (auto cpx = Cast<Complex_Selector>(&rhs)) { return *this == *cpx; }
33
+ else if (auto cpd = Cast<Compound_Selector>(&rhs)) { return *this == *cpd; }
34
+ else if (auto ls = Cast<List>(&rhs)) { return *this == *ls; }
35
+ throw std::runtime_error("invalid selector base classes to compare");
36
+ }
37
+
38
+ bool Selector_List::operator< (const Selector& rhs) const
39
+ {
40
+ if (auto sl = Cast<Selector_List>(&rhs)) { return *this < *sl; }
41
+ else if (auto ss = Cast<Simple_Selector>(&rhs)) { return *this < *ss; }
42
+ else if (auto cpx = Cast<Complex_Selector>(&rhs)) { return *this < *cpx; }
43
+ else if (auto cpd = Cast<Compound_Selector>(&rhs)) { return *this < *cpd; }
44
+ else if (auto ls = Cast<List>(&rhs)) { return *this < *ls; }
45
+ throw std::runtime_error("invalid selector base classes to compare");
46
+ }
47
+
48
+ // Selector lists can be compared to comma lists
49
+ bool Selector_List::operator== (const Expression& rhs) const
50
+ {
51
+ if (auto l = Cast<List>(&rhs)) { return *this == *l; }
52
+ if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
53
+ if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }
54
+ throw std::runtime_error("invalid selector base classes to compare");
55
+ }
56
+
57
+ // Selector lists can be compared to comma lists
58
+ bool Selector_List::operator< (const Expression& rhs) const
59
+ {
60
+ if (auto l = Cast<List>(&rhs)) { return *this < *l; }
61
+ if (auto s = Cast<Selector>(&rhs)) { return *this < *s; }
62
+ if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return true; }
63
+ throw std::runtime_error("invalid selector base classes to compare");
64
+ }
65
+
66
+ bool Complex_Selector::operator== (const Selector& rhs) const
67
+ {
68
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
69
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
70
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
71
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
72
+ throw std::runtime_error("invalid selector base classes to compare");
73
+ }
74
+
75
+ bool Complex_Selector::operator< (const Selector& rhs) const
76
+ {
77
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
78
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
79
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
80
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
81
+ throw std::runtime_error("invalid selector base classes to compare");
82
+ }
83
+
84
+ bool Compound_Selector::operator== (const Selector& rhs) const
85
+ {
86
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
87
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
88
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
89
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
90
+ throw std::runtime_error("invalid selector base classes to compare");
91
+ }
92
+
93
+ bool Compound_Selector::operator< (const Selector& rhs) const
94
+ {
95
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
96
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
97
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
98
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
99
+ throw std::runtime_error("invalid selector base classes to compare");
100
+ }
101
+
102
+ bool Selector_Schema::operator== (const Selector& rhs) const
103
+ {
104
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
105
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
106
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
107
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
108
+ throw std::runtime_error("invalid selector base classes to compare");
109
+ }
110
+
111
+ bool Selector_Schema::operator< (const Selector& rhs) const
112
+ {
113
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
114
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
115
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
116
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
117
+ throw std::runtime_error("invalid selector base classes to compare");
118
+ }
119
+
120
+ bool Simple_Selector::operator== (const Selector& rhs) const
121
+ {
122
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
123
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
124
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
125
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
126
+ throw std::runtime_error("invalid selector base classes to compare");
127
+ }
128
+
129
+ bool Simple_Selector::operator< (const Selector& rhs) const
130
+ {
131
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
132
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
133
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
134
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
135
+ throw std::runtime_error("invalid selector base classes to compare");
136
+ }
137
+
138
+ /*#########################################################################*/
139
+ /*#########################################################################*/
140
+
141
+ bool Selector_List::operator< (const Selector_List& rhs) const
142
+ {
143
+ size_t l = rhs.length();
144
+ if (length() < l) l = length();
145
+ for (size_t i = 0; i < l; i ++) {
146
+ if (*at(i) < *rhs.at(i)) return true;
147
+ if (*at(i) != *rhs.at(i)) return false;
148
+ }
149
+ return false;
150
+ }
151
+
152
+ bool Selector_List::operator== (const Selector_List& rhs) const
153
+ {
154
+ if (&rhs == this) return true;
155
+ if (rhs.length() != length()) return false;
156
+ std::unordered_set<const Complex_Selector *, HashPtr, ComparePtrs> lhs_set;
157
+ lhs_set.reserve(length());
158
+ for (const Complex_Selector_Obj &element : elements()) {
159
+ lhs_set.insert(element.ptr());
160
+ }
161
+ for (const Complex_Selector_Obj &element : rhs.elements()) {
162
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
163
+ }
164
+ return true;
165
+ }
166
+
167
+ bool Compound_Selector::operator< (const Compound_Selector& rhs) const
168
+ {
169
+ size_t L = std::min(length(), rhs.length());
170
+ for (size_t i = 0; i < L; ++i)
171
+ {
172
+ Simple_Selector* l = (*this)[i];
173
+ Simple_Selector* r = rhs[i];
174
+ if (!l && !r) return false;
175
+ else if (!r) return false;
176
+ else if (!l) return true;
177
+ else if (*l != *r)
178
+ { return *l < *r; }
179
+ }
180
+ // just compare the length now
181
+ return length() < rhs.length();
182
+ }
183
+
184
+ bool Compound_Selector::operator== (const Compound_Selector& rhs) const
185
+ {
186
+ if (&rhs == this) return true;
187
+ if (rhs.length() != length()) return false;
188
+ std::unordered_set<const Simple_Selector *, HashPtr, ComparePtrs> lhs_set;
189
+ lhs_set.reserve(length());
190
+ for (const Simple_Selector_Obj &element : elements()) {
191
+ lhs_set.insert(element.ptr());
192
+ }
193
+ // there is no break?!
194
+ for (const Simple_Selector_Obj &element : rhs.elements()) {
195
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
196
+ }
197
+ return true;
198
+ }
199
+
200
+ bool Complex_Selector::operator< (const Complex_Selector& rhs) const
201
+ {
202
+ // const iterators for tails
203
+ const Complex_Selector* l = this;
204
+ const Complex_Selector* r = &rhs;
205
+ Compound_Selector* l_h = NULL;
206
+ Compound_Selector* r_h = NULL;
207
+ if (l) l_h = l->head();
208
+ if (r) r_h = r->head();
209
+ // process all tails
210
+ while (true)
211
+ {
212
+ #ifdef DEBUG
213
+ // skip empty ancestor first
214
+ if (l && l->is_empty_ancestor())
215
+ {
216
+ l_h = NULL;
217
+ l = l->tail();
218
+ if(l) l_h = l->head();
219
+ continue;
220
+ }
221
+ // skip empty ancestor first
222
+ if (r && r->is_empty_ancestor())
223
+ {
224
+ r_h = NULL;
225
+ r = r->tail();
226
+ if (r) r_h = r->head();
227
+ continue;
228
+ }
229
+ #endif
230
+ // check for valid selectors
231
+ if (!l) return !!r;
232
+ if (!r) return false;
233
+ // both are null
234
+ else if (!l_h && !r_h)
235
+ {
236
+ // check combinator after heads
237
+ if (l->combinator() != r->combinator())
238
+ { return l->combinator() < r->combinator(); }
239
+ // advance to next tails
240
+ l = l->tail();
241
+ r = r->tail();
242
+ // fetch the next headers
243
+ l_h = NULL; r_h = NULL;
244
+ if (l) l_h = l->head();
245
+ if (r) r_h = r->head();
246
+ }
247
+ // one side is null
248
+ else if (!r_h) return true;
249
+ else if (!l_h) return false;
250
+ // heads ok and equal
251
+ else if (*l_h == *r_h)
252
+ {
253
+ // check combinator after heads
254
+ if (l->combinator() != r->combinator())
255
+ { return l->combinator() < r->combinator(); }
256
+ // advance to next tails
257
+ l = l->tail();
258
+ r = r->tail();
259
+ // fetch the next headers
260
+ l_h = NULL; r_h = NULL;
261
+ if (l) l_h = l->head();
262
+ if (r) r_h = r->head();
263
+ }
264
+ // heads are not equal
265
+ else return *l_h < *r_h;
266
+ }
267
+ }
268
+
269
+ bool Complex_Selector::operator== (const Complex_Selector& rhs) const
270
+ {
271
+ // const iterators for tails
272
+ const Complex_Selector* l = this;
273
+ const Complex_Selector* r = &rhs;
274
+ Compound_Selector* l_h = NULL;
275
+ Compound_Selector* r_h = NULL;
276
+ if (l) l_h = l->head();
277
+ if (r) r_h = r->head();
278
+ // process all tails
279
+ while (true)
280
+ {
281
+ // check the pointers
282
+ if (!r) return !l;
283
+ if (!l) return !r;
284
+ // both are null
285
+ if (!l_h && !r_h)
286
+ {
287
+ // check combinator after heads
288
+ if (l->combinator() != r->combinator())
289
+ { return l->combinator() < r->combinator(); }
290
+ // advance to next tails
291
+ l = l->tail();
292
+ r = r->tail();
293
+ // fetch the next heads
294
+ l_h = NULL; r_h = NULL;
295
+ if (l) l_h = l->head();
296
+ if (r) r_h = r->head();
297
+ }
298
+ // equals if other head is empty
299
+ else if ((!l_h && !r_h) ||
300
+ (!l_h && r_h->empty()) ||
301
+ (!r_h && l_h->empty()) ||
302
+ (l_h && r_h && *l_h == *r_h))
303
+ {
304
+ // check combinator after heads
305
+ if (l->combinator() != r->combinator())
306
+ { return l->combinator() == r->combinator(); }
307
+ // advance to next tails
308
+ l = l->tail();
309
+ r = r->tail();
310
+ // fetch the next heads
311
+ l_h = NULL; r_h = NULL;
312
+ if (l) l_h = l->head();
313
+ if (r) r_h = r->head();
314
+ }
315
+ // abort
316
+ else break;
317
+ }
318
+ // unreachable
319
+ return false;
320
+ }
321
+
322
+ /*#########################################################################*/
323
+ /*#########################################################################*/
324
+
325
+ bool Selector_List::operator== (const Complex_Selector& rhs) const
326
+ {
327
+ size_t len = length();
328
+ if (len > 1) return false;
329
+ if (len == 0) return rhs.empty();
330
+ return *at(0) == rhs;
331
+ }
332
+
333
+ bool Selector_List::operator< (const Complex_Selector& rhs) const
334
+ {
335
+ size_t len = length();
336
+ if (len > 1) return false;
337
+ if (len == 0) return !rhs.empty();
338
+ return *at(0) < rhs;
339
+ }
340
+
341
+ bool Selector_List::operator== (const Compound_Selector& rhs) const
342
+ {
343
+ size_t len = length();
344
+ if (len > 1) return false;
345
+ if (len == 0) return rhs.empty();
346
+ return *at(0) == rhs;
347
+ }
348
+
349
+ bool Selector_List::operator< (const Compound_Selector& rhs) const
350
+ {
351
+ size_t len = length();
352
+ if (len > 1) return false;
353
+ if (len == 0) return !rhs.empty();
354
+ return *at(0) < rhs;
355
+ }
356
+
357
+ bool Selector_List::operator== (const Simple_Selector& rhs) const
358
+ {
359
+ size_t len = length();
360
+ if (len > 1) return false;
361
+ if (len == 0) return rhs.empty();
362
+ return *at(0) == rhs;
363
+ }
364
+
365
+ bool Selector_List::operator< (const Simple_Selector& rhs) const
366
+ {
367
+ size_t len = length();
368
+ if (len > 1) return false;
369
+ if (len == 0) return !rhs.empty();
370
+ return *at(0) < rhs;
371
+ }
372
+
373
+ /***************************************************************************/
374
+ /***************************************************************************/
375
+
376
+ bool Complex_Selector::operator== (const Selector_List& rhs) const
377
+ {
378
+ size_t len = rhs.length();
379
+ if (len > 1) return false;
380
+ if (len == 0) return empty();
381
+ return *this == *rhs.at(0);
382
+ }
383
+
384
+ bool Complex_Selector::operator< (const Selector_List& rhs) const
385
+ {
386
+ size_t len = rhs.length();
387
+ if (len > 1) return true;
388
+ if (len == 0) return false;
389
+ return *this < *rhs.at(0);
390
+ }
391
+
392
+ bool Complex_Selector::operator== (const Compound_Selector& rhs) const
393
+ {
394
+ if (tail()) return false;
395
+ if (!head()) return rhs.empty();
396
+ return *head() == rhs;
397
+ }
398
+
399
+ bool Complex_Selector::operator< (const Compound_Selector& rhs) const
400
+ {
401
+ if (tail()) return false;
402
+ if (!head()) return !rhs.empty();
403
+ return *head() < rhs;
404
+ }
405
+
406
+ bool Complex_Selector::operator== (const Simple_Selector& rhs) const
407
+ {
408
+ if (tail()) return false;
409
+ if (!head()) return rhs.empty();
410
+ return *head() == rhs;
411
+ }
412
+
413
+ bool Complex_Selector::operator< (const Simple_Selector& rhs) const
414
+ {
415
+ if (tail()) return false;
416
+ if (!head()) return !rhs.empty();
417
+ return *head() < rhs;
418
+ }
419
+
420
+ /***************************************************************************/
421
+ /***************************************************************************/
422
+
423
+ bool Compound_Selector::operator== (const Selector_List& rhs) const
424
+ {
425
+ size_t len = rhs.length();
426
+ if (len > 1) return false;
427
+ if (len == 0) return empty();
428
+ return *this == *rhs.at(0);
429
+ }
430
+
431
+ bool Compound_Selector::operator< (const Selector_List& rhs) const
432
+ {
433
+ size_t len = rhs.length();
434
+ if (len > 1) return true;
435
+ if (len == 0) return false;
436
+ return *this < *rhs.at(0);
437
+ }
438
+
439
+ bool Compound_Selector::operator== (const Complex_Selector& rhs) const
440
+ {
441
+ if (rhs.tail()) return false;
442
+ if (!rhs.head()) return empty();
443
+ return *this == *rhs.head();
444
+ }
445
+
446
+ bool Compound_Selector::operator< (const Complex_Selector& rhs) const
447
+ {
448
+ if (rhs.tail()) return true;
449
+ if (!rhs.head()) return false;
450
+ return *this < *rhs.head();
451
+ }
452
+
453
+ bool Compound_Selector::operator< (const Simple_Selector& rhs) const
454
+ {
455
+ size_t len = length();
456
+ if (len > 1) return false;
457
+ if (len == 0) return rhs.empty();
458
+ return *at(0) == rhs;
459
+ }
460
+
461
+ bool Compound_Selector::operator== (const Simple_Selector& rhs) const
462
+ {
463
+ size_t len = length();
464
+ if (len > 1) return false;
465
+ if (len == 0) return !rhs.empty();
466
+ return *at(0) < rhs;
467
+ }
468
+
469
+ /***************************************************************************/
470
+ /***************************************************************************/
471
+
472
+ bool Simple_Selector::operator== (const Selector_List& rhs) const
473
+ {
474
+ return rhs.length() == 1 && *this == *rhs.at(0);
475
+ }
476
+
477
+ bool Simple_Selector::operator< (const Selector_List& rhs) const
478
+ {
479
+ size_t len = rhs.length();
480
+ if (len > 1) return true;
481
+ if (len == 0) return false;
482
+ return *this < *rhs.at(0);
483
+ }
484
+
485
+ bool Simple_Selector::operator== (const Complex_Selector& rhs) const
486
+ {
487
+ return !rhs.tail() && rhs.head() &&
488
+ rhs.combinator() == Complex_Selector::ANCESTOR_OF &&
489
+ *this == *rhs.head();
490
+ }
491
+
492
+ bool Simple_Selector::operator< (const Complex_Selector& rhs) const
493
+ {
494
+ if (rhs.tail()) return true;
495
+ if (!rhs.head()) return false;
496
+ return *this < *rhs.head();
497
+ }
498
+
499
+ bool Simple_Selector::operator== (const Compound_Selector& rhs) const
500
+ {
501
+ return rhs.length() == 1 && *this == *rhs.at(0);
502
+ }
503
+
504
+ bool Simple_Selector::operator< (const Compound_Selector& rhs) const
505
+ {
506
+ size_t len = rhs.length();
507
+ if (len > 1) return true;
508
+ if (len == 0) return false;
509
+ return *this < *rhs.at(0);
510
+ }
511
+
512
+ /*#########################################################################*/
513
+ /*#########################################################################*/
514
+
515
+ bool Simple_Selector::operator== (const Simple_Selector& rhs) const
516
+ {
517
+ switch (simple_type()) {
518
+ case ID_SEL: return (const Id_Selector&) *this == rhs; break;
519
+ case TYPE_SEL: return (const Type_Selector&) *this == rhs; break;
520
+ case CLASS_SEL: return (const Class_Selector&) *this == rhs; break;
521
+ case PARENT_SEL: return (const Parent_Selector&) *this == rhs; break;
522
+ case PSEUDO_SEL: return (const Pseudo_Selector&) *this == rhs; break;
523
+ case WRAPPED_SEL: return (const Wrapped_Selector&) *this == rhs; break;
524
+ case ATTRIBUTE_SEL: return (const Attribute_Selector&) *this == rhs; break;
525
+ case PLACEHOLDER_SEL: return (const Placeholder_Selector&) *this == rhs; break;
526
+ }
527
+ return false;
528
+ }
529
+
530
+ /***************************************************************************/
531
+ /***************************************************************************/
532
+
533
+ bool Id_Selector::operator== (const Simple_Selector& rhs) const
534
+ {
535
+ auto sel = Cast<Id_Selector>(&rhs);
536
+ return sel ? *this == *sel : false;
537
+ }
538
+
539
+ bool Type_Selector::operator== (const Simple_Selector& rhs) const
540
+ {
541
+ auto sel = Cast<Type_Selector>(&rhs);
542
+ return sel ? *this == *sel : false;
543
+ }
544
+
545
+ bool Class_Selector::operator== (const Simple_Selector& rhs) const
546
+ {
547
+ auto sel = Cast<Class_Selector>(&rhs);
548
+ return sel ? *this == *sel : false;
549
+ }
550
+
551
+ bool Parent_Selector::operator== (const Simple_Selector& rhs) const
552
+ {
553
+ auto sel = Cast<Parent_Selector>(&rhs);
554
+ return sel ? *this == *sel : false;
555
+ }
556
+
557
+ bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
558
+ {
559
+ auto sel = Cast<Pseudo_Selector>(&rhs);
560
+ return sel ? *this == *sel : false;
561
+ }
562
+
563
+ bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
564
+ {
565
+ auto sel = Cast<Wrapped_Selector>(&rhs);
566
+ return sel ? *this == *sel : false;
567
+ }
568
+
569
+ bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
570
+ {
571
+ auto sel = Cast<Attribute_Selector>(&rhs);
572
+ return sel ? *this == *sel : false;
573
+ }
574
+
575
+ bool Placeholder_Selector::operator== (const Simple_Selector& rhs) const
576
+ {
577
+ auto sel = Cast<Placeholder_Selector>(&rhs);
578
+ return sel ? *this == *sel : false;
579
+ }
580
+
581
+ /***************************************************************************/
582
+ /***************************************************************************/
583
+
584
+ bool Id_Selector::operator== (const Id_Selector& rhs) const
585
+ {
586
+ // ID has no namespacing
587
+ return name() == rhs.name();
588
+ }
589
+
590
+ bool Type_Selector::operator== (const Type_Selector& rhs) const
591
+ {
592
+ return is_ns_eq(rhs) && name() == rhs.name();
593
+ }
594
+
595
+ bool Class_Selector::operator== (const Class_Selector& rhs) const
596
+ {
597
+ // Class has no namespacing
598
+ return name() == rhs.name();
599
+ }
600
+
601
+ bool Parent_Selector::operator== (const Parent_Selector& rhs) const
602
+ {
603
+ // Parent has no namespacing
604
+ return name() == rhs.name();
605
+ }
606
+
607
+ bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
608
+ {
609
+ std::string lname = name();
610
+ std::string rname = rhs.name();
611
+ if (is_pseudo_class_element(lname)) {
612
+ if (rname[0] == ':' && rname[1] == ':') {
613
+ lname = lname.substr(1, std::string::npos);
614
+ }
615
+ }
616
+ // right hand is special pseudo (single colon)
617
+ if (is_pseudo_class_element(rname)) {
618
+ if (lname[0] == ':' && lname[1] == ':') {
619
+ lname = lname.substr(1, std::string::npos);
620
+ }
621
+ }
622
+ // Pseudo has no namespacing
623
+ if (lname != rname) return false;
624
+ String_Obj lhs_ex = expression();
625
+ String_Obj rhs_ex = rhs.expression();
626
+ if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
627
+ else return lhs_ex.ptr() == rhs_ex.ptr();
628
+ }
629
+
630
+ bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
631
+ {
632
+ // Wrapped has no namespacing
633
+ if (name() != rhs.name()) return false;
634
+ return *(selector()) == *(rhs.selector());
635
+ }
636
+
637
+ bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
638
+ {
639
+ // get optional value state
640
+ bool no_lhs_val = value().isNull();
641
+ bool no_rhs_val = rhs.value().isNull();
642
+ // both are null, therefore equal
643
+ if (no_lhs_val && no_rhs_val) {
644
+ return (name() == rhs.name())
645
+ && (matcher() == rhs.matcher())
646
+ && (is_ns_eq(rhs));
647
+ }
648
+ // both are defined, evaluate
649
+ if (no_lhs_val == no_rhs_val) {
650
+ return (name() == rhs.name())
651
+ && (matcher() == rhs.matcher())
652
+ && (is_ns_eq(rhs))
653
+ && (*value() == *rhs.value());
654
+ }
655
+ // not equal
656
+ return false;
657
+ }
658
+
659
+ bool Placeholder_Selector::operator== (const Placeholder_Selector& rhs) const
660
+ {
661
+ // Placeholder has no namespacing
662
+ return name() == rhs.name();
663
+ }
664
+
665
+ /*#########################################################################*/
666
+ /*#########################################################################*/
667
+
668
+ bool Simple_Selector::operator< (const Simple_Selector& rhs) const
669
+ {
670
+ switch (simple_type()) {
671
+ case ID_SEL: return (const Id_Selector&) *this < rhs; break;
672
+ case TYPE_SEL: return (const Type_Selector&) *this < rhs; break;
673
+ case CLASS_SEL: return (const Class_Selector&) *this < rhs; break;
674
+ case PARENT_SEL: return (const Parent_Selector&) *this < rhs; break;
675
+ case PSEUDO_SEL: return (const Pseudo_Selector&) *this < rhs; break;
676
+ case WRAPPED_SEL: return (const Wrapped_Selector&) *this < rhs; break;
677
+ case ATTRIBUTE_SEL: return (const Attribute_Selector&) *this < rhs; break;
678
+ case PLACEHOLDER_SEL: return (const Placeholder_Selector&) *this < rhs; break;
679
+ }
680
+ return false;
681
+ }
682
+
683
+ /***************************************************************************/
684
+ /***************************************************************************/
685
+
686
+ bool Id_Selector::operator< (const Simple_Selector& rhs) const
687
+ {
688
+ switch (rhs.simple_type()) {
689
+ case TYPE_SEL: return '#' < 's'; break;
690
+ case CLASS_SEL: return '#' < '.'; break;
691
+ case PARENT_SEL: return '#' < '&'; break;
692
+ case PSEUDO_SEL: return '#' < ':'; break;
693
+ case WRAPPED_SEL: return '#' < '('; break;
694
+ case ATTRIBUTE_SEL: return '#' < '['; break;
695
+ case PLACEHOLDER_SEL: return '#' < '%'; break;
696
+ case ID_SEL: /* let if fall through */ break;
697
+ }
698
+ const Id_Selector& sel =
699
+ (const Id_Selector&) rhs;
700
+ return *this < sel;
701
+ }
702
+
703
+ bool Type_Selector::operator< (const Simple_Selector& rhs) const
704
+ {
705
+ switch (rhs.simple_type()) {
706
+ case ID_SEL: return 'e' < '#'; break;
707
+ case CLASS_SEL: return 'e' < '.'; break;
708
+ case PARENT_SEL: return 'e' < '&'; break;
709
+ case PSEUDO_SEL: return 'e' < ':'; break;
710
+ case WRAPPED_SEL: return 'e' < '('; break;
711
+ case ATTRIBUTE_SEL: return 'e' < '['; break;
712
+ case PLACEHOLDER_SEL: return 'e' < '%'; break;
713
+ case TYPE_SEL: /* let if fall through */ break;
714
+ }
715
+ const Type_Selector& sel =
716
+ (const Type_Selector&) rhs;
717
+ return *this < sel;
718
+ }
719
+
720
+ bool Class_Selector::operator< (const Simple_Selector& rhs) const
721
+ {
722
+ switch (rhs.simple_type()) {
723
+ case ID_SEL: return '.' < '#'; break;
724
+ case TYPE_SEL: return '.' < 's'; break;
725
+ case PARENT_SEL: return '.' < '&'; break;
726
+ case PSEUDO_SEL: return '.' < ':'; break;
727
+ case WRAPPED_SEL: return '.' < '('; break;
728
+ case ATTRIBUTE_SEL: return '.' < '['; break;
729
+ case PLACEHOLDER_SEL: return '.' < '%'; break;
730
+ case CLASS_SEL: /* let if fall through */ break;
731
+ }
732
+ const Class_Selector& sel =
733
+ (const Class_Selector&) rhs;
734
+ return *this < sel;
735
+ }
736
+
737
+ bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
738
+ {
739
+ switch (rhs.simple_type()) {
740
+ case ID_SEL: return ':' < '#'; break;
741
+ case TYPE_SEL: return ':' < 's'; break;
742
+ case CLASS_SEL: return ':' < '.'; break;
743
+ case PARENT_SEL: return ':' < '&'; break;
744
+ case WRAPPED_SEL: return ':' < '('; break;
745
+ case ATTRIBUTE_SEL: return ':' < '['; break;
746
+ case PLACEHOLDER_SEL: return ':' < '%'; break;
747
+ case PSEUDO_SEL: /* let if fall through */ break;
748
+ }
749
+ const Pseudo_Selector& sel =
750
+ (const Pseudo_Selector&) rhs;
751
+ return *this < sel;
752
+ }
753
+
754
+ bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
755
+ {
756
+ switch (rhs.simple_type()) {
757
+ case ID_SEL: return '(' < '#'; break;
758
+ case TYPE_SEL: return '(' < 's'; break;
759
+ case CLASS_SEL: return '(' < '.'; break;
760
+ case PARENT_SEL: return '(' < '&'; break;
761
+ case PSEUDO_SEL: return '(' < ':'; break;
762
+ case ATTRIBUTE_SEL: return '(' < '['; break;
763
+ case PLACEHOLDER_SEL: return '(' < '%'; break;
764
+ case WRAPPED_SEL: /* let if fall through */ break;
765
+ }
766
+ const Wrapped_Selector& sel =
767
+ (const Wrapped_Selector&) rhs;
768
+ return *this < sel;
769
+ }
770
+
771
+ bool Parent_Selector::operator< (const Simple_Selector& rhs) const
772
+ {
773
+ switch (rhs.simple_type()) {
774
+ case ID_SEL: return '&' < '#'; break;
775
+ case TYPE_SEL: return '&' < 's'; break;
776
+ case CLASS_SEL: return '&' < '.'; break;
777
+ case PSEUDO_SEL: return '&' < ':'; break;
778
+ case WRAPPED_SEL: return '&' < '('; break;
779
+ case ATTRIBUTE_SEL: return '&' < '['; break;
780
+ case PLACEHOLDER_SEL: return '&' < '%'; break;
781
+ case PARENT_SEL: /* let if fall through */ break;
782
+ }
783
+ const Parent_Selector& sel =
784
+ (const Parent_Selector&) rhs;
785
+ return *this < sel;
786
+ }
787
+
788
+ bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
789
+ {
790
+ switch (rhs.simple_type()) {
791
+ case ID_SEL: return '[' < '#'; break;
792
+ case TYPE_SEL: return '[' < 'e'; break;
793
+ case CLASS_SEL: return '[' < '.'; break;
794
+ case PARENT_SEL: return '[' < '&'; break;
795
+ case PSEUDO_SEL: return '[' < ':'; break;
796
+ case WRAPPED_SEL: return '[' < '('; break;
797
+ case PLACEHOLDER_SEL: return '[' < '%'; break;
798
+ case ATTRIBUTE_SEL: /* let if fall through */ break;
799
+ }
800
+ const Attribute_Selector& sel =
801
+ (const Attribute_Selector&) rhs;
802
+ return *this < sel;
803
+ }
804
+
805
+ bool Placeholder_Selector::operator< (const Simple_Selector& rhs) const
806
+ {
807
+ switch (rhs.simple_type()) {
808
+ case ID_SEL: return '%' < '#'; break;
809
+ case TYPE_SEL: return '%' < 's'; break;
810
+ case CLASS_SEL: return '%' < '.'; break;
811
+ case PARENT_SEL: return '%' < '&'; break;
812
+ case PSEUDO_SEL: return '%' < ':'; break;
813
+ case WRAPPED_SEL: return '%' < '('; break;
814
+ case ATTRIBUTE_SEL: return '%' < '['; break;
815
+ case PLACEHOLDER_SEL: /* let if fall through */ break;
816
+ }
817
+ const Placeholder_Selector& sel =
818
+ (const Placeholder_Selector&) rhs;
819
+ return *this < sel;
820
+ }
821
+
822
+ /***************************************************************************/
823
+ /***************************************************************************/
824
+
825
+ bool Id_Selector::operator< (const Id_Selector& rhs) const
826
+ {
827
+ // ID has no namespacing
828
+ return name() < rhs.name();
829
+ }
830
+
831
+ bool Type_Selector::operator< (const Type_Selector& rhs) const
832
+ {
833
+ return has_ns_ == rhs.has_ns_
834
+ ? (ns_ == rhs.ns_
835
+ ? name_ < rhs.name_
836
+ : ns_ < rhs.ns_)
837
+ : has_ns_ < rhs.has_ns_;
838
+ }
839
+
840
+ bool Class_Selector::operator< (const Class_Selector& rhs) const
841
+ {
842
+ // Class has no namespacing
843
+ return name() < rhs.name();
844
+ }
845
+
846
+ bool Parent_Selector::operator< (const Parent_Selector& rhs) const
847
+ {
848
+ // Parent has no namespacing
849
+ return name() < rhs.name();
850
+ }
851
+
852
+ bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
853
+ {
854
+ std::string lname = name();
855
+ std::string rname = rhs.name();
856
+ if (is_pseudo_class_element(lname)) {
857
+ if (rname[0] == ':' && rname[1] == ':') {
858
+ lname = lname.substr(1, std::string::npos);
859
+ }
860
+ }
861
+ // right hand is special pseudo (single colon)
862
+ if (is_pseudo_class_element(rname)) {
863
+ if (lname[0] == ':' && lname[1] == ':') {
864
+ lname = lname.substr(1, std::string::npos);
865
+ }
866
+ }
867
+ // Peudo has no namespacing
868
+ if (lname != rname)
869
+ { return lname < rname; }
870
+ String_Obj lhs_ex = expression();
871
+ String_Obj rhs_ex = rhs.expression();
872
+ if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
873
+ else return lhs_ex.ptr() < rhs_ex.ptr();
874
+ }
875
+
876
+ bool Wrapped_Selector::operator< (const Wrapped_Selector& rhs) const
877
+ {
878
+ // Wrapped has no namespacing
879
+ if (name() != rhs.name())
880
+ { return name() < rhs.name(); }
881
+ return *(selector()) < *(rhs.selector());
882
+ }
883
+
884
+ bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const
885
+ {
886
+ if (is_ns_eq(rhs)) {
887
+ if (name() != rhs.name())
888
+ { return name() < rhs.name(); }
889
+ if (matcher() != rhs.matcher())
890
+ { return matcher() < rhs.matcher(); }
891
+ bool no_lhs_val = value().isNull();
892
+ bool no_rhs_val = rhs.value().isNull();
893
+ if (no_lhs_val && no_rhs_val) return false; // equal
894
+ else if (no_lhs_val) return true; // lhs is null
895
+ else if (no_rhs_val) return false; // rhs is null
896
+ return *value() < *rhs.value(); // both are given
897
+ } else { return ns() < rhs.ns(); }
898
+ }
899
+
900
+ bool Placeholder_Selector::operator< (const Placeholder_Selector& rhs) const
901
+ {
902
+ // Placeholder has no namespacing
903
+ return name() < rhs.name();
904
+ }
905
+
906
+ /*#########################################################################*/
907
+ /*#########################################################################*/
908
+
909
+ }